
Habari, Habr! Mimi ni Artem Karamyshev, mkuu wa timu ya usimamizi wa mfumo . Tumekuwa na bidhaa nyingi mpya za uzinduzi katika mwaka uliopita. Tulitaka kuhakikisha kuwa huduma za API ni rahisi kupanuka, kustahimili makosa, na tayari kwa ukuaji wa haraka wa upakiaji wa watumiaji. Jukwaa letu linatekelezwa kwenye OpenStack, na ninataka kukuambia ni sehemu gani za shida za uvumilivu wa makosa tulilazimika kutatua ili kupata mfumo unaostahimili makosa. Nadhani hii itakuwa ya kuvutia kwa wale ambao pia hutengeneza bidhaa kwenye OpenStack.
Uvumilivu wa jumla wa hitilafu wa jukwaa unajumuisha uthabiti wa vipengele vyake. Kwa hivyo, hatua kwa hatua tutapitia viwango vyote ambapo tuligundua hatari na kuzifunga.
Toleo la video la hadithi hii, chanzo chake kikuu ambacho kilikuwa ripoti katika mkutano wa Uptime day 4, ulioandaliwa na , unaweza kuona .
Ustahimilivu wa usanifu wa kimwili
Sehemu ya umma ya wingu la MCS sasa inategemea vituo viwili vya data vya Tier III, kati yao kuna nyuzi zake zenye giza, zilizohifadhiwa katika kiwango cha kimwili na njia tofauti, na upitishaji wa 200 Gbit/s. Tier III hutoa kiwango muhimu cha uvumilivu wa makosa kwa miundombinu ya kimwili.
Fiber ya giza imehifadhiwa katika viwango vya kimwili na vya kimantiki. Mchakato wa kuhifadhi nafasi ya kituo ulikuwa wa mara kwa mara, matatizo yakatokea, na tunaboresha mawasiliano kati ya vituo vya data kila mara.
Kwa mfano, si muda mrefu uliopita, wakati wa kufanya kazi katika kisima karibu na moja ya vituo vya data, mchimbaji alivunja bomba, na ndani ya bomba hili kulikuwa na cable kuu na ya ziada ya macho. Kituo chetu cha mawasiliano kinachostahimili makosa na kituo cha data kiligeuka kuwa hatari kwa wakati mmoja, kwenye kisima. Kwa hiyo, tumepoteza sehemu ya miundombinu. Tulifanya hitimisho na kuchukua hatua kadhaa, ikiwa ni pamoja na kusakinisha optics ya ziada kwenye kisima kilicho karibu.
Katika vituo vya data kuna maeneo ya uwepo wa watoa huduma za mawasiliano ambao tunatangaza viambishi vyetu kupitia BGP. Kwa kila mwelekeo wa mtandao, metric bora huchaguliwa, ambayo inaruhusu wateja tofauti kutolewa kwa ubora bora wa uunganisho. Ikiwa mawasiliano kupitia mtoa huduma mmoja yatapungua, tunaunda upya uelekezaji wetu kupitia watoa huduma wanaopatikana.
Ikiwa mtoaji atashindwa, tunabadilisha kiotomatiki hadi anayefuata. Katika tukio la kushindwa kwa moja ya vituo vya data, tuna nakala ya kioo ya huduma zetu katika kituo cha pili cha data, ambacho kinachukua mzigo mzima.

Ustahimilivu wa miundombinu ya kimwili
Tunachotumia kwa uvumilivu wa kiwango cha maombi
Huduma yetu imejengwa juu ya idadi ya vipengele vya opensource.
ExaBGP ni huduma inayotekelezea idadi ya vitendakazi kwa kutumia itifaki ya uelekezaji inayobadilika kulingana na BGP. Tunaitumia kikamilifu kutangaza anwani zetu za IP zilizoidhinishwa ambapo watumiaji hufikia API.
HAProxy ni kisawazisha cha mzigo wa juu ambacho hukuruhusu kusanidi sheria zinazonyumbulika sana za kusawazisha trafiki katika viwango tofauti vya muundo wa OSI. Tunaitumia kusawazisha mbele ya huduma zote: hifadhidata, vidalali vya ujumbe, huduma za API, huduma za wavuti, miradi yetu ya ndani - kila kitu kiko nyuma ya HAProxy.
Programu ya API - programu ya wavuti iliyoandikwa kwa python, ambayo mtumiaji husimamia miundombinu yake na huduma yake.
Maombi ya mfanyakazi (hapa ni mfanyakazi tu) - katika huduma za OpenStack, hii ni daemon ya miundombinu ambayo hukuruhusu kutangaza amri za API kwa miundombinu. Kwa mfano, uumbaji wa disk hutokea kwa mfanyakazi, na ombi la uumbaji hutokea katika API ya maombi.
Usanifu wa Kawaida wa Maombi ya OpenStack
Huduma nyingi ambazo zimetengenezwa kwa OpenStack hujaribu kufuata dhana moja. Huduma kawaida huwa na sehemu 2: API na wafanyikazi (watekelezaji wa nyuma). Kama sheria, API ni programu ya WSGI kwenye python, ambayo inazinduliwa kama mchakato huru (daemon), au kutumia seva ya wavuti ya Nginx iliyotengenezwa tayari au Apache. API huchakata ombi la mtumiaji na kupitisha maagizo zaidi kwa maombi ya mfanyakazi kwa ajili ya utekelezaji. Uhamisho hutokea kwa kutumia wakala wa ujumbe, kwa kawaida RabbitMQ, wengine wanasaidiwa vibaya. Ujumbe unapomfikia wakala, huchakatwa na wafanyakazi na, ikiwa ni lazima, kurudisha jibu.
Mtazamo huu unahusisha pointi za kawaida za kutofaulu: RabbitMQ na hifadhidata. Lakini RabbitMQ imetengwa ndani ya huduma moja na, kwa nadharia, inaweza kuwa mtu binafsi kwa kila huduma. Kwa hivyo katika MCS tunatenganisha huduma hizi kadri tuwezavyo; kwa kila mradi mmoja mmoja tunaunda hifadhidata tofauti, RabbitMQ tofauti. Njia hii ni nzuri kwa sababu katika tukio la ajali katika maeneo fulani magumu, si huduma nzima inayoharibika, lakini ni sehemu yake tu.
Idadi ya maombi ya mfanyakazi haina kikomo, kwa hivyo API inaweza kupanua kwa urahisi nyuma ya visawazishaji ili kuongeza utendakazi na uvumilivu wa makosa.
Baadhi ya huduma zinahitaji uratibu ndani ya huduma wakati shughuli changamano za mfuatano zinapotokea kati ya API na wafanyakazi. Katika kesi hii, kituo kimoja cha uratibu hutumiwa, mfumo wa nguzo kama vile Redis, Memcache, nk, ambayo inaruhusu mfanyakazi mmoja kumwambia mwingine kwamba kazi hii amepewa ("tafadhali usiichukue"). Tunatumia nk. Kama sheria, wafanyikazi huwasiliana kikamilifu na hifadhidata, kuandika na kusoma habari kutoka hapo. Tunatumia mariadb kama hifadhidata, ambayo iko katika kundi la wasimamizi wengi.
Huduma hii ya kawaida ya kipekee imepangwa kwa njia inayokubalika kwa ujumla kwa OpenStack. Inaweza kuzingatiwa kama mfumo uliofungwa, ambao njia za kuongeza na uvumilivu wa makosa ni dhahiri kabisa. Kwa mfano, kwa uvumilivu wa kosa la API, inatosha kuweka usawa mbele yao. Kuongeza wafanyikazi kunapatikana kwa kuongeza idadi yao.
Hatua dhaifu katika mpango mzima ni RabbitMQ na MariaDB. Usanifu wao unastahili makala tofauti.Katika makala hii nataka kuzingatia uvumilivu wa makosa ya API.

Usanifu wa Maombi ya Openstack. Kusawazisha na kuvumilia makosa ya jukwaa la wingu
Kufanya usawazishaji wa HAProxy kustahimili makosa kwa kutumia ExaBGP
Ili kufanya API zetu ziwe scalable, haraka na kuhimili makosa, tunaweka mizani ya mzigo mbele yao. Tulichagua HAProxy. Kwa maoni yangu, ina sifa zote muhimu kwa kazi yetu: kusawazisha katika viwango kadhaa vya OSI, interface ya usimamizi, kubadilika na scalability, idadi kubwa ya mbinu za kusawazisha, usaidizi wa meza za kikao.
Tatizo la kwanza ambalo lilihitaji kutatuliwa lilikuwa uvumilivu wa makosa ya mizani yenyewe. Ufungaji tu wa kusawazisha pia husababisha kutofaulu: kusawazisha huvunjika na huduma huanguka. Ili kuzuia hili kutokea, tulitumia HAProxy kwa kushirikiana na ExaBGP.
ExaBGP hukuruhusu kutekeleza utaratibu wa kuangalia hali ya huduma. Tulitumia utaratibu huu kuangalia utendakazi wa HAProxy na, ikitokea matatizo, kuzima huduma ya HAProxy kutoka BGP.
Mpango wa ExaBGP+HAProxy
- Tunaweka programu muhimu, ExaBGP na HAProxy, kwenye seva tatu.
- Tunaunda kiolesura cha kitanzi kwenye kila seva.
- Kwenye seva zote tatu tunapeana anwani nyeupe ya IP kwenye kiolesura hiki.
- Anwani nyeupe ya IP inatangazwa kwenye Mtandao kupitia ExaBGP.
Uvumilivu wa hitilafu hupatikana kwa kutangaza anwani sawa ya IP kutoka kwa seva zote tatu. Kutoka kwa mtazamo wa mtandao, anwani sawa inapatikana kutoka kwa hops tatu tofauti zinazofuata. Router inaona njia tatu zinazofanana, huchagua kipaumbele cha juu zaidi kulingana na metric yake mwenyewe (hii kawaida ni chaguo sawa), na trafiki huenda tu kwa moja ya seva.
Katika kesi ya matatizo na uendeshaji wa HAProxy au kushindwa kwa seva, ExaBGP huacha kutangaza njia, na trafiki hubadilika kwa seva nyingine.
Kwa hivyo, tulipata uvumilivu wa makosa ya mizani.

Uvumilivu wa makosa ya wasawazishaji wa HAProxy
Mpango huo uligeuka kuwa usio kamili: tulijifunza jinsi ya kuhifadhi HAProxy, lakini hatukujifunza jinsi ya kusambaza mzigo ndani ya huduma. Kwa hiyo, tulipanua mpango huu kidogo: tuliendelea kusawazisha kati ya anwani kadhaa nyeupe za IP.
Kusawazisha kulingana na DNS pamoja na BGP
Suala la kusawazisha mzigo kwa HAProksi yetu bado halijatatuliwa. Walakini, inaweza kutatuliwa kwa urahisi kabisa, kama tulivyofanya hapa.
Ili kusawazisha seva tatu utahitaji anwani 3 nyeupe za IP na DNS nzuri ya zamani. Kila moja ya anwani hizi imedhamiriwa kwenye kiolesura cha kitanzi cha kila HAProksi na kutangazwa kwenye Mtandao.
Katika OpenStack, kusimamia rasilimali, saraka ya huduma hutumiwa, ambayo inabainisha API ya mwisho ya huduma fulani. Katika saraka hii tunasajili jina la kikoa - public.infra.mail.ru, ambayo inatatuliwa kupitia DNS na anwani tatu tofauti za IP. Kama matokeo, tunapata usambazaji wa mzigo kati ya anwani tatu kupitia DNS.
Lakini kwa kuwa wakati wa kutangaza anwani nyeupe za IP hatudhibiti vipaumbele vya uteuzi wa seva, hii bado haijasawazisha. Kwa kawaida, seva moja pekee itachaguliwa kulingana na ukubwa wa anwani ya IP, na nyingine mbili zitakuwa bila kufanya kitu kwa sababu hakuna vipimo vilivyobainishwa katika BGP.
Tulianza kutuma njia kupitia ExaBGP na vipimo tofauti. Kila msawazishaji anatangaza anwani zote tatu nyeupe za IP, lakini moja yao, moja kuu kwa usawa huu, inatangazwa na kipimo cha chini zaidi. Kwa hivyo wakati wasawazishaji wote watatu wanafanya kazi, simu kwa anwani ya IP ya kwanza huenda kwa mizani ya kwanza, huita ya pili hadi ya pili, na inaita ya tatu hadi ya tatu.
Nini kinatokea wakati mmoja wa mizani anaanguka? Ikiwa usawazishaji wowote hautafaulu, anwani yake kuu bado inatangazwa kutoka kwa zingine mbili, na trafiki inasambazwa tena kati yao. Kwa hivyo, tunampa mtumiaji anwani kadhaa za IP mara moja kupitia DNS. Kwa kusawazisha kwa kutumia DNS na vipimo tofauti, tunapata usambazaji sawa wa mzigo kwenye visawazishi vyote vitatu. Na wakati huo huo hatupoteza uvumilivu wa makosa.

Kusawazisha HAProksi kulingana na DNS + BGP
Mwingiliano kati ya ExaBGP na HAProxy
Kwa hivyo, tulitekeleza uvumilivu wa makosa ikiwa seva itaondoka, kwa kuzingatia kusimamisha tangazo la njia. Lakini HAProxy inaweza kuzima kwa sababu nyingine zaidi ya kushindwa kwa seva: makosa ya utawala, kushindwa ndani ya huduma. Tunataka kuondoa mizani iliyovunjika kutoka chini ya mzigo katika kesi hizi pia, na tunahitaji utaratibu tofauti.
Kwa hivyo, kwa kupanua mpango uliopita, tulitekeleza mapigo ya moyo kati ya ExaBGP na HAProxy. Huu ni utekelezaji wa programu ya mwingiliano kati ya ExaBGP na HAProxy, wakati ExaBGP inatumia hati maalum ili kuangalia hali ya programu.
Ili kufanya hivyo, unahitaji kusanidi ukaguzi wa afya katika usanidi wa ExaBGP, ambayo inaweza kuangalia hali ya HAProxy. Kwa upande wetu, tulisanidi hali ya nyuma ya afya katika HAProxy, na kutoka upande wa ExaBGP tunaangalia na ombi rahisi la GET. Ikiwa tangazo litaacha kutokea, basi HAProxy kuna uwezekano mkubwa kuwa haifanyi kazi na hakuna haja ya kuitangaza.

Ukaguzi wa Afya wa HAProxy
HAProxy Peers: maingiliano ya kipindi
Jambo lililofuata la kufanya ni kusawazisha vipindi. Wakati wa kufanya kazi kwa njia ya mizani iliyosambazwa, ni vigumu kuandaa uhifadhi wa habari kuhusu vikao vya mteja. Lakini HAProxy ni mojawapo ya wasawazishaji wachache wanaoweza kufanya hivi kutokana na utendakazi wa Rika - uwezo wa kuhamisha majedwali ya kikao kati ya michakato tofauti ya HAProxy.
Kuna njia tofauti za kusawazisha: rahisi kama vile , na kupanuliwa, wakati kikao cha mteja kinakumbukwa, na kila wakati anaishia kwenye seva sawa na hapo awali. Tulitaka kutekeleza chaguo la pili.
HAProxy hutumia vijiti-meza ili kuhifadhi vipindi vya mteja vya utaratibu huu. Wanahifadhi anwani ya IP ya mteja, anwani iliyochaguliwa (nyuma) na maelezo fulani ya huduma. Kwa kawaida, majedwali ya vijiti hutumiwa kuhifadhi jozi ya chanzo-IP + lengwa-IP, ambayo ni muhimu hasa kwa programu ambazo haziwezi kuhamisha muktadha wa kipindi cha mtumiaji wakati wa kubadili kiweka sawazishaji kingine, kwa mfano, katika hali ya kusawazisha ya RoundRobin.
Ikiwa jedwali la vijiti linafundishwa kusonga kati ya michakato tofauti ya HAProxy (kati ya ambayo kusawazisha hufanyika), wasawazishaji wetu wataweza kufanya kazi na kundi moja la meza za vijiti. Hii itafanya iwezekane kubadili mtandao wa mteja kwa urahisi ikiwa moja ya visawazishaji itashindwa; kufanya kazi na vipindi vya mteja kutaendelea kwenye sehemu za nyuma zile zile ambazo zilichaguliwa hapo awali.
Kwa uendeshaji sahihi, tatizo la anwani ya IP ya chanzo cha usawazishaji ambayo kikao kilianzishwa lazima kutatuliwa. Kwa upande wetu, hii ni anwani yenye nguvu kwenye kiolesura cha loopback.
Kazi sahihi ya wenzao hupatikana tu chini ya hali fulani. Hiyo ni, muda wa kuisha kwa TCP lazima uwe wa kutosha au ubadilishaji lazima uwe wa haraka vya kutosha ili kipindi cha TCP kisipate muda wa kusitishwa. Hata hivyo, inaruhusu byte imefumwa.
Katika IaaS tuna huduma iliyojengwa kwa kutumia teknolojia sawa. Hii , ambayo inaitwa Octavia. Inategemea michakato miwili ya HAProxy na mwanzoni inajumuisha usaidizi kwa wenzao. Wamejidhihirisha kuwa bora katika huduma hii.
Picha inaonyesha kimkakati msogeo wa jedwali rika kati ya matukio matatu ya HAProxy, usanidi unapendekezwa kuhusu jinsi hii inaweza kusanidiwa:

HAProxy Peers (usawazishaji wa kipindi)
Ikiwa unatekeleza mpango huo huo, uendeshaji wake lazima ufanyike kwa uangalifu. Sio ukweli kwamba itafanya kazi kwa njia sawa 100% ya wakati. Lakini angalau hutapoteza meza za vijiti wakati unahitaji kukumbuka IP ya chanzo cha mteja.
Kupunguza idadi ya maombi ya wakati mmoja kutoka kwa mteja sawa
Huduma zozote zinazopatikana kwa umma, ikijumuisha API zetu, zinaweza kutegemea maporomoko ya maombi. Sababu zao zinaweza kuwa tofauti kabisa, kutoka kwa makosa ya mtumiaji hadi mashambulizi yaliyolengwa. Tunatumiwa mara kwa mara na anwani za IP. Wateja mara nyingi hufanya makosa katika hati zao na kutupa mini-DDoSs.
Njia moja au nyingine, ulinzi wa ziada lazima utolewe. Suluhisho dhahiri ni kupunguza idadi ya maombi ya API na sio kupoteza wakati wa usindikaji wa ombi hasidi.
Ili kutekeleza vikwazo vile, tunatumia mipaka ya kiwango, iliyoandaliwa kwa misingi ya HAProxy, kwa kutumia meza sawa za fimbo. Kuweka mipaka ni rahisi sana na hukuruhusu kuweka kikomo cha mtumiaji kwa idadi ya maombi kwa API. Algorithm inakumbuka IP ya chanzo ambayo maombi hufanywa na kupunguza idadi ya maombi ya wakati mmoja kutoka kwa mtumiaji mmoja. Bila shaka, tulihesabu wasifu wa wastani wa upakiaji wa API kwa kila huduma na kuweka kikomo cha ≈ mara 10 ya thamani hii. Tunaendelea kufuatilia kwa karibu hali hiyo na kuweka kidole kwenye pigo.
Je, hii inaonekanaje katika mazoezi? Tuna wateja ambao hutumia API zetu mara kwa mara kufanya mizani kiotomatiki. Wanaunda takriban mashine mia mbili hadi tatu asubuhi na kuzifuta jioni. Kwa OpenStack, kuunda mashine ya kawaida, pia na huduma za PaaS, inahitaji angalau maombi 1000 ya API, kwani mwingiliano kati ya huduma pia hutokea kupitia API.
Uhamisho kama huo wa kazi husababisha mzigo mkubwa. Tulikagua mzigo huu, tukakusanya vilele vya kila siku, tukaongeza mara kumi, na hii ikawa kikomo chetu cha viwango. Tunaweka kidole kwenye pigo. Mara nyingi tunaona roboti na vichanganuzi vinavyojaribu kutuangalia ili kuona kama tuna hati zozote za CGA zinazoweza kuendeshwa, tunazikata kikamilifu.
Jinsi ya kusasisha codebase yako bila watumiaji kutambua
Pia tunatekeleza ustahimilivu wa makosa katika kiwango cha michakato ya kusambaza msimbo. Kunaweza kuwa na hitilafu wakati wa uchapishaji, lakini athari zake kwenye upatikanaji wa huduma zinaweza kupunguzwa.
Tunasasisha huduma zetu kila mara na lazima tuhakikishe kuwa codebase inasasishwa bila kuathiri watumiaji. Tulifanikiwa kutatua tatizo hili kwa kutumia uwezo wa usimamizi wa HAProxy na utekelezaji wa Kuzima kwa Neema katika huduma zetu.
Ili kutatua tatizo hili, ilikuwa ni lazima kuhakikisha udhibiti wa mizani na kuzima "sahihi" kwa huduma:
- Kwa upande wa HAProxy, udhibiti unafanywa kupitia faili ya takwimu, ambayo kimsingi ni tundu na imefafanuliwa katika usanidi wa HAProxy. Unaweza kutuma amri kwake kupitia stdio. Lakini chombo chetu kikuu cha udhibiti wa usanidi kinastahili, kwa hiyo ina moduli iliyojengwa ya kusimamia HAProxy. Ambayo tunatumia kikamilifu.
- Huduma zetu nyingi za API na Injini zinaunga mkono teknolojia nzuri za kuzima: wakati wa kuzima, hungoja kazi ya sasa ikamilike, iwe ombi la http au kazi fulani ya huduma. Kitu kimoja kinatokea kwa mfanyakazi. Inajua kazi zote inazofanya na kuishia ikiwa imekamilisha kila kitu kwa mafanikio.
Shukrani kwa pointi hizi mbili, kanuni salama ya utumaji wetu inaonekana kama hii.
- Msanidi hukusanya kifurushi kipya cha msimbo (kwetu hii ni RPM), huijaribu katika mazingira ya dev, huijaribu katika hatua, na kuiacha kwenye hazina ya hatua.
- Msanidi huweka kazi ya kupelekwa kwa maelezo ya kina zaidi ya "vizalia vya zamani": toleo la kifurushi kipya, maelezo ya utendakazi mpya na maelezo mengine kuhusu uwekaji ikiwa ni lazima.
- Msimamizi wa mfumo anaanza sasisho. Inazindua Ansible playbook, ambayo nayo hufanya yafuatayo:
- Huchukua kifurushi kutoka kwa hazina ya hatua na kukitumia kusasisha toleo la kifurushi kwenye hazina ya bidhaa.
- Hukusanya orodha ya viunga vya huduma iliyosasishwa.
- Huzima huduma ya kwanza kusasishwa katika HAProxy na inasubiri michakato yake imalizike. Shukrani kwa kuzima kwa njia nzuri, tuna uhakika kwamba maombi yote ya sasa ya mteja yatakamilika kwa mafanikio.
- Baada ya API na wafanyikazi kusimamishwa kabisa, na HAProxy imezimwa, msimbo unasasishwa.
- Ansible huendesha huduma.
- Kwa kila huduma, "vipini" fulani huvutwa, ambavyo hufanya upimaji wa kitengo kwenye idadi ya vipimo vya ufunguo vilivyoainishwa mapema. Ukaguzi wa msingi wa msimbo mpya unafanyika.
- Ikiwa hakuna makosa yaliyopatikana katika hatua ya awali, backend imeanzishwa.
- Wacha tuendelee kwenye sehemu inayofuata.
- Baada ya viambajengo vyote kusasishwa, majaribio ya utendaji huzinduliwa. Ikiwa hazipo, basi msanidi huangalia utendakazi wowote mpya ambao ameunda.
Hii inakamilisha uwekaji.

Mzunguko wa sasisho la huduma
Mpango huu haungefanya kazi ikiwa hatungekuwa na sheria moja. Tunaunga mkono matoleo ya zamani na mapya katika vita. Mapema, katika hatua ya maendeleo ya programu, imewekwa kwamba hata ikiwa kuna mabadiliko katika hifadhidata ya huduma, hawatavunja msimbo uliopita. Kama matokeo, msingi wa nambari unasasishwa hatua kwa hatua.
Hitimisho
Kushiriki mawazo yangu mwenyewe juu ya usanifu wa WEB unaostahimili makosa, ningependa kwa mara nyingine kutambua mambo yake muhimu:
- uvumilivu wa makosa ya kimwili;
- uvumilivu wa makosa ya mtandao (balancers, BGP);
- uvumilivu wa makosa ya programu iliyotumiwa na kuendelezwa.
Muda thabiti wa kila mtu!
Chanzo: mapenzi.com
