ข้ามไปยังเนื้อหา

Clustering & Quorum Queues

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 หายหมด"]
classic queue อยู่บน node เดียว — เป็น single point of failure

ดังนั้น clustering อย่างเดียวให้ scale และ topology ที่แชร์กัน แต่ไม่ได้ให้ high availability สำหรับ message ใน queue ถ้า node ที่เป็นเจ้าของล่ม classic queue (ที่ไม่ได้ replicate) กับข้อมูลข้างในก็หายไปด้วย

ในอดีต วิธีแก้คือ 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 คือ 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 หาย"]
quorum queue ที่ replicate ข้าม 3 node

เพราะต้องให้ majority เห็นตรงกัน quorum queue จึงรอดเมื่อเสีย node ส่วนน้อย (เช่น 1 จาก 3 node) โดย ไม่มี message หาย และ elect leader ใหม่อัตโนมัติ นี่คือตัวเลือก default สำหรับ HA ใน RabbitMQ ยุคใหม่

replication ไม่ฟรี และ quorum queue เลือกอย่างจงใจ:

Classic queueQuorum queue
Replicationไม่มี (node เดียว)Raft, majority quorum
Node failuremessage หายรอดเมื่อเสีย 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 หายได้

ใน cluster ของ RabbitMQ, classic queue เก็บ message ของตัวเองไว้ที่ไหนจริง ๆ?
quorum queue ใช้อะไรในการ replicate อย่างปลอดภัย?
สถานะของ classic mirrored queue ใน RabbitMQ ปัจจุบันเป็นอย่างไร?
trade-off หลักของ quorum queue เทียบกับ classic queue คืออะไร?