10 yeas of experience of building mission critical Fintech system handling extremely high load
Walkthroughs, tutorials, guides, and tips. This story will teach you how to do something new or how to do something better.
Uthabiti katika programu hurejelea uwezo wa programu kuendelea kufanya kazi vizuri na kwa kutegemewa, hata inapokabiliwa na matatizo au matatizo yasiyotarajiwa. Katika miradi ya Fintech uthabiti ni wa umuhimu mkubwa kwa sababu kadhaa. Kwanza, makampuni yanalazimika kukidhi mahitaji ya udhibiti na wasimamizi wa fedha wanasisitiza uthabiti wa uendeshaji ili kudumisha utulivu ndani ya mfumo. Zaidi ya hayo, kuenea kwa zana za kidijitali na kutegemea watoa huduma wengine huweka wazi biashara za Fintech kwenye vitisho vya usalama vilivyoongezeka. Ustahimilivu pia husaidia kupunguza hatari za hitilafu zinazosababishwa na mambo mbalimbali kama vile vitisho vya mtandao, magonjwa ya milipuko, au matukio ya kisiasa ya kijiografia, kulinda shughuli za msingi za biashara na mali muhimu.
Kwa mifumo ya uthabiti, tunaelewa seti ya mbinu na mikakati bora iliyoundwa ili kuhakikisha kwamba programu inaweza kustahimili kukatizwa na kudumisha utendakazi wake. Mifumo hii hufanya kama nyavu za usalama, zinazotoa mbinu za kushughulikia hitilafu, kudhibiti upakiaji, na kupona kutokana na hitilafu, na hivyo kuhakikisha kwamba programu zinaendelea kuwa thabiti na kutegemewa chini ya hali mbaya.
Mikakati ya kawaida ya ustahimilivu ni pamoja na bulkhead, akiba, kurudi nyuma, jaribu tena, na kivunja mzunguko. Katika makala hii, nitawajadili kwa undani zaidi, na mifano ya matatizo ambayo wanaweza kusaidia kutatua.
Wacha tuangalie mpangilio hapo juu. Tuna programu ya kawaida sana iliyo na viunga kadhaa nyuma yetu ili kupata data kutoka. Kuna viteja kadhaa vya HTTP vilivyounganishwa kwenye sehemu hizi za nyuma. Inatokea kwamba wote wanashiriki bwawa la uunganisho sawa! Na pia rasilimali zingine kama CPU na RAM.
Nini kitatokea, Iwapo mmoja wa wanaorudisha nyuma atapata aina fulani ya matatizo yanayosababisha ucheleweshaji wa ombi la juu? Kutokana na muda wa juu wa kujibu, kidimbwi chote cha muunganisho kitakaliwa kikamilifu na maombi yanayosubiri majibu kutoka kwa backend1. Kwa hivyo, maombi yanayokusudiwa kwa ajili ya mazingira bora ya nyuma2 na ya nyuma3 hayataweza kuendelea kwa sababu bwawa limechoka. Hii inamaanisha kuwa kutofaulu katika mojawapo ya viunga vyetu kunaweza kusababisha kutofaulu katika programu nzima. Kwa hakika, tunataka tu utendakazi unaohusishwa na hali ya nyuma inayoshindikana kuathiriwa na uharibifu, huku programu zingine zikiendelea kufanya kazi kama kawaida.
Muundo wa Bulkhead ni nini?
Neno, muundo wa Bulkhead, linatokana na ujenzi wa meli, inahusisha kuunda sehemu kadhaa za pekee ndani ya meli. Ikiwa uvujaji hutokea katika sehemu moja, hujaa maji, lakini sehemu nyingine haziathiri. Kutengwa huku kunazuia chombo kizima kuzama kwa sababu ya uvunjaji mmoja.
Mchoro wa Bulkhead unaweza kutumika kutenga aina mbalimbali za rasilimali ndani ya programu, kuzuia kushindwa katika sehemu moja kuathiri mfumo mzima. Hivi ndivyo tunavyoweza kuitumia kwa shida yetu:
Hebu tuseme mifumo yetu ya nyuma ina uwezekano mdogo wa kukumbana na hitilafu kibinafsi. Hata hivyo, operesheni inapohusisha kuhoji mambo haya yote ya nyuma kwa sambamba, kila moja inaweza kurudisha hitilafu kwa kujitegemea. Kwa sababu hitilafu hizi hutokea kwa kujitegemea, uwezekano wa jumla wa hitilafu katika programu yetu ni kubwa kuliko uwezekano wa hitilafu wa upande wowote wa nyuma. Uwezekano wa limbikizi wa hitilafu unaweza kuhesabiwa kwa kutumia fomula P_total=1−(1−p)^n, ambapo n ni idadi ya mifumo ya nyuma.
Kwa mfano, ikiwa tuna nakala kumi za nyuma, kila moja ikiwa na uwezekano wa hitilafu wa p=0.001 (sambamba na SLA ya 99.9%), uwezekano wa hitilafu unaotokana ni:
P_jumla=1−(1−0.001)^10=0.009955
Hii inamaanisha kuwa SLA yetu iliyojumuishwa inashuka hadi takriban 99%, ikionyesha jinsi uaminifu wa jumla unavyopungua wakati wa kuuliza maswali mengi ya nyuma kwa sambamba. Ili kupunguza suala hili, tunaweza kutekeleza kashe ya kumbukumbu.
Akiba ya kumbukumbu hutumika kama akiba ya data ya kasi ya juu, kuhifadhi data inayofikiwa mara kwa mara na kuondoa hitaji la kuileta kutoka kwa vyanzo vinavyoweza kuwa polepole kila wakati. Kwa kuwa akiba zilizohifadhiwa kwenye kumbukumbu zina uwezekano wa 0% wa hitilafu ikilinganishwa na kuleta data kwenye mtandao, huongeza kwa kiasi kikubwa uaminifu wa programu yetu. Kwa kuongezea, kache hupunguza trafiki ya mtandao, na hivyo kupunguza uwezekano wa makosa. Kwa hivyo, kwa kutumia akiba ya kumbukumbu, tunaweza kufikia kiwango cha chini zaidi cha makosa katika programu yetu ikilinganishwa na mifumo yetu ya nyuma. Zaidi ya hayo, akiba za kumbukumbu hutoa urejeshaji wa data haraka kuliko uletaji unaotegemea mtandao, na hivyo kupunguza muda wa maombi—faida kubwa.
Kwa data iliyobinafsishwa, kama vile wasifu au mapendekezo ya mtumiaji, kutumia akiba za kumbukumbu kunaweza pia kuwa na ufanisi mkubwa. Lakini tunahitaji kuhakikisha maombi yote kutoka kwa mtumiaji yanakwenda kwa mfano sawa wa programu ili kutumia data iliyohifadhiwa kwao, ambayo inahitaji vipindi vya kunata. Utekelezaji wa vipindi vinavyonata unaweza kuwa changamoto, lakini kwa hali hii, hatuhitaji mbinu changamano. Usawazishaji mdogo wa trafiki unakubalika, kwa hivyo kanuni thabiti ya kusawazisha mzigo kama vile hashing thabiti itatosha.
Zaidi ya hayo, katika tukio la kushindwa kwa nodi, hashing thabiti huhakikisha kwamba watumiaji wanaohusishwa na nodi iliyoshindwa tu hupata kusawazisha, na kupunguza usumbufu kwa mfumo. Mbinu hii hurahisisha udhibiti wa akiba zilizobinafsishwa na huongeza uthabiti na utendaji wa jumla wa programu yetu.
Ikiwa data tunayokusudia kuweka akiba ni muhimu na inatumiwa katika kila ombi linaloshughulikia mfumo wetu, kama vile sera za ufikiaji, mipango ya usajili au huluki nyingine muhimu katika kikoa chetu—chanzo cha data hii kinaweza kusababisha tatizo kubwa katika mfumo wetu. Ili kukabiliana na changamoto hii, mbinu moja ni kuiga data hii moja kwa moja kwenye kumbukumbu ya programu yetu.
Katika hali hii, ikiwa kiasi cha data katika chanzo kinaweza kudhibitiwa, tunaweza kuanzisha mchakato kwa kupakua muhtasari wa data hii mwanzoni mwa programu yetu. Baadaye, tunaweza kupokea matukio ya masasisho ili kuhakikisha data iliyohifadhiwa inasalia kulinganishwa na chanzo. Kwa kutumia njia hii, tunaimarisha uaminifu wa kufikia data hii muhimu, kwani kila urejeshaji hutokea moja kwa moja kutoka kwa kumbukumbu na uwezekano wa hitilafu wa 0%. Zaidi ya hayo, kurejesha data kutoka kwa kumbukumbu ni haraka sana, na hivyo kuboresha utendaji wa programu yetu. Mkakati huu kwa ufanisi hupunguza hatari inayohusishwa na kutegemea chanzo cha data cha nje, kuhakikisha ufikiaji thabiti na wa kuaminika kwa taarifa muhimu kwa ajili ya uendeshaji wa programu yetu.
Hata hivyo, hitaji la kupakua data juu ya uanzishaji wa programu, na hivyo kuchelewesha mchakato wa kuanzisha, inakiuka mojawapo ya kanuni za 'programu ya vipengele 12' inayotetea uanzishaji wa programu haraka. Lakini, hatutaki kupoteza faida za kutumia kache. Ili kukabiliana na tatizo hili, hebu tuchunguze masuluhisho yanayoweza kutokea.
Kuanzisha haraka ni muhimu, haswa kwa majukwaa kama Kubernetes, ambayo yanategemea uhamishaji wa haraka wa programu hadi nodi tofauti za kimwili. Kwa bahati nzuri, Kubernetes inaweza kudhibiti programu zinazoanza polepole kwa kutumia vipengele kama vile uchunguzi wa kuanzisha.
Changamoto nyingine ambayo tunaweza kukumbana nayo ni kusasisha usanidi wakati programu inaendeshwa. Mara nyingi, kurekebisha saa za akiba au muda wa ombi kuisha ni muhimu ili kutatua masuala ya uzalishaji. Hata kama tunaweza kupeleka faili zilizosasishwa za usanidi kwa programu yetu kwa haraka, kutumia mabadiliko haya kwa kawaida kunahitaji kuwashwa upya. Kwa muda ulioongezwa wa uanzishaji wa kila programu, uanzishaji upya wa programu unaweza kuchelewesha sana kupeleka marekebisho kwa watumiaji wetu.
Ili kukabiliana na hili, suluhisho moja ni kuhifadhi usanidi katika utofauti unaofanana na kuwa na uzi wa usuli ukisasisha mara kwa mara. Hata hivyo, vigezo fulani, kama vile muda wa ombi la HTTP, vinaweza kuhitaji kuanzishwa upya kwa HTTP au wateja wa hifadhidata wakati usanidi unaolingana unabadilika, na hivyo kusababisha changamoto inayoweza kutokea. Walakini, wateja wengine, kama kiendeshi cha Cassandra ya Java, wanaunga mkono upakiaji upya kiotomatiki wa usanidi, kurahisisha mchakato huu.
Utekelezaji wa usanidi unaoweza kupakiwa upya unaweza kupunguza athari mbaya ya muda mrefu wa kuanzisha programu na kutoa manufaa ya ziada, kama vile kuwezesha utekelezaji wa alama za vipengele. Mbinu hii hutuwezesha kudumisha kutegemewa na uitikiaji wa programu huku tukisimamia kwa ustadi masasisho ya usanidi.
Sasa hebu tuangalie tatizo lingine: katika mfumo wetu, wakati ombi la mtumiaji linapokewa na kushughulikiwa kwa kutuma swali kwa backend au hifadhidata, mara kwa mara, jibu la hitilafu hupokelewa badala ya data inayotarajiwa. Baadaye, mfumo wetu hujibu mtumiaji kwa 'kosa'.
Hata hivyo, katika hali nyingi, inaweza kuwa vyema zaidi kuonyesha data iliyopitwa na wakati pamoja na ujumbe unaoonyesha kuwa kuna ucheleweshaji wa kuonyesha upya data, badala ya kumwacha mtumiaji ujumbe mkubwa wa hitilafu.
Ili kushughulikia suala hili na kuboresha tabia ya mfumo wetu, tunaweza kutekeleza muundo wa Fallback. Dhana ya muundo huu inahusisha kuwa na chanzo cha pili cha data, ambacho kinaweza kuwa na data ya ubora wa chini au safi ikilinganishwa na chanzo msingi. Ikiwa chanzo msingi cha data hakipatikani au kinarejesha hitilafu, mfumo unaweza kurudi kwenye kurejesha data kutoka kwa chanzo hiki cha pili, na kuhakikisha kuwa aina fulani ya taarifa inawasilishwa kwa mtumiaji badala ya kuonyesha ujumbe wa hitilafu.
Ukitazama picha iliyo hapo juu, utaona mfanano kati ya suala tunalokabiliana nalo sasa na lile tulilokumbana nalo na mfano wa akiba.
Ili kulitatua, tunaweza kuzingatia kutekeleza muundo unaojulikana kama jaribu tena. Badala ya kutegemea akiba, mfumo unaweza kutengenezwa kutuma ombi kiotomatiki ikiwa kuna hitilafu. Mchoro huu wa kujaribu tena unatoa mbadala rahisi na unaweza kupunguza kwa ufanisi uwezekano wa hitilafu katika programu yetu. Tofauti na uakibishaji, ambao mara nyingi huhitaji mbinu changamano za kubatilisha akiba ili kushughulikia mabadiliko ya data, kujaribu tena maombi yaliyoshindikana ni rahisi kutekeleza. Kwa vile ubatilishaji wa akiba unachukuliwa sana kuwa mojawapo ya kazi zenye changamoto nyingi katika uhandisi wa programu, kutumia mkakati wa kujaribu tena kunaweza kurahisisha ushughulikiaji wa makosa na kuboresha ustahimilivu wa mfumo.
Hata hivyo, kupitisha mkakati wa kujaribu tena bila kuzingatia madhara yanayoweza kutokea kunaweza kusababisha matatizo zaidi.
Hebu fikiria mmoja wa watetezi wetu akipata kutofaulu. Katika hali kama hii, kuanzisha majaribio ya kurudi nyuma kwa kushindwa kunaweza kusababisha ongezeko kubwa la kiasi cha trafiki. Ongezeko hili la ghafla la msongamano linaweza kulemea hali ya nyuma, na kuzidisha kushindwa na kusababisha athari ya mteremko kwenye mfumo mzima.
Ili kukabiliana na changamoto hii, ni muhimu kukamilisha muundo wa kujaribu tena na mchoro wa kikatiza mzunguko. Kikatiza mzunguko hutumika kama njia ya ulinzi inayofuatilia kiwango cha makosa ya huduma za mkondo wa chini. Kiwango cha hitilafu kinapozidi kiwango kilichoainishwa awali, kivunja mzunguko hukatiza maombi kwa huduma iliyoathiriwa kwa muda maalum. Katika kipindi hiki, mfumo unakataa kutuma maombi ya ziada ili kuruhusu muda wa huduma kushindwa kurejesha. Baada ya muda uliowekwa, kivunja mzunguko kwa uangalifu huruhusu idadi ndogo ya maombi kupita, kuthibitisha ikiwa huduma imetulia. Ikiwa huduma imepona, trafiki ya kawaida hurejeshwa hatua kwa hatua; vinginevyo, mzunguko unabaki wazi, kuendelea kuzuia maombi mpaka huduma itaanza tena operesheni ya kawaida. Kwa kuunganisha muundo wa kikatiza mzunguko pamoja na mantiki ya kujaribu tena, tunaweza kudhibiti kwa njia ifaayo hali za hitilafu na kuzuia upakiaji wa mfumo wakati wa hitilafu za nyuma.
Kwa kumalizia, kwa kutekeleza mifumo hii ya ustahimilivu, tunaweza kuimarisha programu zetu dhidi ya dharura, kudumisha upatikanaji wa juu, na kutoa hali ya utumiaji iliyofumwa kwa watumiaji. Zaidi ya hayo, ningependa kusisitiza kwamba telemetry bado ni zana nyingine ambayo haipaswi kupuuzwa wakati wa kutoa ustahimilivu wa mradi. Kumbukumbu nzuri na vipimo vinaweza kuimarisha ubora wa huduma kwa kiasi kikubwa na kutoa maarifa muhimu kuhusu utendakazi wao, hivyo kusaidia kufanya maamuzi sahihi ili kuziboresha zaidi.