Implementasi Protokol Keanggotaan Grup Proses Infeksi (SWIM) bergaya Infeksi yang Scalable dan Asynchronous yang ditulis dalam Rust.
Peringatan
Penafian: Proyek ini masih dalam proses dan belum siap produksi. Basis kode mungkin berisi bug atau fitur yang tidak lengkap. Gunakan dengan hati-hati. Masukan dan kontribusi diterima, Terima kasih!.
io_uring
melalui Tokio (SWIM:Basic)
+ (SWIM+Inf.)
+ (SWIM+Inf.+Susp.)
dan diperluas untuk menyertakan fitur dari Lifeguard oleh Hashicorp Research Gossipod menggunakan 3 jenis pesan: PING
, PING-REQ
, dan BROADCAST
(yang mencakup subtipe JOIN
, LEAVE
, SUSPECT
, ALIVE
, dan CONFIRM
). Pesan PING
dan PING-REQ
sangat penting dalam mekanisme deteksi kegagalan sistem berdasarkan SWIM, yang memfasilitasi pertukaran keadaan secara konstan dengan mendukung penyebaran informasi pada proses ini. Ketika perubahan keadaan terjadi, baik melalui permintaan sukarela atau deteksi kegagalan rutin, sistem menggunakan pesan BROADCAST
untuk penyebaran informasi ini secara acak. Setiap node dalam jaringan mempertahankan nomor inkarnasi, dimulai dari nol, yang hanya dapat bertambah oleh node itu sendiri. Nomor ini sangat penting untuk mengelola status node dalam daftar keanggotaan lokal node lain dan berfungsi sebagai sarana untuk menyangkal kecurigaan (SWIM+Inf.+Susp.)
dari node lain. Desain ini memungkinkan Gossipod mencapai manajemen status terdistribusi dan deteksi kegagalan yang efisien dan tangguh dalam jaringan terdistribusi atau terdesentralisasi, menyeimbangkan kebutuhan akan informasi terkini, resolusi konflik, dan keandalan sistem.
Dengan Ekstensi, Lifeguard menawarkan fitur implementasi tambahan yang belum dimasukkan ke dalam versi Gossipod saat ini yang didukung penuh oleh daftar anggota Hashicorp. Saya berencana untuk mengintegrasikan fitur-fitur ini dalam rilis mendatang.
diagram urutan
peserta N1 sebagai Node 1
peserta N2 sebagai Node 2
peserta N3 sebagai Node 3
peserta Nx sebagai Node x (Acak)
Catatan atas N1,Nx: Probing & Penyebaran Informasi melalui piggybacking
N1->>N2: PING (dengan info yang dibonceng)
N2->>N1: ACK (dengan info yang dibonceng)
N1->>N3: PING-REQ (untuk N2)
N3->>N2: PING
N2->>N3: ACK
N3->>N1: ACK (tidak langsung)
Catatan atas N1,Nx: Diseminasi Perubahan Negara
N1->>Nx: BROADCAST (TINGGALKAN/GABUNG/SUSPEK/KONFIRMASI)
Nx->>N2: PING (dengan perubahan status piggyback)
N2->>N3: PING (dengan perubahan status piggyback)
Catatan atas N1,Nx: Deteksi & Pemulihan Kegagalan
N1->>N2 : PING (tidak ada respon)
N1->>N3: PING-REQ (untuk N2)
N3->>N2: PING (tidak ada respon)
N3->>N1: TIDAK
N1->>Nx: PENYIARAN (TERcuriga N2)
Catatan atas N2: N2 menerima pesan SUSPECT
N2->>N2: Menambah nomor inkarnasi
N2->>Nx: BROADCAST (HIDUP dengan nomor inkarnasi baru)
alt N2 berhasil membantah
Nx->>N1: PING (dengan digendong ALIVE N2)
Catatan atas N1: Perbarui status N2 menjadi hidup
kalau tidak, N2 tidak membantah tepat waktu
N1->>Nx: BROADCAST (KONFIRMASI N2 sebagai gagal)
akhir
Untuk melihat Gossipod beraksi, lihat direktori ./examples
, yang berisi sejumlah demo. Di bawah ini Anda dapat menjalankan dua contoh gosipod berbeda yang menentukan alamat port dan nama node berbeda
> cargo run -p ping_node -- --name=NODE_1 --port=7948
> cargo run -p pong_node -- --name=NODE_2 --port=7947 --join-addr=127.0.0.1:7948
let config = GossipodConfigBuilder :: new ( )
. with_name ( & args . name )
. with_port ( args . port )
. with_addr ( args . ip . parse :: < Ipv4Addr > ( ) . expect ( "Invalid IP address" ) )
. with_probing_interval ( Duration :: from_secs ( 1 ) )
. with_ack_timeout ( Duration :: from_millis ( 500 ) )
. with_indirect_ack_timeout ( Duration :: from_secs ( 1 ) )
. with_suspicious_timeout ( Duration :: from_secs ( 5 ) )
. with_network_type ( NetworkType :: LAN )
. build ( )
. await ? ;
let gossipod = Gossipod :: new ( config ) . await ? ;
# [ derive ( Clone , Debug , Serialize , Deserialize , PartialEq , Eq , Hash ) ]
struct Metadata {
region : String ,
datacenter : String ,
}
impl NodeMetadata for Metadata { }
let metadata = Metadata {
region : "aws-west-1" . to_string ( ) ,
datacenter : "dc1" . to_string ( ) ,
} ;
let gossipod = Gossipod :: with_metadata ( config , metadata ) . await ? ;
Berikut ini contoh dasar cara menggunakan Gossipod di aplikasi Anda:
// Configuration
let config = GossipodConfigBuilder :: new ( )
. with_name ( & args . name )
. with_port ( args . port )
. with_addr ( args . ip . parse :: < Ipv4Addr > ( ) . expect ( "Invalid IP address" ) )
. with_probing_interval ( Duration :: from_secs ( 1 ) )
. with_ack_timeout ( Duration :: from_millis ( 500 ) )
. with_indirect_ack_timeout ( Duration :: from_secs ( 1 ) )
. with_suspicious_timeout ( Duration :: from_secs ( 5 ) )
. with_network_type ( NetworkType :: LAN )
. build ( )
. await ? ;
// New instance
let gossipod = Arc :: new ( Gossipod :: new ( config . clone ( ) ) . await ? ) ;
// Start Gossipod
tokio :: spawn ( gossipod . clone ( ) . start ( ) ) ;
// Wait for Gossipod to start
while !gossipod . is_running ( ) . await {
time :: sleep ( Duration :: from_millis ( 100 ) ) . await ;
}