Clustering & Quorum Queues
cluster แชร์ metadata ไม่ใช่ queue
หัวข้อที่มีชื่อว่า “cluster แชร์ metadata ไม่ใช่ queue”cluster ของ RabbitMQ คือ node หลายตัวที่ทำงานเป็น broker เชิงตรรกะตัวเดียว ทุก node แชร์ metadata — exchange, binding, user, vhost และรายชื่อ queue ที่มีอยู่ — ดังนั้น client ต่อเข้า node ไหนก็เห็น topology เดียวกัน
แต่มีจุดที่คนมักตกใจ: classic queue อยู่บน node ตัวเดียวที่ถูก declare เท่านั้น node อื่นรู้ว่า queue นี้มีอยู่ แต่ไม่ได้ถือ message ของตัวเองเลย ถ้า client ต่อเข้าที่อื่น operation ของตัวเองจะถูก forward ไปยัง node ที่เป็นเจ้าของ queue
flowchart TB c["Client (ต่อเข้าที่ไหนก็ได้)"] --> n1["Node 1 queue: orders (เจ้าของ)"] c -.forward.-> n2["Node 2 (ไม่มี message)"] c -.forward.-> n3["Node 3 (ไม่มี message)"] n1 --> risk["Node 1 ล่ม → queue + message หายหมด"]
ดังนั้น clustering อย่างเดียวให้ scale และ topology ที่แชร์กัน แต่ไม่ได้ให้ high availability สำหรับ message ใน queue ถ้า node ที่เป็นเจ้าของล่ม classic queue (ที่ไม่ได้ replicate) กับข้อมูลข้างในก็หายไปด้วย
คำตอบเดิม: mirrored queue (ถูกถอดออกใน RabbitMQ 4.0)
หัวข้อที่มีชื่อว่า “คำตอบเดิม: mirrored queue (ถูกถอดออกใน RabbitMQ 4.0)”ในอดีต วิธีแก้คือ classic mirrored queue — replicate เนื้อหาของ queue ไปเป็น mirror บน node อื่น mirroring ใช้งานได้ แต่ปวดหัวเรื่อง operation: sync queue ใหญ่ ๆ ช้า, failover semantics ยุ่งยาก และมี edge case ที่ทำ message หายหรือซ้ำได้ตอน partition classic queue mirroring ถูก deprecated ตั้งแต่ RabbitMQ 3.x และ ถูกถอดออกทั้งหมดใน RabbitMQ 4.0 — quorum queue คือตัวแทน ดังนั้นบน broker เวอร์ชันปัจจุบันคุณใช้ mirrored queue ไม่ได้แล้ว
คำตอบยุคใหม่: quorum queue
หัวข้อที่มีชื่อว่า “คำตอบยุคใหม่: quorum queue”quorum queue คือ replicated queue ที่สร้างบน consensus algorithm ชื่อ Raft quorum queue มี leader และ follower กระจายอยู่บน node ต่าง ๆ ใน cluster โดย message จะถูก confirm ก็ต่อเมื่อ replica เกิน majority (quorum) เขียนลง disk แบบ durable แล้ว
flowchart TB p["Publisher"] --> leader["Node 1: leader replica"] leader --> f1["Node 2: follower"] leader --> f2["Node 3: follower"] leader --> conf["confirm ก็ต่อเมื่อ majority เก็บแล้ว"] leader --> ha["leader ล่ม → เลือก follower ขึ้นมาแทน, ไม่มี message หาย"]
เพราะต้องให้ majority เห็นตรงกัน quorum queue จึงรอดเมื่อเสีย node ส่วนน้อย (เช่น 1 จาก 3 node) โดย ไม่มี message หาย และ elect leader ใหม่อัตโนมัติ นี่คือตัวเลือก default สำหรับ HA ใน RabbitMQ ยุคใหม่
trade-off
หัวข้อที่มีชื่อว่า “trade-off”replication ไม่ฟรี และ quorum queue เลือกอย่างจงใจ:
| Classic queue | Quorum queue | |
|---|---|---|
| Replication | ไม่มี (node เดียว) | Raft, majority quorum |
| Node failure | message หาย | รอดเมื่อเสีย node ส่วนน้อย |
| Throughput | สูงสุด | ต่ำกว่า (ต้นทุน replication) |
| Latency | ต่ำสุด | สูงกว่า (รอ quorum) |
| Memory model | เก็บใน memory ได้ | durable บน disk เสมอ |
| เหมาะกับ | transient, throughput สูง | message สำคัญที่หายไม่ได้ |
quorum queue เป็น durable เสมอ และต้องการจำนวน replica เป็นเลขคี่ (ปกติ 3 หรือ 5) เพื่อ break ties ใช้ quorum queue กับ message ที่สำคัญ ส่วน classic queue ยังเหมาะกับงาน transient ที่ throughput สูงและยอมให้ message หายได้