หมายเหตุ : ยังอยู่ในช่วงอัลฟ่า API อาจมีการเปลี่ยนแปลง
(repo นี้สะท้อนไปที่https://codeberg.org/flowerinthenight/zgroup)
zgroup เป็นไลบรารี Zig ที่สามารถจัดการความเป็นสมาชิกคลัสเตอร์และการตรวจหาความล้มเหลวของสมาชิก ใช้การผสมผสานระหว่างการเผยแพร่ข้อมูลสไตล์ซุบซิบของ SWIM Protocol และอัลกอริธึมการเลือกตั้งผู้นำของ Raft (ลบการจัดการบันทึก) เพื่อติดตามการเปลี่ยนแปลงของคลัสเตอร์
เป้าหมายหลักของ zgroup ประการหนึ่งคือสามารถติดตามคลัสเตอร์ที่มีขนาดที่สามารถเปลี่ยนแปลงได้แบบไดนามิกเมื่อเวลาผ่านไป (เช่น การปรับใช้ Kubernetes, GCP Instance Groups, AWS Autoscaling Groups เป็นต้น) โดยมีการพึ่งพาและโหลดเครือข่ายน้อยที่สุด งานที่เกี่ยวข้องก่อนหน้านี้ทั้งหมดของฉันจนถึงตอนนี้ ขึ้นอยู่กับบริการภายนอกบางอย่าง (ดูสปินเดิล การป้องกันความเสี่ยง) โดยใช้การเต้นของหัวใจแบบดั้งเดิมเพื่อให้บรรลุเป้าหมายนี้ เทคนิคการเต้นหัวใจนี้มักจะทนทุกข์ทรมานจากการเพิ่มขนาดเพย์โหลด (สัดส่วนกับขนาดคลัสเตอร์) เมื่อคลัสเตอร์ใหญ่ขึ้น แต่ฉันต้องการระบบที่ไม่ได้รับผลกระทบจากผลข้างเคียงนั้น เข้าสู่การเผยแพร่ข้อมูลสไตล์การติดเชื้อของ SWIM สามารถใช้ขนาดเพย์โหลดคงที่โดยไม่คำนึงถึงขนาดคลัสเตอร์ SWIM ใช้การรวมกันของ PING
, INDIRECT-PING
และ ACK
เพื่อตรวจจับความล้มเหลวของสมาชิกในขณะที่ส่งข้อความเดียวกันเหล่านี้เพื่อเผยแพร่การอัปเดตการเป็นสมาชิก (โปรโตคอลการนินทา) ปัจจุบัน zgroup ใช้โปรโตคอลการตรวจสอบโดยตรงของ SWIM เท่านั้น ยังไม่ได้ใช้โปรโตคอลย่อย Suspicion อย่างสมบูรณ์ (ยัง)
ในขณะนี้ zgroup ใช้เพย์โหลด 64 ไบต์เดียวสำหรับข้อความทั้งหมด รวมถึงการเลือกผู้นำ (ดูด้านล่าง)
ฉันยังต้องการความสามารถในการเลือกผู้นำโดยไม่ต้องพึ่งบริการล็อคภายนอก ในขณะนี้ zgroup ใช้โปรโตคอลย่อยอัลกอริธึมการเลือกผู้นำของ Raft (โดยไม่มีการจัดการบันทึก) เพื่อให้บรรลุเป้าหมายนี้ ฉันควรทราบว่าอัลกอริธึมการเลือกตั้งผู้นำของ Raft ขึ้นอยู่กับการเป็นสมาชิกที่มั่นคงเพื่อให้ทำงานได้อย่างถูกต้อง ดังนั้นการเลือกตั้งผู้นำของ zgroup จึงเป็นพื้นฐานที่ดีที่สุดเท่านั้น สมองแตกแยกยังคงสามารถเกิดขึ้นได้ในขณะที่ขนาดคลัสเตอร์ยังคงเปลี่ยนแปลง มีการเพิ่มตัวป้องกันโค้ดเพิ่มเติมเพื่อลดการแบ่งสมองในสถานการณ์เหล่านี้ แต่ก็ยังไม่ได้ถูกกำจัดออกไปทั้งหมด ในกรณีการใช้งานของฉัน (และการทดสอบ) การเปลี่ยนแปลงขนาดคลัสเตอร์แบบค่อยเป็นค่อยไปส่วนใหญ่จะมีเสถียรภาพ ในขณะที่การเปลี่ยนแปลงอย่างกะทันหันด้วยส่วนต่างขนาดใหญ่จะไม่เป็นเช่นนั้น ตัวอย่างเช่น การกระโดดครั้งใหญ่อย่างกะทันหันจากสามโหนด (ขนาดขั้นต่ำของ zgroup) ไปเป็นร้อยเนื่องจากการปรับขนาดอัตโนมัติ จะทำให้สมองแตกแยก เมื่อบรรลุเป้าหมายแล้ว จะมีการเลือกผู้นำเพียงคนเดียวเสมอ
หมายเหตุเกี่ยวกับช่วงหมดเวลาแบบสุ่มของ Raft ในระหว่างการเลือกผู้นำ: ผู้นำของ zgroup ติดตามค่าเฉลี่ยเวลาแฝงของ ping และพยายามปรับช่วงหมดเวลาตามเพื่อรองรับการเปลี่ยนแปลงล่วงเวลาขนาดคลัสเตอร์
เพื่อให้โหนดเข้าร่วมคลัสเตอร์ที่มีอยู่ได้ จะต้องมีที่อยู่สำหรับเข้าร่วม แม้ว่า zgroup จะเปิดเผยฟังก์ชัน join()
สำหรับสิ่งนี้ แต่ก็มีกลไกการโทรกลับ โดยให้ที่อยู่การเข้าร่วมแก่ผู้โทร ที่อยู่นี้สามารถจัดเก็บไว้ในที่จัดเก็บภายนอกเพื่อให้โหนดอื่นๆ ใช้งานได้ ภายใน zgroup ใช้โหนดที่มีที่อยู่ IP (v4) สูงสุดในกลุ่ม
มีไบนารีตัวอย่างเพื่อแสดงวิธีการใช้ไลบรารี มีสองวิธีในการรันตัวอย่าง:
# Build the sample binary:
$ zig build --summary all
# Run the 1st process. The expected args look like:
#
# ./zgroup groupname member_ip:port [join_ip:port]
#
# Run the first process (join to self).
$ ./zig-out/bin/zgroup group1 0.0.0.0:8080 0.0.0.0:8080
# Then you can run additional instances.
# Join through the 1st process/node (different terminal):
$ ./zig-out/bin/zgroup group1 0.0.0.0:8081 0.0.0.0:8080
# Join through the 2nd process/node (different terminal):
$ ./zig-out/bin/zgroup group1 0.0.0.0:8082 0.0.0.0:8081
# Join through the 1st process/node (different terminal):
$ ./zig-out/bin/zgroup group1 0.0.0.0:8083 0.0.0.0:8080
# and so on...
หากกำหนดค่าไว้ ไบนารีตัวอย่างจะใช้บริการฟรี https://keyvalue.immanuel.co/ เป็นร้านค้าสำหรับที่อยู่การรวม
# Build the sample binary:
$ zig build --summary all
# Generate UUID:
$ uuidgen
{output}
# Run the 1st process. The expected args look like:
#
# ./zgroup groupname member_ip:port
#
# Run the first process:
$ ZGROUP_JOIN_PREFIX={output} ./zig-out/bin/zgroup group1 0.0.0.0:8080
# Add a second node (different terminal):
$ ZGROUP_JOIN_PREFIX={output} ./zig-out/bin/zgroup group1 0.0.0.0:8081
# Add a third node (different terminal):
$ ZGROUP_JOIN_PREFIX={output} ./zig-out/bin/zgroup group1 0.0.0.0:8082
# Add a fourth node (different terminal):
$ ZGROUP_JOIN_PREFIX={output} ./zig-out/bin/zgroup group1 0.0.0.0:8083
# and so on...
มีการจัดเตรียมไฟล์การปรับใช้ Kubernetes ตัวอย่างไว้เพื่อทดลองใช้ zgroup บน Kubernetes Deployments ก่อนที่จะปรับใช้ ตรวจสอบให้แน่ใจว่าได้อัปเดตตัวแปรสภาพแวดล้อม ZGROUP_JOIN_PREFIX
ดังนี้:
# Generate UUID:
$ uuidgen
{output}
# Update the 'value' part with your output.
...
- name: ZGROUP_JOIN_PREFIX
value: " {output} "
...
# Deploy to Kubernetes:
$ kubectl create -f k8s.yaml
# You will notice some initial errors in the logs.
# Wait for a while before the K/V store is updated.
มีการจัดเตรียมสคริปต์เริ่มต้นตัวอย่างเพื่อลองใช้ zgroup บน GCP MIG ก่อนที่จะปรับใช้ ตรวจสอบให้แน่ใจว่าได้อัปเดตค่า ZGROUP_JOIN_PREFIX
ในสคริปต์แล้ว ดังนี้:
# Generate UUID:
$ uuidgen
{output}
# Update the 'value' part of ZGROUP_JOIN_PREFIX with your output.
...
ZGROUP_JOIN_PREFIX={output} ./zgroup group1 ...
# Create an instance template:
$ gcloud compute instance-templates create zgroup-tmpl
--machine-type e2-micro
--metadata=startup-script= ' ' " $( cat startup-gcp-mig.sh ) " ' '
# Create a regional MIG:
$ gcloud compute instance-groups managed create rmig
--template zgroup-tmpl --size 3 --region {your-region}
# You can view the logs through:
$ tail -f /var/log/messages
มีสคริปต์เริ่มต้นตัวอย่างให้ไว้เพื่อลองใช้ zgroup บน AWS ASG ก่อนที่จะปรับใช้ ตรวจสอบให้แน่ใจว่าได้อัปเดตค่า ZGROUP_JOIN_PREFIX
ในสคริปต์แล้ว ดังนี้:
# Generate UUID:
$ uuidgen
{output}
# Update the 'value' part of ZGROUP_JOIN_PREFIX with your output.
...
ZGROUP_JOIN_PREFIX={output} ./zgroup group1 ...
# Create a launch template. ImageId here is Amazon Linux, default VPC.
# (Added newlines for readability. Might not run when copied as is.)
$ aws ec2 create-launch-template
--launch-template-name zgroup-lt
--version-description version1
--launch-template-data '
{
"UserData":" ' " $( cat startup-aws-asg.sh | base64 -w 0 ) " ' ",
"ImageId":"ami-0f75d1a8c9141bd00",
"InstanceType":"t2.micro"
} '
# Create the ASG:
$ aws autoscaling create-auto-scaling-group
--auto-scaling-group-name zgroup-asg
--launch-template LaunchTemplateName=zgroup-lt,Version= ' 1 '
--min-size 3
--max-size 3
--availability-zones {target-zone}
# You can view the logs through:
$ [sudo] journalctl -f
หากต้องการรับสมาชิกปัจจุบันของกลุ่ม คุณสามารถลองทำดังนี้:
const members = try fleet . getMembers ( gpa . allocator ());
defer members . deinit ();
for ( members . items , 0 .. ) | v , i | {
defer gpa . allocator (). free ( v );
log . info ( "member[{d}]: {s}" , .{ i , v });
}
ส่วนที่ยุ่งยากของการใช้ zgroup คือการกำหนดค่าการหมดเวลาเพื่อเพิ่มประสิทธิภาพการเผยแพร่และการบรรจบกันของรัฐ การใช้งานปัจจุบันได้รับการทดสอบภายในเครือข่ายท้องถิ่นเท่านั้น
PR ยินดีต้อนรับ.