CATATAN : Masih dalam tahap alpha. API dapat berubah.
(Repo ini dicerminkan ke https://codeberg.org/flowerinthenight/zgroup).
zgroup adalah perpustakaan Zig yang dapat mengelola keanggotaan cluster dan deteksi kegagalan anggota. Ia menggunakan kombinasi penyebaran informasi gaya SWIM Protocol, dan algoritma pemilihan pemimpin Raft (tanpa manajemen log) untuk melacak perubahan cluster.
Salah satu tujuan utama zgroup adalah untuk dapat melacak cluster dengan ukuran yang dapat berubah secara dinamis seiring waktu (misalnya Penerapan Kubernetes, Grup Instance GCP, Grup AWS Autoscaling, dll.) dengan ketergantungan dan beban jaringan yang minimal. Semua pekerjaan terkait saya sebelumnya sejauh ini, bergantung pada beberapa layanan eksternal (lihat spindel, lindung nilai), menggunakan detak jantung tradisional, untuk mencapai hal ini. Teknik detak jantung ini biasanya mengalami peningkatan ukuran muatan (sebanding dengan ukuran cluster) seiring bertambahnya ukuran cluster. Namun saya menginginkan sistem yang tidak mengalami efek samping tersebut. Ikuti penyebaran informasi bergaya infeksi SWIM. Itu dapat menggunakan ukuran muatan yang konstan terlepas dari ukuran cluster. SWIM menggunakan kombinasi PING
, INDIRECT-PING
, dan ACK
untuk mendeteksi kegagalan anggota sambil membonceng pesan yang sama untuk menyebarkan pembaruan keanggotaan (protokol gosip). Saat ini, zgroup hanya menggunakan protokol probing langsung SWIM; itu belum sepenuhnya mengimplementasikan sub-protokol Kecurigaan.
Saat ini, zgroup menggunakan payload tunggal 64-byte untuk semua pesannya, termasuk pemilihan pemimpin (lihat di bawah).
Saya juga menginginkan semacam kemampuan pemilihan pemimpin tanpa bergantung pada layanan kunci eksternal. Saat ini, zgroup menggunakan sub-protokol algoritme pemilihan pemimpin Raft (tanpa manajemen log) untuk mencapai hal ini. Saya harus mencatat bahwa algoritme pemilihan pemimpin Raft bergantung pada keanggotaan yang stabil agar dapat berfungsi dengan baik, jadi pemilihan pemimpin zgroup hanyalah berdasarkan upaya terbaik; split-brain masih bisa terjadi selama ukuran cluster masih berubah. Penjaga kode tambahan ditambahkan untuk meminimalkan perpecahan otak dalam skenario ini tetapi tidak sepenuhnya dihilangkan. Dalam kasus penggunaan (dan pengujian) saya, perubahan ukuran klaster bertahap sebagian besar stabil, sedangkan perubahan mendadak dengan delta ukuran besar tidak. Misalnya, lompatan besar dan tiba-tiba dari tiga node (ukuran minimum zgroup) menjadi, katakanlah, seratus, karena penskalaan otomatis, akan menyebabkan otak terbelah. Namun, ketika ukuran target tercapai, satu pemimpin akan selalu dipilih.
Catatan tentang rentang waktu tunggu acak Raft selama pemilihan pemimpin: pemimpin zgroup melacak rata-rata latensi ping dan mencoba menyesuaikan rentang waktu tunggu untuk mengakomodasi perubahan ukuran klaster dari waktu ke waktu.
Agar sebuah node dapat bergabung dengan cluster yang sudah ada, diperlukan alamat penggabungan. Meskipun zgroup menampilkan fungsi join()
untuk ini, zgroup juga menyediakan mekanisme panggilan balik, yang memberikan alamat bergabung kepada penelepon. Alamat ini kemudian dapat disimpan ke penyimpanan eksternal untuk digunakan oleh node lain. Secara internal, zgroup menggunakan node dengan alamat IP (v4) tertinggi dalam grup.
Contoh biner disediakan untuk menunjukkan cara menggunakan perpustakaan. Ada dua cara untuk menjalankan sampel:
# 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...
Jika dikonfigurasi, biner sampel menggunakan layanan gratis, https://keyvalue.immanuel.co/, sebagai penyimpanan alamat gabungan.
# 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...
Contoh file penerapan Kubernetes disediakan untuk mencoba zgroup pada Penerapan Kubernetes. Namun sebelum menerapkan, pastikan untuk memperbarui variabel lingkungan ZGROUP_JOIN_PREFIX
, seperti:
# 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.
Contoh skrip startup disediakan untuk mencoba zgroup di GCP MIG. Sebelum menerapkan, pastikan untuk memperbarui nilai ZGROUP_JOIN_PREFIX
di skrip, seperti:
# 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
Contoh skrip startup disediakan untuk mencoba zgroup di AWS ASG. Sebelum menerapkan, pastikan untuk memperbarui nilai ZGROUP_JOIN_PREFIX
di skrip, seperti:
# 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
Untuk mendapatkan anggota grup saat ini, Anda dapat mencoba sesuatu seperti:
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 });
}
Bagian tersulit dalam menggunakan zgroup adalah mengonfigurasi batas waktu untuk mengoptimalkan penyebaran dan konvergensi status. Implementasi saat ini hanya diuji dalam jaringan lokal.
PR dipersilakan.