Top fakapov Cyan

Top fakapov Cyan

Bonan al ĉiuj! 

Mi nomiĝas Nikita, mi estas la teamgvidanto de la Cian-inĝenierteamo. Unu el miaj respondecoj ĉe la kompanio estas redukti la nombron da incidentoj rilataj al infrastrukturo en produktado al nulo.
Kio estos diskutita sube alportis al ni multe da doloro, kaj la celo de ĉi tiu artikolo estas malhelpi aliajn homojn ripeti niajn erarojn aŭ almenaŭ minimumigi ilian efikon. 

Antaŭparolo

Antaŭ longa tempo, kiam Cian konsistis el monolitoj, kaj ankoraŭ ne estis sugestoj de mikroservoj, ni mezuris la haveblecon de rimedo kontrolante 3-5 paĝojn. 

Ili respondas - ĉio estas en ordo, se ili ne respondas dum longa tempo - vigla. Kiom longe ili devis esti senlabore por ke ĝi estu konsiderata okazaĵo estis decidita de homoj en kunvenoj. Teamo de inĝenieroj ĉiam estis implikita en la enketo de la okazaĵo. Kiam la esploro estis finita, ili skribis postmortan - specon de raporto retpoŝte en la formato: kio okazis, kiom longe ĝi daŭris, kion ni faris en la momento, kion ni faros estonte. 

La ĉefaj paĝoj de la retejo aŭ kiel ni komprenas, ke ni trafis la fundon

 
Por iel kompreni la prioritaton de la eraro, ni identigis la plej kritikajn retpaĝojn por komerca funkcieco. Uzante ilin, ni nombras la nombron da sukcesaj/malsukcesaj petoj kaj tempoforpasoj. Jen kiel ni mezuras funkcian tempon. 

Ni diru, ke ni eksciis, ke ekzistas kelkaj supergravaj sekcioj de la retejo, kiuj respondecas pri la ĉefa servo - serĉado kaj sendado de reklamoj. Se la nombro da malsukcesaj petoj superas 1%, tio estas kritika okazaĵo. Se ene de 15 minutoj dum pinttempo la eraroprocento superas 0,1%, tiam tio ankaŭ estas konsiderata kiel kritika okazaĵo. Ĉi tiuj kriterioj kovras la plej multajn el la okazaĵoj; la resto estas ekster la amplekso de ĉi tiu artikolo.

Top fakapov Cyan

Plej bonaj okazaĵoj Cian

Do, ni certe lernis determini la fakton, ke okazaĵo okazis. 

Nun ĉiu okazaĵo estas detale priskribita kaj reflektita en la Jira epopeo. Cetere: por tio ni komencis apartan projekton, nomatan FAIL - en ĝi oni povas krei nur epopeojn. 

Se vi kolektas ĉiujn malsukcesojn dum la lastaj jaroj, la gvidantoj estas: 

  • mssql rilataj okazaĵoj;
  • okazaĵoj kaŭzitaj de eksteraj faktoroj;
  • administraj eraroj.

Ni rigardu pli detale la erarojn de administrantoj, kaj ankaŭ iujn aliajn interesajn malsukcesojn.

Kvina loko - "Ordigante aferojn en la DNS"

Estis ŝtorma mardo. Ni decidis restarigi ordon en la DNS-grupo. 

Mi volis translokigi internajn DNS-servilojn de bind al powerdns, asignante tute apartajn servilojn por tio, kie estas nenio krom DNS. 

Ni metis unu DNS-servilon en ĉiu loko de niaj DC-oj, kaj venis la momento movi zonojn de bind al powerdns kaj ŝanĝi la infrastrukturon al novaj serviloj. 

En la mezo de la movo, el ĉiuj serviloj, kiuj estis specifitaj en lokaj kaŝmemoroj sur ĉiuj serviloj, nur unu restis, kiu estis en la datumcentro en Sankt-Peterburgo. Ĉi tiu DC estis komence deklarita kiel ne-kritika por ni, sed subite fariĝis ununura punkto de fiasko.
Estis dum ĉi tiu periodo de translokiĝo ke la kanalo inter Moskvo kaj Sankt-Peterburgo falis malsupren. Ni fakte restis sen DNS dum kvin minutoj kaj reiris kiam la gastiganto riparis la problemon. 

Konkludoj:

Se pli frue ni neglektis eksterajn faktorojn dum preparo por laboro, nun ili ankaŭ estas inkluzivitaj en la listo de tio, por kio ni preparas. Kaj nun ni strebas certigi, ke ĉiuj komponantoj estas rezervitaj n-2, kaj dum la laboro ni povas malaltigi ĉi tiun nivelon al n-1.

  • Dum ellaboro de agadplano, marku la punktojn kie la servo povus malsukcesi, kaj pripensu scenaron kie ĉio iris "de malbona al pli malbona" ​​anticipe.
  • Distribuu internajn DNS-servilojn tra malsamaj geolokigoj/datumcentroj/rakoj/ŝaltiloj/enigaĵoj.
  • Sur ĉiu servilo, instalu lokan kaŝmemoron DNS-servilon, kiu redirektas petojn al la ĉefaj DNS-serviloj, kaj se ĝi ne disponeblas, ĝi respondos el la kaŝmemoro. 

Kvara loko - "Purigado de aferoj en Nginx"

Iun bonan tagon, nia teamo decidis, ke "ni havis sufiĉe da ĉi tio", kaj la procezo de refactoring nginx-agordoj komenciĝis. La ĉefa celo estas alporti la agordojn al intuicia strukturo. Antaŭe, ĉio estis "historie establita" kaj ne portis ajnan logikon. Nun ĉiu servilo_nomo estis movita al dosiero de la sama nomo kaj ĉiuj agordoj estis distribuitaj en dosierujojn. Cetere, la agordo enhavas 253949 liniojn aŭ 7836520 signojn kaj okupas preskaŭ 7 megabajtojn. Plej alta nivelo de strukturo: 

Nginx strukturo

├── access
│   ├── allow.list
...
│   └── whitelist.conf
├── geobase
│   ├── exclude.conf
...
│   └── geo_ip_to_region_id.conf
├── geodb
│   ├── GeoIP.dat
│   ├── GeoIP2-Country.mmdb
│   └── GeoLiteCity.dat
├── inc
│   ├── error.inc
...
│   └── proxy.inc
├── lists.d
│   ├── bot.conf
...
│   ├── dynamic
│   └── geo.conf
├── lua
│   ├── cookie.lua
│   ├── log
│   │   └── log.lua
│   ├── logics
│   │   ├── include.lua
│   │   ├── ...
│   │   └── utils.lua
│   └── prom
│       ├── stats.lua
│       └── stats_prometheus.lua
├── map.d
│   ├── access.conf
│   ├── .. 
│   └── zones.conf
├── nginx.conf
├── robots.txt
├── server.d
│   ├── cian.ru
│   │   ├── cian.ru.conf
│   │   ├── ...
│   │   └── my.cian.ru.conf
├── service.d
│   ├── ...
│   └── status.conf
└── upstream.d
    ├── cian-mcs.conf
    ├── ...
    └── wafserver.conf

Ĝi fariĝis multe pli bona, sed dum la procezo de renomado kaj distribuado de agordoj, kelkaj el ili havis malĝustan etendon kaj ne estis inkluzivitaj en la direktivo include *.conf. Kiel rezulto, kelkaj gastigantoj iĝis neatingeblaj kaj resendis 301 al la ĉefpaĝo. Pro la fakto, ke la respondkodo ne estis 5xx/4xx, tion oni ne tuj rimarkis, sed nur matene. Post tio, ni komencis verki testojn por kontroli infrastrukturajn komponantojn.

Konkludoj: 

  • Struktu viajn agordojn ĝuste (ne nur nginx) kaj pripensu la strukturon en frua etapo de la projekto. Tiel vi faros ilin pli kompreneblaj al la teamo, kiu siavice reduktos TTM.
  • Skribu testojn por iuj infrastrukturaj komponantoj. Ekzemple: kontroli ke ĉiuj ŝlosilaj servilnomoj donas la ĝustan statuson + respondkorpon. Sufiĉos havi nur kelkajn skriptojn ĉemane, kiuj kontrolas la bazajn funkciojn de la komponanto, por ne freneze memori je la 3-a horo kion alian oni devas kontroli. 

Tria loko - "Subite elĉerpiĝis spaco en Kasandra"

La datumoj konstante kreskis, kaj ĉio estis bona ĝis la momento, kiam la riparo de grandaj kazspacoj komencis malsukcesi en la Kasandra areto, ĉar kompaktado ne povis funkcii sur ili. 

Iun ŝtorman tagon la areto preskaŭ fariĝis kukurbo, nome:

  • estis ĉirkaŭ 20% de la tuta spaco forlasita en la areto;
  • Estas neeble plene aldoni nodojn, ĉar purigado ne okazas post aldonado de nodo pro manko de spaco sur la sekcioj;
  • produktiveco iom post iom malpliiĝas ĉar kompaktado ne funkcias; 
  • La areto estas en kriz-reĝimo.

Top fakapov Cyan

Eliro - ni aldonis 5 pliajn nodojn sen purigado, post kio ni komencis sisteme forigi ilin el la areto kaj reeniri ilin, kiel malplenaj nodoj, kiuj elĉerpis spacon. Multe pli da tempo estis elspezita ol ni ŝatus. Ekzistis risko de parta aŭ kompleta malhavebleco de la areto. 

Konkludoj:

  • Sur ĉiuj Cassandra-serviloj, ne pli ol 60% de la spaco sur ĉiu sekcio devas esti okupita. 
  • Ili devus esti ŝarĝitaj je ne pli ol 50% CPU.
  • Vi ne forgesu pri kapacita planado kaj devas pripensi ĝin por ĉiu komponanto, surbaze de ĝiaj specifaĵoj.
  • Ju pli da nodoj en la areto, des pli bone. Serviloj enhavantaj malgrandan kvanton da datumoj estas troŝarĝitaj pli rapide, kaj tia areto estas pli facile revivigebla. 

Dua loko - "Datumoj malaperis de konsula ŝlosilvalora konservado"

Por serva malkovro, ni, kiel multaj, uzas konsulon. Sed ni ankaŭ uzas ĝian ŝlosilvaloron por bluverda aranĝo de la monolito. Ĝi stokas informojn pri aktivaj kaj neaktivaj kontraŭfluoj, kiuj ŝanĝas lokojn dum deplojo. Por tiu celo, deploja servo estis skribita kiu interagis kun KV. En iu momento, la datumoj de KV malaperis. Restarigite el memoro, sed kun kelkaj eraroj. Kiel rezulto, dum la alŝuto, la ŝarĝo sur la kontraŭfluoj estis distribuita malegale, kaj ni ricevis multajn 502-erarojn pro la backends troŝarĝitaj sur la CPU. Rezulte ni transiris de konsulo KV al postgres, de kie ne plu estas tiel facile forigi ilin.  

Konkludoj:

  • Servoj sen ajna rajtigo ne devus enhavi datumojn kritikajn por la funkciado de la retejo. Ekzemple, se vi ne havas rajtigon en ES, estus pli bone rifuzi aliron je la reto-nivelo de ĉie, kie ĝi ne bezonas, lasi nur la necesajn, kaj ankaŭ agordi action.destructive_requires_name: true.
  • Praktiku vian rezervan kaj reakiran mekanismon anticipe. Ekzemple, faru skripton anticipe (ekzemple en python) kiu povas sekurkopii kaj restarigi.

Unua loko - "Kapitano Unobvious" 

Iam ni rimarkis neegalan distribuon de ŝarĝo sur nginx kontraŭflue en kazoj kie estis 10+ serviloj en la backend. Pro la fakto, ke round-robin sendis petojn de la 1-a ĝis la lasta kontraŭflue en ordo, kaj ĉiu reŝargo de nginx rekomencis, la unuaj kontraŭfluoj ĉiam ricevis pli da petoj ol la ceteraj. Kiel rezulto, ili funkciis pli malrapide kaj la tuta retejo suferis. Ĉi tio iĝis ĉiam pli videbla kiam la kvanto de trafiko pliiĝis. Simple ĝisdatigi nginx por ebligi hazardan ne funkciis - ni devas refari amason da lua kodo, kiu ne ekflugis sur versio 1.15 (tiutempe). Ni devis fliki nian nginx 1.14.2, enkondukante hazardan subtenon en ĝi. Ĉi tio solvis la problemon. Ĉi tiu cimo gajnas la kategorion "Kapitano Ne-evidenteco".

Konkludoj:

Estis tre interese kaj ekscite esplori ĉi tiun cimon). 

  • Organizu vian monitoradon por ke ĝi helpu vin trovi tiajn fluktuojn rapide. Ekzemple, vi povas uzi ELK por monitori rps sur ĉiu backend de ĉiu kontraŭflue, monitori ilian respondtempon el la vidpunkto de nginx. En ĉi tiu kazo, ĉi tio helpis nin identigi la problemon. 

Kiel rezulto, la plej multaj el la fiaskoj povus esti evititaj per pli skrupula aliro al tio, kion vi faris. Ni devas ĉiam memori la leĝon de Murphy: Ĉio, kio povas misfunkcii, misfunkciiĝos, kaj konstrui komponantojn bazitajn sur ĝi. 

fonto: www.habr.com

Aldoni komenton