Understand memcached mechanism

ก่อนใช้งาน memcached กับ production server
เรามาทำความเข้าใจกับเจ้า memcached อย่างจริงจังกันดีกว่า

Memcached จัดการ memory ของมันอย่างไร
ขอไม่เขียนเกี่ยวกับ memory ส่วนที่อยู่นอกเหนือจากส่วนที่ใช้เก็บข้อมูลนะครับ
เนื่องจากยังไม่ป๋าพอที่จะล้วงข้อมูลออกมา ^_^

สำหรับ memory ที่เรากำหนดให้เป็นที่เก็บข้อมูลของเจ้า memcached (ซึ่งมีหน่วยเป็น MiB = 1,048,576 bytes)
จะถูกแบ่งเป็น page หรือ slab (ขนาดไม่เกิน 1 MiB) และภายใน page จะแบ่งเป็น chunk ขนาดเท่า ๆ กัน

โดยข้อมูล 1 ตัว จะต้องอยู่ใน 1 chunk เท่านั้น
ทำให้ขนาดข้อมูล 1 ตัวที่ใหญ่ที่สุดที่ใส่เข้าไปใน memcached ได้คือ 1 MiB เท่านั้น (chunk size = 1 MiB, 1 chunk per page)

ขนาดของ chunk ในแต่ละ page ถูกกำหนดด้วย parameter ที่เรียก memcached server โดยเราสามารถระบุขนาด chunk ที่เล็กที่สุด (-n <size>)
และอัตราการเติบโตของขนาด chunk ได้ (-f <factor>) โดยเราจะเรียกแต่ละระดับของขนาด chunk ว่า slab class
ตัวอย่างเช่น

[karn@karn php.memcached]$ memcached -p 11214 -vv -n 48 -f 1.5
slab class   1: chunk size     88 perslab 11915
slab class   2: chunk size    132 perslab  7943
slab class   3: chunk size    200 perslab  5242
slab class   4: chunk size    300 perslab  3495
slab class   5: chunk size    452 perslab  2319
slab class   6: chunk size    680 perslab  1542
slab class   7: chunk size   1020 perslab  1028
slab class   8: chunk size   1532 perslab   684
slab class   9: chunk size   2300 perslab   455
slab class  10: chunk size   3452 perslab   303
slab class  11: chunk size   5180 perslab   202
slab class  12: chunk size   7772 perslab   134
slab class  13: chunk size  11660 perslab    89
slab class  14: chunk size  17492 perslab    59
slab class  15: chunk size  26240 perslab    39
slab class  16: chunk size  39360 perslab    26
slab class  17: chunk size  59040 perslab    17
slab class  18: chunk size  88560 perslab    11
slab class  19: chunk size 132840 perslab     7
slab class  20: chunk size 199260 perslab     5
slab class  21: chunk size 298892 perslab     3
slab class  22: chunk size 448340 perslab     2

นอกจากนี้ก็จะมี chunk size = 1048576 อีก 1 class สำหรับข้อมูลที่ใหญ่เกินกว่าจะมี 2 chunk ใน 1 page ได้ครับ
จากตัวอย่าง จะเห็นว่ามีค่า perslab ระบุมาด้วย นั่นคือการ allocate page ใหม่นั้น
ระบบจะสร้าง page ขนาดใหญ่ที่สุดจะใส่ได้ใน 1 MiB ซึ่งจะมีจำนวน chunk ตามค่า perslab ข้างต้นครับ

Memcached จัดเก็บข้อมูลอย่างไร
เมื่อเราส่งข้อมูลเพื่อไปเก็บใน memcached ระบบจะหา class ต่ำที่สุดเท่าที่จะใส่ข้อมูลของเราได้ใน 1 chunk
ถ้ามี chunk เหลืออยู่ใน class ก็จะใส่ข้อมูลของเราได้เลย
แต่ถ้าไม่มี chunk เหลือแล้ว ระบบจะสร้าง page ใหม่ใน class นั้นขึ้นมาเพื่อใส่ข้อมูลลงไป
(ในกรณีที่ยังไม่เกินขนาดที่เรากำหนดให้ memcached server ตัวนี้ใช้ได้)

แล้วถ้า memory ไม่เพียงพอแล้วหล่ะ memcached จะทำอย่างไร?
แบ่งเป็น 2 กรณี

1. กรณีที่เราไม่ได้กำหนด -M ไว้ใน parameter ของ memcached
ระบบจะค้นหา chunk ที่ไม่ได้ถูกใช้งานมานานที่สุด เพื่อลบทิ้ง
และนำข้อมูลใหม่ใส่ลงไป ซึ่งเหตุการณ์นี้เรียกว่า "Eviction"

เราสามารถตรวจสอบจำนวนครั้งที่เกิด Eviction ได้จาก command stats

2. กรณีที่เรากำหนด -M ไว้ใน parameter ของ memcached
ระบบจะตอบกลับไปว่า SERVER_ERROR out of memory

Memcached farm จัดเก็บข้อมูลอย่างไร
ในกรณีที่เราใช้ memcached หลายตัว ไม่ว่าจะอยู่ในเครื่องเดียวกันหรือไม่ก็ตาม
memcached แต่ละตัวจะไม่มีการสื่อสารถึงกัน ดังนั้นผู้ที่จะกำหนดว่า key นี้จะไปเก็บที่ memcached ตัวไหน
จึงเป็นภาระของ client โดย client จะต้องมี consistent hashing function ของ key

สมมติว่า hashing function of key = h(k)
เมื่อมี key ใด ๆ เข้ามาในระบบ client ก็จะแปลงด้วย h(k) เพื่อหาว่า key นี้จะต้องไปจัดเก็บที่ memcached ตัวใด
จากนั้นจึงส่ง key และ value ไปจัดเก็บที่ server ดังกล่าวตามปรกติตามขั้นตอนของหัวข้อที่แล้ว