Lima siswa lan telung toko kunci sing disebarake

Utawa carane kita nulis klien C ++ perpustakaan kanggo ZooKeeper, etcd lan Konsul KV

Ing jagad sistem sing disebarake, ana sawetara tugas khas: nyimpen informasi babagan komposisi kluster, ngatur konfigurasi simpul, ndeteksi simpul sing rusak, milih pimpinan. lan liyane. Kanggo ngatasi masalah kasebut, sistem distribusi khusus wis digawe - layanan koordinasi. Saiki kita bakal kasengsem ing telu mau: ZooKeeper, etcd lan Konsul. Saka kabeh fungsi kaya Konsul, kita bakal fokus ing Konsul KV.

Lima siswa lan telung toko kunci sing disebarake

Intine, kabeh sistem kasebut minangka toko nilai kunci sing bisa dilipat. Sanajan model data kasebut duwe bedane sing signifikan, sing bakal dibahas mengko, dheweke ngrampungake masalah praktis sing padha. Temenan, saben aplikasi sing nggunakake layanan koordinasi digandhengake karo salah sijine, sing bisa nyebabake kabutuhan ndhukung sawetara sistem ing siji pusat data sing ngrampungake masalah sing padha kanggo aplikasi sing beda-beda.

Ing idea kanggo ngatasi masalah iki asalé saka agensi consulting Australia, lan ambruk kanggo kita, tim cilik mahasiswa, kanggo ngleksanakake, kang aku arep ngomong bab.

Kita ngatur kanggo nggawe perpustakaan sing nyedhiyani antarmuka umum kanggo nggarap ZooKeeper, etcd lan Konsul KV. Pustaka ditulis ing C ++, nanging ana rencana kanggo port menyang basa liyane.

Model Data

Kanggo ngembangake antarmuka umum kanggo telung sistem sing beda, sampeyan kudu ngerti apa sing padha lan kepiye bedane. Ayo dadi tokoh metu.

Kebon Binatang

Lima siswa lan telung toko kunci sing disebarake

Tombol diatur dadi wit lan diarani simpul. Mulane, kanggo simpul sampeyan bisa entuk dhaptar anak-anake. Operasi nggawe znode (nggawe) lan ngganti nilai (setData) dipisahake: mung tombol sing ana sing bisa diwaca lan diganti. Watches bisa ditempelake ing operasi mriksa orane simpul, maca nilai, lan njupuk anak. Watch minangka pemicu siji-wektu sing murub nalika versi data sing cocog ing server diganti. Node ephemeral digunakake kanggo ndeteksi kegagalan. Dheweke diikat karo sesi klien sing nggawe dheweke. Nalika klien nutup sesi utawa mandheg ngandhani ZooKeeper babagan orane, simpul kasebut kanthi otomatis dibusak. Transaksi prasaja didhukung - sakumpulan operasi sing kabeh bisa sukses utawa gagal yen iki ora bisa ditindakake paling ora siji.

lsp

Lima siswa lan telung toko kunci sing disebarake

Pangembang saka sistem iki padha cetha inspirasi dening ZooKeeper, lan mulane nindakake kabeh beda. Ora ana hirarki tombol, nanging padha mbentuk set lexicographically dhawuh. Sampeyan bisa entuk utawa mbusak kabeh tombol sing ana ing kisaran tartamtu. Struktur iki bisa uga katon aneh, nanging nyatane ekspresif banget, lan tampilan hierarkis bisa ditiru kanthi gampang.

etcd ora duwe operasi mbandhingake-lan-set standar, nanging duwe soko luwih apik: transaksi. Mesthi, padha ana ing kabeh telung sistem, nanging etcd transaksi utamané apik. Dheweke kalebu telung blok: mriksa, sukses, gagal. Blok pisanan ngemot sakumpulan kahanan, kaloro lan katelu - operasi. Transaksi kasebut ditindakake kanthi atom. Yen kabeh kahanan bener, banjur blok sukses dieksekusi, yen blok gagal dieksekusi. Ing API 3.3, pamblokiran sukses lan gagal bisa ngemot transaksi bersarang. Yaiku, bisa ditindakake kanthi atom nglakokake konstruksi kondisional kanthi tingkat nesting sing meh sewenang-wenang. Sampeyan bisa mangerteni sing luwih lengkap babagan apa mriksa lan operasi saka dokumentasi.

Jam tangan uga ana ing kene, sanajan rada rumit lan bisa digunakake maneh. Yaiku, sawise nginstal jam tangan ing sawetara tombol, sampeyan bakal nampa kabeh nganyari ing kisaran iki nganti sampeyan mbatalake jam tangan, lan ora mung sing pisanan. Ing etcd, analog saka sesi klien ZooKeeper minangka sewa.

Konsul K.V.

Ora ana struktur hierarki sing ketat ing kene, nanging Konsul bisa nggawe tampilan sing ana: sampeyan bisa njaluk lan mbusak kabeh tombol kanthi awalan sing ditemtokake, yaiku, nggarap "subtree" tombol kasebut. Pitakonan kasebut diarani rekursif. Kajaba iku, Konsul mung bisa milih tombol sing ora ngemot karakter kasebut sawise ater-ater, sing cocog kanggo entuk "anak" langsung. Nanging kudu eling yen iki minangka tampilan struktur hirarkis: cukup bisa nggawe kunci yen ora ana wong tuwa utawa mbusak kunci sing duwe anak, dene bocah-bocah bakal terus disimpen ing sistem kasebut.

Lima siswa lan telung toko kunci sing disebarake
Tinimbang jam tangan, Konsul wis mblokir panjalukan HTTP. Intine, iki minangka telpon biasa kanggo metode maca data, sing, bebarengan karo paramèter liyane, versi data pungkasan sing dikawruhi dituduhake. Yen versi saiki data sing cocog ing server luwih gedhe tinimbang sing ditemtokake, respon kasebut langsung bali, yen ora - nalika owah-owahan regane. Ana uga sesi sing bisa digandhengake karo tombol kapan wae. Wigati dicathet yen ora kaya etcd lan ZooKeeper, ing ngendi mbusak sesi ndadékaké pambusakan tombol sing gegandhengan, ana mode sing sesi kasebut mung ora disambungake. kasedhiya transaksi, tanpa cabang, nanging karo kabeh jinis mriksa.

Sijine kabeh bebarengan

ZooKeeper nduweni model data sing paling ketat. Pitakonan sawetara ekspresif sing kasedhiya ing etcd ora bisa ditiru kanthi efektif ing ZooKeeper utawa Konsul. Nyoba kanggo nggabungake sing paling apik saka kabeh layanan, kita rampung karo antarmuka sing meh padha karo antarmuka ZooKeeper kanthi pangecualian sing signifikan ing ngisor iki:

  • urutan, wadhah lan TTL kelenjar ora didhukung
  • ACL ora didhukung
  • metode set nggawe kunci yen ora ana (ing ZK setData ngasilake kesalahan ing kasus iki)
  • cara set lan cas dipisahake (ing ZK padha ateges padha)
  • cara mbusak mbusak simpul bebarengan karo subtree (ing ZK delete ngasilake kesalahan yen simpul duwe anak)
  • Kanggo saben tombol mung ana siji versi - versi nilai (ing ZK ana telu)

Penolakan saka kelenjar urutan amarga kasunyatan sing etcd lan Konsul ora duwe dibangun ing support kanggo wong-wong mau, lan padha bisa gampang dipun ginakaken dening pangguna ing ndhuwur antarmuka perpustakaan asil.

Ngleksanakake prilaku padha ZooKeeper nalika mbusak vertex mbutuhake njaga counter anak kapisah kanggo saben tombol ing etcd lan Konsul. Amarga kita nyoba supaya ora nyimpen informasi meta, diputusake kanggo mbusak kabeh subtree.

Subtleties saka implementasine

Ayo dideleng sawetara aspek implementasi antarmuka perpustakaan ing macem-macem sistem.

Hierarki ing etc

Njaga tampilan hierarki ing etcd dadi salah sawijining tugas sing paling menarik. Pitakonan kisaran nggawe gampang njupuk dhaptar kunci kanthi ater-ater sing ditemtokake. Contone, yen sampeyan butuh kabeh sing diwiwiti "/foo", sampeyan njaluk sawetara ["/foo", "/fop"). Nanging iki bakal ngasilake kabeh subtree kunci, sing bisa uga ora bisa ditampa yen subtree gedhe. Kaping pisanan, kita ngrancang nggunakake mekanisme terjemahan utama, dipun ginakaken ing zetcd. Iki kalebu nambahake siji bait ing wiwitan tombol, padha karo ambane simpul ing wit. Ayo kula menehi conto.

"/foo" -> "u01/foo"
"/foo/bar" -> "u02/foo/bar"

Banjur njaluk kabeh anak langsung kunci "/foo" bisa kanthi njaluk sawetara ["u02/foo/", "u02/foo0"). Ya, ing ASCII "0" ngadeg sakwise "/".

Nanging carane ngleksanakake aman saka vertex ing kasus iki? Pranyata sampeyan kudu mbusak kabeh kisaran jinis kasebut ["uXX/foo/", "uXX/foo0") kanggo XX saka 01 kanggo FF. Banjur kita mlayu menyang watesan nomer operasi ing siji transaksi.

Akibaté, sistem konversi tombol prasaja wis nemokke, kang ndadekake iku bisa kanggo èfèktif ngleksanakake loro mbusak tombol lan entuk dhaptar anak. Cukup kanggo nambah karakter khusus sadurunge token pungkasan. Tuladhane:

"/very" -> "/u00very"
"/very/long" -> "/very/u00long"
"/very/long/path" -> "/very/long/u00path"

Banjur mbusak tombol "/very" dadi pambusakan "/u00very" lan jangkoan ["/very/", "/very0"), lan njupuk kabeh anak - ing panjalukan kanggo tombol saka sawetara ["/very/u00", "/very/u01").

Mbusak tombol ing ZooKeeper

Kaya sing wis dakcritakake, ing ZooKeeper sampeyan ora bisa mbusak simpul yen duwe anak. Kita pengin mbusak tombol bebarengan karo subtree. Aku kudu piye? Kita nindakake iki kanthi optimisme. Kaping pisanan, kita ngliwati subtree kanthi rekursif, entuk anak-anak saka saben vertex kanthi pitakon sing kapisah. Banjur kita mbangun transaksi sing nyoba mbusak kabeh kelenjar subtree ing urutan sing bener. Mesthi wae, owah-owahan bisa kedadeyan ing antarane maca subtree lan mbusak. Ing kasus iki, transaksi bakal gagal. Kajaba iku, subtree bisa diganti sajrone proses maca. Panjaluk kanggo anak saka simpul sabanjure bisa ngasilake kesalahan yen, contone, simpul iki wis dibusak. Ing kasus loro, kita mbaleni kabeh proses maneh.

Pendekatan iki ndadekake mbusak tombol banget ora efektif yen wis anak, lan malah luwih yen aplikasi terus bisa karo subtree, mbusak lan nggawe tombol. Nanging, iki ngidini kita supaya ora rumit implementasine cara liya ing etcd lan Konsul.

disetel ing ZooKeeper

Ing ZooKeeper ana cara kapisah sing bisa digunakake karo struktur wit (nggawe, mbusak, getChildren) lan sing bisa digunakake karo data ing simpul (setData, getData). wis digawe, mbusak utawa setData - yen durung ana. We needed cara pesawat sing bisa disebut tanpa mikir bab ngarsane tombol.

Salah siji opsi yaiku njupuk pendekatan optimis, kaya karo pambusakan. Priksa manawa ana simpul. Yen ana, nelpon setData, yen ora nggawe. Yen cara pungkasan ngasilake kesalahan, baleni maneh. Wangsulan: Bab ingkang pisanan kanggo Wigati iku test eksistensi punika tanpa guna. Sampeyan bisa langsung nelpon nggawe. Rampung sing sukses tegese simpul kasebut ora ana lan digawe. Yen ora, nggawe bakal ngasilake kesalahan sing cocog, sawise sampeyan kudu nelpon setData. Mesthi, ing antarane telpon, vertex bisa dibusak dening telpon saingan, lan setData uga bakal ngasilake kesalahan. Ing kasus iki, sampeyan bisa nindakake kabeh maneh, nanging iku worth iku?

Yen loro cara ngasilake kesalahan, mula kita ngerti manawa ana pambusakan sing saingan. Ayo mbayangno manawa pambusakan iki kedadeyan sawise nelpon set. Banjur makna apa wae sing arep ditetepake wis dibusak. Iki tegese kita bisa nganggep yen set wis dieksekusi kanthi sukses, sanajan ora ana sing ditulis.

Rincian liyane teknis

Ing bagean iki kita bakal ngaso saka sistem mbagekke lan pirembagan bab coding.
Salah sawijining syarat utama pelanggan yaiku lintas platform: paling ora siji layanan kudu didhukung ing Linux, MacOS lan Windows. Kaping pisanan, kita dikembangake mung kanggo Linux, lan wiwit nyoba ing sistem liyane mengko. Iki nyebabake akeh masalah, sing kanggo sawetara wektu ora jelas carane nyedhaki. Akibaté, kabeh telung layanan koordinasi saiki didhukung ing Linux lan MacOS, dene mung Consul KV sing didhukung ing Windows.

Wiwit wiwitan, kita nyoba nggunakake perpustakaan sing wis siap kanggo ngakses layanan. Ing cilik saka ZooKeeper, pilihan tiba ing ZooKeeper C++, sing pungkasane gagal dikompilasi ing Windows. Nanging, iki ora nggumunake: perpustakaan dipanggonke mung linux. Kanggo Konsul mung pilihan pkonsul. Dhukungan kudu ditambahake sesi и transaksi. Kanggo etcd, perpustakaan lengkap ndhukung versi paling anyar saka protokol ora ketemu, supaya kita mung klien grpc kui.

Inspirasi dening antarmuka bedo saka ZooKeeper C ++ perpustakaan, kita mutusaké uga ngleksanakake antarmuka bedo. ZooKeeper C ++ nggunakake mangsa / janji primitif kanggo iki. Ing STL, sayangé, padha dileksanakake banget andhap asor. Contone, ora banjur metode, sing ditrapake fungsi liwati kanggo asil mangsa nalika kasedhiya. Ing kasus kita, cara kuwi perlu kanggo ngowahi asil menyang format perpustakaan kita. Kanggo ngatasi masalah iki, kita kudu ngetrapake blumbang benang sing prasaja, amarga panjaluk pelanggan ora bisa nggunakake perpustakaan pihak katelu sing abot kayata Boost.

Kita banjur implementasine kaya iki. Nalika disebut, janji tambahan / pasangan mangsa digawe. Masa depan anyar bali, lan sing liwati diselehake bebarengan karo fungsi sing cocog lan janji tambahan ing antrian. Utas saka blumbang milih sawetara masa depan saka antrian lan polling nggunakake wait_for. Nalika asil kasedhiya, fungsi sing cocog diarani lan nilai bali diterusake menyang janji.

Kita nggunakake blumbang thread sing padha kanggo nglakokake pitakon kanggo etcd lan Konsul. Iki tegese perpustakaan dhasar bisa diakses kanthi macem-macem utas. ppconsul ora Utas aman, supaya telpon kanggo iku dilindhungi dening kunci.
Sampeyan bisa nggarap grpc saka pirang-pirang benang, nanging ana subtleties. Ing etcd Watches dipun ginakaken liwat grpc streams. Iki minangka saluran bidirectional kanggo pesen saka jinis tartamtu. Pustaka nggawe utas siji kanggo kabeh jam tangan lan utas siji sing ngolah pesen sing mlebu. Dadi grpc nglarang nulis paralel kanggo stream. Iki tegese nalika miwiti utawa mbusak jam tangan, sampeyan kudu ngenteni nganti panjaluk sadurunge wis rampung ngirim sadurunge ngirim sing sabanjure. Kita digunakake kanggo sinkronisasi variabel kondisional.

Asile

Deleng dhewe: liboffkv.

Tim kita: Raed Romanov, Ivan Glushenkov, Dmitry Kamaldinov, Victor Krapivensky, Vitaly Iwan.

Source: www.habr.com

Add a comment