Qrator filtra reta agorda administradsistemo

Qrator filtra reta agorda administradsistemo

TL; DR: Priskribo de la kliento-servila arkitekturo de nia interna reta agorda administradsistemo, QControl. Ĝi baziĝas sur du-tavola transportprotokolo kiu funkcias kun gzip-pakitaj mesaĝoj sen malkunpremo inter finpunktoj. Distribuitaj enkursigiloj kaj finpunktoj ricevas agordajn ĝisdatigojn, kaj la protokolo mem permesas la instaladon de lokalizitaj mezaj relajsoj. La sistemo estas konstruita sur la principo diferenciga sekurkopio ("lastatempa-stabila", klarigita malsupre) kaj uzas la demandlingvon JMESpath kune kun la ŝablona motoro Jinja por bildigi agordajn dosierojn.

Qrator Labs funkciigas tutmonde distribuitan atakan mildigan reton. Nia reto funkcias laŭ la principo anycast, kaj subretoj estas reklamitaj per BGP. Estante BGP anycast-reto fizike situanta en pluraj regionoj de la Tero, ni povas prilabori kaj filtri nelegitiman trafikon pli proksime al la kerno de la Interreto - Tier-1-funkciigistoj.

Aliflanke, esti geografie distribuita reto ne estas facila. Komunikado inter retpunktoj de ĉeesto estas kritika por la sekureca servoprovizanto havi konsekvencan agordon de ĉiuj retaj nodoj, ĝisdatigante ilin ĝustatempe. Tial, por provizi la plej altan eblan nivelon de kerna servo al la konsumanto, ni devis trovi manieron fidinde sinkronigi agordajn datumojn tra kontinentoj.

En la komenco estis la Vorto. Ĝi rapide iĝis komunika protokolo bezonanta ĝisdatigon.


La bazŝtono de la ekzisto de QControl, kaj samtempe la ĉefa kialo por elspezi gravan kvanton da tempo kaj rimedoj por konstrui ĉi tiun specon de protokolo, estas la bezono akiri ununuran aŭtoritatan fonton de agordo kaj, finfine, sinkronigi niajn punktojn de ĉeesto. kun ĝi. La stokado mem estis nur unu el pluraj postuloj dum la evoluo de QControl. Krome, ni ankaŭ bezonis integriĝojn kun ekzistantaj kaj planitaj servoj ĉe punktoj de ĉeesto (POP), inteligentaj (kaj agordeblaj) metodoj por validumado de datumoj, kaj ankaŭ alirkontrolon. Krom ĉi tio, ni ankaŭ volis kontroli tian sistemon uzante komandojn anstataŭ fari modifojn al dosieroj. Antaŭ QControl, datumoj estis senditaj al punktoj de ĉeesto preskaŭ permane. Se unu el la ĉeestpunktoj estus neatingebla kaj ni forgesus ĝisdatigi ĝin poste, la agordo finiĝus malsinkronigita kaj ni devus perdi tempon por refunkciigi ĝin.

Kiel rezulto, ni elpensis la sekvan skemon:
Qrator filtra reta agorda administradsistemo
La agorda servilo respondecas pri datenvalidigo kaj stokado; la enkursigilo havas plurajn finpunktojn kiuj ricevas kaj elsendas agordadatigojn de klientoj kaj subtenteamoj ĝis la servilo, kaj de la servilo ĝis punktoj de ĉeesto.

Interreta konektkvalito ankoraŭ multe varias tra la mondo - por ilustri ĉi tiun punkton, ni rigardu simplan MTR de Prago, Ĉeĥio ĝis Singapuro kaj Honkongo.

Qrator filtra reta agorda administradsistemo
MTR de Prago ĝis Singapuro

Qrator filtra reta agorda administradsistemo
Same al Honkongo

Alta latenteco signifas pli malaltan rapidecon. Krome, estas paka perdo. Kanala larĝo ne kompensas ĉi tiun problemon, kiu ĉiam devas esti konsiderata dum konstruado de malcentralizitaj sistemoj.

La plena agordo de punkto de ĉeesto estas grava kvanto da datumoj, kiuj devas esti senditaj al multaj ricevantoj per nefidindaj konektoj. Feliĉe, kvankam la agordo ŝanĝiĝas konstante, ĝi okazas en malgrandaj pliigoj.

Lastatempa-stabila dezajno

Ni povas diri, ke konstrui distribuitan reton bazitan sur la principo de pliigaj ĝisdatigoj estas sufiĉe evidenta solvo. Sed estas multaj problemoj kun diferencoj. Ni devas konservi ĉiujn diferencojn inter la referencpunktoj, kaj ankaŭ povi resendi ilin se iu maltrafis parton de la datumoj. Ĉiu celloko devas apliki ilin en strikte specifita sinsekvo. Tipe, en la kazo de pluraj cellokoj, tia operacio povas daŭri longan tempon. La ricevilo devas ankaŭ povi peti la mankantajn partojn kaj, kompreneble, la centra parto devas respondi al tia peto ĝuste, sendante nur la mankantajn datumojn.

Kiel rezulto, ni venis al sufiĉe interesa solvo - ni havas nur unu referencan tavolon, fiksitan, ni nomu ĝin stabila, kaj nur unu diferencon por ĝi - lastatempa. Ĉiu lastatempa baziĝas sur la lasta generita stalo kaj sufiĉas por rekonstrui la agordajn datumojn. Tuj kiam la freŝa freŝa atingas sian celon, la malnova ne plu estas bezonata.

Restas nur sendi freŝan stabilan agordon de tempo al tempo, ekzemple ĉar lastatempa fariĝis tro granda. Kio ankaŭ gravas ĉi tie estas, ke ni sendas ĉiujn ĉi tiujn ĝisdatigojn en elsendo/multelsenda reĝimo, sen zorgi pri individuaj ricevantoj kaj ilia kapablo kunmeti datumojn. Post kiam ni estas certaj, ke ĉiuj havas la ĝustan stalon, ni sendas nur novajn freŝajn. Ĉu indas klarigi, ke tio funkcias? Verkoj. Stalo estas konservita en la agorda servilo kaj ricevantoj, lastatempa estas kreita laŭbezone.

Arkitekturo de dunivela transporto

Kial ni konstruis nian transporton sur du niveloj? La respondo estas sufiĉe simpla - ni volis malkunligi vojigon de altnivela logiko, inspirante de la OSI-modelo kun ĝiaj transportaj kaj aplikaj tavoloj. Ni uzis Thrift por la rolo de la transportprotokolo, kaj la msgpack seriigformaton por la altnivela formato de kontrolmesaĝoj. Jen kial la enkursigilo (faranta multielsendo/elsendo/relajso) ne rigardas enen msgpack, ne malpakas aŭ pakas la enhavon reen, kaj nur plusendas datumojn.

Ŝparemo (el la angla - "ŝparemo", prononcita [θrift]) estas interfaca priskriba lingvo, kiu estas uzata por difini kaj krei servojn por malsamaj programlingvoj. Ĝi estas kadro por foraj proceduroj (RPC). Kombinas programaran dukton kun koda genera motoro por disvolvi servojn, kiuj funkcias pli-malpli efike kaj facile inter lingvoj.

Ni elektis la kadron Thrift pro RPC kaj subteno por multaj lingvoj. Kiel kutime, la facilaj partoj estis la kliento kaj servilo. Tamen, la enkursigilo montriĝis malfacila por fendi, parte pro la manko de preta solvo dum nia evoluo.

Qrator filtra reta agorda administradsistemoEstas aliaj ebloj, kiel protobuf / gRPC, tamen, kiam ni komencis nian projekton, gRPC estis sufiĉe nova kaj ni ne kuraĝis akcepti ĝin.

Kompreneble, ni povus (kaj fakte devus) konstrui nian propran biciklon. Estus pli facile krei protokolon por tio, kion ni bezonas, ĉar la kliento-servila arkitekturo estas relative facila por efektivigi kompare kun konstruado de enkursigilo sur Thrift. Unumaniere aŭ alia, ekzistas tradicia antaŭjuĝo al memskribitaj protokoloj kaj efektivigoj de popularaj bibliotekoj (pro bona kialo); krome, dum diskutoj ĉiam aperas la demando: "Kiel ni portos ĉi tion al aliaj lingvoj?" Do ni tuj forĵetis la ideon de biciklo.

Msgpack estas simila al JSON, sed pli rapida kaj pli malgranda. Ĝi estas binara datuma seriiga formato, kiu permesas interŝanĝi datumojn inter pluraj lingvoj.

Ĉe la unua nivelo ni havas Thrift kun la minimuma informo necesa por la enkursigilo por plusendi la mesaĝon. Ĉe la dua nivelo estas pakitaj msgpack-strukturoj.

Ni elektis msgpack ĉar ĝi estas pli rapida kaj pli kompakta kompare kun JSON. Sed pli grave, ĝi subtenas kutimajn datumtipojn, permesante al ni uzi bonegajn funkciojn kiel preterpasi krudajn binarojn aŭ specialajn objektojn indikante la foreston de datumoj, kio estis grava por nia "lastastabila" skemo.

JMESPath
JMESPath estas JSON demandlingvo.
Ĝuste tiel aspektas la priskribo, kiun ni ricevas de la oficiala JMESPath-dokumentado, sed fakte ĝi faras multe pli ol tio. JMESPath permesas vin serĉi kaj filtri subarbojn en arbitra arbstrukturo, kaj apliki ŝanĝojn al datumoj sur la flugo. Ĝi ankaŭ permesas vin aldoni specialajn filtrilojn kaj datumtransformprocedurojn. Kvankam ĝi, kompreneble, postulas cerban penon por kompreni.

jinja
Por iuj konsumantoj, ni devas transformi la agordon en dosieron - do ni uzas ŝablonmotoron kaj Jinja estas la evidenta elekto. Kun ĝia helpo, ni generas agordan dosieron el la ŝablono kaj datumoj ricevitaj ĉe la celo.

Por generi agordan dosieron, ni bezonas JMESPath-peton, ŝablonon por la dosierloko en la FS, kaj ŝablonon por la agordo mem. Ankaŭ estas bona ideo en ĉi tiu etapo klarigi la dosierpermesojn. Ĉio ĉi estis sukcese kombinita en unu dosiero - antaŭ la komenco de la agorda ŝablono, ni metis kaplinion en YAML-formato, kiu priskribas la reston.

Ekzemple:

---
selector: "[@][[email protected]._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
file_mode: 0644
reload_daemons: [fft] ...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

Por fari agordan dosieron por nova servo, ni nur aldonas novan ŝablondosieron. Neniuj ŝanĝoj al la fontkodo aŭ programaro pri la ĉeestpunktoj estas bezonataj.

Kio ŝanĝiĝis de kiam QControl ekfunkciis? La unua kaj plej grava afero estas konsekvenca kaj fidinda livero de agordaj ĝisdatigoj al ĉiuj nodoj en la reto. La dua estas ricevi potencan ilon por kontroli la agordon kaj fari ŝanĝojn al ĝi de nia subtena teamo, kaj ankaŭ de konsumantoj de la servo.

Ni povis fari ĉion ĉi uzante la lastatempan stabilan ĝisdatigskemon por simpligi komunikadon inter la agorda servilo kaj agordaj ricevantoj. Uzante du-tavolan protokolon por subteni enhav-sendependan manieron vojigi datumojn. Sukcese integris agordan generacian motoron bazitan en Jinja en distribuitan filtran reton. Ĉi tiu sistemo subtenas larĝan gamon de agordaj metodoj por niaj distribuitaj kaj heterogenaj ekstercentraj.

Dankon pro via helpo verki la materialon. VolanDamrod, serenheit, Ne.

Angla versio post.

fonto: www.habr.com

Aldoni komenton