RabbitMQ เป็นนายหน้าข้อความที่เขียนด้วยภาษา Erlang ซึ่งช่วยให้คุณสามารถจัดระเบียบคลัสเตอร์เฟลโอเวอร์ที่มีการจำลองข้อมูลเต็มรูปแบบข้ามหลายโหนด โดยที่แต่ละโหนดสามารถให้บริการคำขออ่านและเขียนได้ ด้วยคลัสเตอร์ Kubernetes จำนวนมากในการดำเนินงานจริง เราจึงรองรับการติดตั้ง RabbitMQ จำนวนมาก และต้องเผชิญกับความจำเป็นในการย้ายข้อมูลจากคลัสเตอร์หนึ่งไปยังอีกคลัสเตอร์หนึ่งโดยไม่ต้องหยุดทำงาน
เราต้องการการดำเนินการนี้อย่างน้อยสองกรณี:
- การถ่ายโอนข้อมูลจากคลัสเตอร์ RabbitMQ ที่ไม่ได้อยู่ใน Kubernetes ไปยังคลัสเตอร์ใหม่ – “kubernetized” แล้ว (เช่น ทำงานในพ็อด K8s) –
- การย้าย RabbitMQ ภายใน Kubernetes จากเนมสเปซหนึ่งไปยังอีกเนมสเปซ (เช่น หากวงจรถูกคั่นด้วยเนมสเปซ จะเป็นการถ่ายโอนโครงสร้างพื้นฐานจากวงจรหนึ่งไปยังอีกวงจรหนึ่ง)
สูตรที่เสนอในบทความมุ่งเน้นไปที่สถานการณ์ (แต่ไม่ได้จำกัดอยู่เพียงสถานการณ์เหล่านั้น) ซึ่งมีคลัสเตอร์ RabbitMQ เก่า (เช่น 3 โหนด) ซึ่งอยู่ใน K8 แล้วหรือบนเซิร์ฟเวอร์เก่าบางเซิร์ฟเวอร์ แอปพลิเคชันที่โฮสต์บน Kubernetes (มีอยู่แล้วหรือในอนาคต) ใช้งานได้:
... และเรากำลังเผชิญกับภารกิจในการโยกย้ายไปยังการผลิตใหม่ใน Kubernetes
ขั้นแรก จะมีการอธิบายแนวทางทั่วไปในการย้ายถิ่น และหลังจากนั้นจะอธิบายรายละเอียดทางเทคนิคของการนำไปปฏิบัติ
อัลกอริธึมการย้ายข้อมูล
ขั้นตอนแรกเบื้องต้นก่อนดำเนินการใด ๆ คือการตรวจสอบว่าโหมดความพร้อมใช้งานสูงถูกเปิดใช้งานในการติดตั้ง RabbitMQ เก่า (ha-mode: all
:
ขั้นตอนต่อไปคือการเพิ่มคลัสเตอร์ RabbitMQ ใหม่ในพ็อด Kubernetes (เช่น ในกรณีของเรา ประกอบด้วย 3 โหนด แต่จำนวนอาจแตกต่างกัน)
หลังจากนี้ เราจะรวมคลัสเตอร์ RabbitMQ เก่าและใหม่เข้าด้วยกัน เพื่อให้ได้คลัสเตอร์เดียว (จาก 6 โหนด):
กระบวนการซิงโครไนซ์ข้อมูลระหว่างคลัสเตอร์ RabbitMQ เก่าและใหม่เริ่มต้นขึ้น เมื่อข้อมูลทั้งหมดซิงโครไนซ์ระหว่างโหนดทั้งหมดในคลัสเตอร์แล้ว เราก็สามารถเปลี่ยนแอปพลิเคชันไปใช้คลัสเตอร์ใหม่ได้:
หลังจากการดำเนินการเหล่านี้ ก็เพียงพอที่จะลบโหนดเก่าออกจากคลัสเตอร์ RabbitMQ และถือว่าการย้ายเสร็จสมบูรณ์:
เราใช้รูปแบบนี้หลายครั้งในการผลิต อย่างไรก็ตาม เพื่อความสะดวกของเรา เราได้ปรับใช้ภายในระบบพิเศษที่กระจายการกำหนดค่า RMQ มาตรฐานไปยังคลัสเตอร์ Kubernetes หลายคลัสเตอร์ (สำหรับผู้ที่สงสัย: เรากำลังพูดถึง
มาลองในทางปฏิบัติดูครับ
ความต้องการ
รายละเอียดนั้นง่ายมาก:
- คลัสเตอร์ Kubernetes (minikube ก็ใช้งานได้เช่นกัน);
- คลัสเตอร์ RabbitMQ (สามารถปรับใช้บน Bare Metal และสร้างเหมือนคลัสเตอร์ทั่วไปใน Kubernetes จากแผนภูมิ Helm อย่างเป็นทางการ)
สำหรับตัวอย่างด้านล่าง ฉันปรับใช้ RMQ กับ Kubernetes และเรียกมันว่า rmq-old
.
การเตรียมจุดยืน
1. ดาวน์โหลดแผนภูมิ Helm และแก้ไขเล็กน้อย:
helm fetch --untar stable/rabbitmq-ha
เพื่อความสะดวกเราตั้งรหัสผ่าน ErlangCookie
และทำการเมือง ha-all
เพื่อให้ตามค่าเริ่มต้น คิวจะถูกซิงโครไนซ์ระหว่างโหนดทั้งหมดของคลัสเตอร์ RMQ:
rabbitmqPassword: guest
rabbitmqErlangCookie: mae9joopaol7aiVu3eechei2waiGa2we
definitions:
policies: |-
{
"name": "ha-all",
"pattern": ".*",
"vhost": "/",
"definition": {
"ha-mode": "all",
"ha-sync-mode": "automatic",
"ha-sync-batch-size": 81920
}
}
2. ติดตั้งแผนภูมิ:
helm install . --name rmq-old --namespace rmq-old
3. ไปที่แผงผู้ดูแลระบบ RabbitMQ สร้างคิวใหม่และเพิ่มข้อความหลายรายการ สิ่งเหล่านี้จำเป็นเพื่อว่าหลังจากการย้ายข้อมูลแล้ว เราจะมั่นใจได้ว่าข้อมูลทั้งหมดได้รับการเก็บรักษาไว้และเราจะไม่สูญเสียสิ่งใดเลย:
ม้านั่งทดสอบพร้อมแล้ว: เรามี RabbitMQ “เก่า” พร้อมข้อมูลที่จำเป็นต้องถ่ายโอน
การย้ายคลัสเตอร์ RabbitMQ
1. ก่อนอื่น มาปรับใช้ RabbitMQ ใหม่กันก่อน เพื่อน เนมสเปซด้วย เดียวกัน ErlangCookie
และรหัสผ่านสำหรับผู้ใช้ ในการดำเนินการนี้ เราจะดำเนินการตามที่อธิบายไว้ข้างต้น โดยเปลี่ยนคำสั่งสุดท้ายสำหรับการติดตั้ง RMQ เป็นดังนี้:
helm install . --name rmq-new --namespace rmq-new
2. ตอนนี้คุณต้องรวมคลัสเตอร์ใหม่เข้ากับคลัสเตอร์เก่า โดยไปที่แต่ละพ็อด ใหม่ RabbitMQ และดำเนินการคำสั่ง:
export OLD_RMQ=rabbit@rmq-old-rabbitmq-ha-0.rmq-old-rabbitmq-ha-discovery.rmq-old.svc.cluster.local &&
rabbitmqctl stop_app &&
rabbitmqctl join_cluster $OLD_RMQ &&
rabbitmqctl start_app
ในตัวแปร OLD_RMQ
พบที่อยู่ของโหนดใดโหนดหนึ่ง เก่า คลัสเตอร์ RMQ
คำสั่งเหล่านี้จะหยุดโหนดปัจจุบัน ใหม่ คลัสเตอร์ RMQ แนบเข้ากับคลัสเตอร์เก่าแล้วเปิดใช้งานอีกครั้ง
3. คลัสเตอร์ RMQ จำนวน 6 โหนดพร้อมแล้ว:
คุณต้องรอในขณะที่ข้อความซิงโครไนซ์ระหว่างโหนดทั้งหมด เดาได้ไม่ยากว่าเวลาในการซิงโครไนซ์ข้อความขึ้นอยู่กับความจุของฮาร์ดแวร์ที่คลัสเตอร์ใช้งานและจำนวนข้อความ ในสถานการณ์ที่อธิบายไว้ มีเพียง 10 รายการเท่านั้น ดังนั้นข้อมูลจึงถูกซิงโครไนซ์ทันที แต่เมื่อมีข้อความจำนวนมากเพียงพอ การซิงโครไนซ์อาจใช้เวลานานหลายชั่วโมง
ดังนั้นสถานะการซิงโครไนซ์:
ที่นี่ +5
หมายถึงมีข้อความเข้าแล้ว ขึ้น บน 5 โหนด (ยกเว้นสิ่งที่ระบุไว้ในช่อง Node
). ดังนั้นการซิงโครไนซ์จึงสำเร็จ
4. สิ่งที่เหลืออยู่คือเปลี่ยนที่อยู่ RMQ ในแอปพลิเคชันเป็นคลัสเตอร์ใหม่ (การดำเนินการเฉพาะที่นี่ขึ้นอยู่กับสแต็กเทคโนโลยีที่คุณใช้และลักษณะเฉพาะของแอปพลิเคชันอื่นๆ) หลังจากนั้นคุณก็สามารถบอกลาคลัสเตอร์เก่าได้
สำหรับการดำเนินการครั้งสุดท้าย (เช่น แล้ว หลังจาก การสลับแอปพลิเคชันไปเป็นคลัสเตอร์ใหม่) ไปที่แต่ละโหนด เก่า คลัสเตอร์และดำเนินการคำสั่ง:
rabbitmqctl stop_app
rabbitmqctl reset
คลัสเตอร์ “ลืม” เกี่ยวกับโหนดเก่า: คุณสามารถลบ RMQ เก่าได้ ซึ่ง ณ จุดนี้การย้ายจะเสร็จสมบูรณ์
หมายเหตุ: หากคุณใช้ RMQ กับใบรับรอง จะไม่มีอะไรเปลี่ยนแปลงโดยพื้นฐาน - กระบวนการย้ายจะดำเนินการเหมือนกันทุกประการ
ผลการวิจัย
รูปแบบที่อธิบายไว้เหมาะสำหรับเกือบทุกกรณีที่เราต้องการย้าย RabbitMQ หรือเพียงย้ายไปยังคลัสเตอร์ใหม่
ในกรณีของเรา ปัญหาเกิดขึ้นเพียงครั้งเดียว เมื่อเข้าถึง RMQ จากหลายแห่ง และเราไม่มีโอกาสเปลี่ยนที่อยู่ RMQ เป็นที่อยู่ใหม่ทุกที่ จากนั้นเราได้เปิดตัว RMQ ใหม่ในเนมสเปซเดียวกันโดยมีป้ายกำกับเดียวกัน เพื่อให้ตกอยู่ภายใต้บริการและ Ingresses ที่มีอยู่ และเมื่อเปิดตัวพ็อด เราก็จัดการป้ายกำกับด้วยมือ โดยลบป้ายกำกับออกตั้งแต่ต้นเพื่อไม่ให้คำขอตกอยู่ที่ RMQ ที่ว่างเปล่า และเพิ่มกลับหลังจากการซิงโครไนซ์ข้อความ
เราใช้กลยุทธ์เดียวกันเมื่ออัปเดต RabbitMQ เป็นเวอร์ชันใหม่โดยมีการกำหนดค่าที่เปลี่ยนแปลง - ทุกอย่างทำงานเหมือนนาฬิกา
PS
เรากำลังเตรียมบทความเกี่ยวกับ MongoDB (การย้ายจากเซิร์ฟเวอร์ฮาร์ดแวร์ไปยัง Kubernetes) และ MySQL (วิธีที่เราเตรียม DBMS นี้ภายใน Kubernetes) เพื่อความต่อเนื่องเชิงตรรกะของเนื้อหานี้ พวกเขาจะถูกเผยแพร่ในอีกไม่กี่เดือนข้างหน้า
PPS
อ่านเพิ่มเติมในบล็อกของเรา:
- «
ฐานข้อมูลและ Kubernetes (รีวิวและรายงานวิดีโอ) "; - «
เคล็ดลับและคำแนะนำของ K8: การเร่งความเร็วบูตสแตรปสำหรับฐานข้อมูลขนาดใหญ่ '
ที่มา: will.com