
Salaam wote. Katika makala hii nitakuambia kwa nini sisi katika Avito tulichagua Kafka miezi tisa iliyopita na ni nini. Nitashiriki moja ya kesi za utumiaji - wakala wa ujumbe. Na mwishowe, wacha tuzungumze juu ya faida gani tulizopata kwa kutumia Kafka kama mbinu ya Huduma.
tatizo

Kwanza, muktadha mdogo. Wakati fulani uliopita tulianza kuondokana na usanifu wa monolithic, na sasa Avito tayari ina huduma mia kadhaa tofauti. Wana hazina zao wenyewe, rundo lao la teknolojia na wanawajibika kwa sehemu yao ya mantiki ya biashara.
Moja ya matatizo na idadi kubwa ya huduma ni mawasiliano. Huduma A mara nyingi inataka kujua taarifa ambayo Huduma B inayo. Katika hali hii, Huduma A hufikia Huduma B kupitia API iliyosawazishwa. Huduma B inataka kujua kinachoendelea na huduma D na D, na wao, kwa upande wake, wanapendezwa na huduma A na B. Wakati kuna huduma nyingi za "curious", uhusiano kati yao hugeuka kwenye tangle iliyopigwa.
Wakati huo huo, huduma A inaweza kukosa kupatikana wakati wowote. Na huduma B na huduma zingine zote zilizounganishwa nayo zinapaswa kufanya nini katika kesi hii? Na ikiwa mlolongo wa simu zinazofuatana zinazofuatana zinahitajika ili kukamilisha operesheni ya biashara, uwezekano wa kushindwa kwa operesheni nzima inakuwa kubwa zaidi (na kwa muda mrefu mnyororo, ni wa juu zaidi).
Uchaguzi wa teknolojia

Sawa, shida ziko wazi. Wanaweza kuondolewa kwa kuunda mfumo wa kati wa ujumbe kati ya huduma. Sasa kila moja ya huduma inahitaji tu kujua kuhusu mfumo huu wa ujumbe. Kwa kuongeza, mfumo yenyewe lazima uwe na uvumilivu wa makosa na upanuzi wa usawa, na pia, katika tukio la ajali, kukusanya buffer ya kufikia kwa usindikaji unaofuata.
Hebu sasa tuchague teknolojia ambayo uwasilishaji wa ujumbe utatekelezwa. Ili kufanya hivyo, hebu kwanza tuelewe kile tunachotarajia kutoka kwake:
- ujumbe kati ya huduma haipaswi kupotea;
- ujumbe unaweza kurudiwa;
- ujumbe unaweza kuhifadhiwa na kusomwa kwa kina cha siku kadhaa (bafa inayoendelea);
- huduma zinaweza kujiandikisha kwa data wanayopenda;
- huduma nyingi zinaweza kusoma data sawa;
- ujumbe unaweza kuwa na malipo ya kina, mengi (uhamisho wa hali iliyobebwa na tukio);
- Wakati mwingine unahitaji kuhakikisha mpangilio wa ujumbe.
Pia ilikuwa muhimu sana kwetu kuchagua mfumo wa hatari zaidi na unaotegemewa na upitishaji wa hali ya juu (angalau ujumbe 100k wa kilobaiti kadhaa kwa sekunde).
Katika hatua hii, tuliagana na RabbitMQ (ngumu kuweka uthabiti kwenye rps za juu), PGQ kutoka SkyTools (sio haraka vya kutosha na haina kiwango vizuri) na NSQ (isiyoendelea). Tunatumia teknolojia hizi zote katika kampuni yetu, lakini hazikufaa kwa tatizo kutatuliwa.
Kisha, tulianza kuangalia teknolojia ambazo zilikuwa mpya kwetu - Apache Kafka, Apache Pulsar na Utiririshaji wa NATS.
Pulsar alikuwa wa kwanza kutupwa. Tuliamua kuwa Kafka na Pulsar ni suluhisho zinazofanana. Na licha ya ukweli kwamba Pulsar imejaribiwa na kampuni kubwa, ni mpya zaidi na inatoa latency ya chini (kwa nadharia), tuliamua kuacha Kafka kati ya hizi mbili kama kiwango cha ukweli cha kazi kama hizo. Pengine tutarudi kwa Apache Pulsar siku zijazo.
Na sasa wamebaki wagombea wawili: Utiririshaji wa NATS na Apache Kafka. Tulisoma suluhisho zote mbili kwa undani, na zote mbili zilifaa kwa kazi hiyo. Lakini mwishowe, tuliogopa vijana wa jamaa wa Utiririshaji wa NATS (na ukweli kwamba mmoja wa watengenezaji wakuu, Tyler Treat, aliamua kuacha mradi huo na kuanza yake mwenyewe - Liftbridge). Wakati huo huo, hali ya Kuunganisha ya Utiririshaji wa NATS haikutoa uwezekano wa kuongeza nguvu kwa usawa (labda hii sio shida tena baada ya kuongezwa kwa hali ya kugawa mnamo 2017).
Hata hivyo, Utiririshaji wa NATS ni teknolojia nzuri iliyoandikwa katika Go na kuungwa mkono na Cloud Native Computing Foundation. Tofauti na Apache Kafka, haiitaji Zookeeper kufanya kazi (labda ), kwani hutumia RAFT ndani. Wakati huo huo, Utiririshaji wa NATS ni rahisi kudhibiti. Hatuondoi kwamba tutarudi kwenye teknolojia hii katika siku zijazo.
Na bado, leo mshindi wetu ni Apache Kafka. Katika vipimo vyetu, imeonekana kuwa haraka sana (zaidi ya ujumbe milioni kwa sekunde kwa kusoma na kuandika na kiasi cha ujumbe wa kilobyte 1), ya kuaminika kabisa, yenye kuenea sana na kuthibitishwa na uzoefu katika uzalishaji wa makampuni makubwa. Kwa kuongezea, Kafka inasaidia angalau kampuni kadhaa kubwa za kibiashara (sisi, kwa mfano, tunatumia toleo la Confluent), na Kafka pia ina mfumo wa ikolojia ulioendelezwa.
Muhtasari wa Kafka
Kabla hatujaanza, ningependa kupendekeza mara moja kitabu bora - "Kafka: Mwongozo wa uhakika" (pia kuna tafsiri ya Kirusi, lakini maneno ni ya kushangaza kidogo). Ina maelezo unayohitaji ili kupata ufahamu wa kimsingi wa Kafka na hata kidogo zaidi. Nyaraka za Apache na blogu ya Confluent pia zimeandikwa vizuri na ni rahisi kusoma.
Basi hebu tuangalie kwa jicho la ndege jinsi Kafka inavyofanya kazi. Topolojia ya msingi ya Kafka inajumuisha mzalishaji, watumiaji, wakala na mlinzi wa wanyama.
Broker

Wakala ana jukumu la kuhifadhi data yako. Data zote zimehifadhiwa katika fomu ya binary, na wakala hajui kidogo kuhusu wao ni nini na muundo wao ni nini.
Kila aina ya tukio la mantiki kawaida iko katika mada yake tofauti. Kwa mfano, tukio la kuunda tangazo linaweza kuangukia kwenye mada.iliyoundwa, na tukio la mabadiliko yake linaweza kuangukia kwenye kipengee.kubadilishwa. Mada zinaweza kuzingatiwa kama waainishaji wa hafla. Katika kiwango cha mada, unaweza kuweka vigezo vya usanidi kama vile:
- kiasi cha data iliyohifadhiwa na/au umri wake (retention.bytes, retention.ms);
- data redundancy factor (sababu ya kurudia);
- ukubwa wa juu wa ujumbe mmoja (max.message.bytes);
- idadi ya chini ya nakala thabiti ambapo data inaweza kuandikwa kwa mada (min.insync.replicas);
- uwezo wa kutekeleza kushindwa kwenye nakala ya nyuma isiyosawazishwa na uwezekano wa upotezaji wa data (unclean.leader.election.enable);
- na mengine mengi ().
Kwa upande wake, kila mada imegawanywa katika sehemu moja au zaidi. Ni katika vyama kwamba matukio hatimaye huanguka. Ikiwa kuna zaidi ya wakala mmoja kwenye nguzo, basi sehemu zitasambazwa sawasawa kwa madalali wote (kadiri inavyowezekana), ambayo itaruhusu mzigo wa kuandika na kusoma katika mada moja kuongezwa kwa madalali kadhaa mara moja.
Kwenye diski, data kwa kila kizigeu huhifadhiwa kwa namna ya faili za sehemu, kwa default sawa na gigabyte moja (kudhibitiwa kupitia log.segment.bytes). Kipengele muhimu ni kwamba data inafutwa kutoka kwa sehemu (wakati uhifadhi umeanzishwa) katika sehemu (huwezi kufuta tukio moja kutoka kwa kizigeu, unaweza tu kufuta sehemu nzima, na ile isiyotumika pekee).
Mtunza zookeeper
Zookeeper hufanya kazi kama hifadhi ya metadata na mratibu. Ni yeye anayeweza kusema ikiwa madalali wako hai (unaweza kuangalia hii kupitia macho ya mchungaji wa zookeeper kwa kutumia ganda la zookeeper na amri. ls /brokers/ids), wakala gani ndiye mtawala (get /controller), ikiwa sehemu hizo ziko katika ulandanishi na nakala zao (get /brokers/topics/topic_name/partitions/partition_number/state) Pia, ni mlinzi wa wanyama ambapo mtayarishaji na mtumiaji ataenda kwanza ili kujua ni mada gani na sehemu gani zimehifadhiwa kwenye dalali gani. Katika hali ambapo kipengele cha urudufishaji zaidi ya 1 kimebainishwa kwa mada, mlinzi wa bustani ataonyesha sehemu gani ni viongozi (zitaandikiwa na kusomwa kutoka). Katika tukio la kushindwa kwa wakala, maelezo kuhusu sehemu za viongozi wapya yatarekodiwa katika mlinzi wa wanyama (kutoka toleo la 1.1.0 asynchronously, ).
Katika matoleo ya zamani ya Kafka, mlinzi wa zoo pia alikuwa na jukumu la kuhifadhi vifaa, lakini sasa vimehifadhiwa katika mada maalum. __consumer_offsets kwenye wakala (ingawa bado unaweza kutumia mlinda bustani kwa madhumuni haya).
Njia rahisi zaidi ya kugeuza data yako kuwa malenge ni kupoteza taarifa kutoka kwa mlinzi wa bustani. Katika hali kama hiyo, itakuwa ngumu sana kuelewa ni nini cha kusoma na kutoka wapi.
Mtayarishaji
Mtayarishaji mara nyingi ni huduma ambayo huandika data moja kwa moja kwa Apache Kafka. Mtayarishaji huchagua mada ambayo atahifadhi ujumbe wake wa mada na anaanza kuiandikia habari. Kwa mfano, mtayarishaji anaweza kuwa huduma ya tangazo. Katika hali hii, itatuma matukio kama vile "tangazo limeundwa", "tangazo limesasishwa", "tangazo limefutwa", n.k. kwa mada za mada. Kila tukio ni jozi ya thamani-msingi.
Kwa chaguo-msingi, matukio yote yanasambazwa kati ya sehemu za mada kwa kutumia robini ya pande zote ikiwa ufunguo haujabainishwa (kupoteza kuagiza), na kupitia MurmurHash (ufunguo) ikiwa ufunguo upo (kuagiza ndani ya kizigeu kimoja).
Inafaa kumbuka mara moja kuwa Kafka inahakikisha mpangilio wa matukio ndani ya kundi moja tu. Lakini kwa kweli hii mara nyingi sio shida. Kwa mfano, unaweza kuwa na uhakika wa kuongeza mabadiliko yote kwa tamko sawa katika sehemu moja (hivyo kuhifadhi mpangilio wa mabadiliko haya ndani ya tamko). Unaweza pia kutuma nambari ya mfuatano katika mojawapo ya sehemu za tukio.
Consumer

Mtumiaji ana jukumu la kuleta data kutoka kwa Apache Kafka. Ikiwa tunarudi kwa mfano hapo juu, mtumiaji anaweza kuwa huduma ya wastani. Huduma hii itasajiliwa kwa mada ya huduma ya tangazo, na tangazo jipya linapotokea, italipokea na kulichanganua kwa kuzingatia baadhi ya sera zilizobainishwa.
Apache Kafka anakumbuka ni matukio gani ya hivi majuzi ambayo mtumiaji alipokea (mada ya huduma hutumiwa kwa hili __consumer__offsets), na hivyo kuhakikisha kwamba ikiwa usomaji umefanikiwa, mtumiaji hatapokea ujumbe huo mara mbili. Hata hivyo, ikiwa unatumia enable.auto.commit = chaguo la kweli na ukakabidhi kabisa kazi ya kufuatilia nafasi ya mtumiaji katika mada kwa Kafka, unaweza . Katika msimbo wa uzalishaji, mara nyingi nafasi ya mtumiaji inadhibitiwa kwa mikono (msanidi programu anadhibiti wakati ambapo ahadi ya tukio la kusoma lazima ifanyike).
Katika hali ambapo mtumiaji mmoja haitoshi (kwa mfano, mtiririko wa matukio mapya ni kubwa sana), unaweza kuongeza watumiaji kadhaa zaidi kwa kuwaunganisha pamoja katika kikundi cha watumiaji. Kikundi cha watumiaji kimantiki ni sawa na mtumiaji, lakini na data iliyosambazwa kati ya washiriki wa kikundi. Hii inaruhusu kila mshiriki kuchukua sehemu yake ya ujumbe, na hivyo kuongeza kasi ya kusoma.
Matokeo ya mtihani

Sitaandika maandishi mengi ya maelezo hapa, nitashiriki tu matokeo yaliyopatikana. Majaribio yalifanywa kwenye mashine 3 halisi (CPU 12, RAM ya 384GB, 15k SAS DISK, 10GBit/s Net), madalali na mlinzi wa bustani waliwekwa katika lxc.
Upimaji wa Utendaji
Wakati wa kupima, matokeo yafuatayo yalipatikana.
- Kasi ya kurekodi jumbe 1 KB kwa wakati mmoja na watayarishaji 9 ni matukio 1300000 kwa sekunde.
- Kasi ya kusoma jumbe 1 KB kwa wakati mmoja na watumiaji 9 ni matukio 1500000 kwa sekunde.
Mtihani wa uvumilivu wa makosa
Wakati wa kupima, matokeo yafuatayo yalipatikana ( madalali 3, watunza bustani 3).
- Kusitishwa kwa njia isiyo ya kawaida kwa mmoja wa wakala hakusababishi kikundi kusimama au kutopatikana. Kazi inaendelea kama kawaida, lakini madalali waliobaki wana mzigo mzito.
- Kusitishwa kusiko kwa kawaida kwa madalali wawili katika kesi ya kundi la madalali watatu na min.isr = 2 kunasababisha nguzo hiyo kutopatikana kwa kuandikwa, lakini kupatikana kwa usomaji. Ikiwa min.isr = 1, nguzo inaendelea kupatikana kwa kusoma na kuandika. Hata hivyo, hali hii inapingana na mahitaji ya usalama wa juu wa data.
- Kuzimwa kwa njia isiyo ya kawaida kwa mojawapo ya seva za Zookeeper hakusababishi nguzo hiyo kusimama au kutopatikana. Kazi inaendelea kama kawaida.
- Kuzimika kusiko kwa kawaida kwa seva mbili za Zookeeper husababisha nguzo hiyo kutopatikana hadi angalau seva moja ya Zookeeper irejeshwe. Taarifa hii ni kweli kwa kundi la Zookeeper la seva 3. Kama matokeo, baada ya utafiti, iliamuliwa kuongeza nguzo ya Zookeeper hadi seva 5 ili kuongeza uvumilivu wa makosa.
Kafka kama huduma

Tuna hakika kwamba Kafka ni teknolojia bora ambayo inaruhusu sisi kutatua kazi tuliyopewa (kutekeleza dalali wa ujumbe). Hata hivyo, tuliamua kuzuia huduma kufikia moja kwa moja Kafka na tukaifunga juu kwa huduma ya basi ya data. Kwa nini tulifanya hivi? Kwa kweli, kuna sababu chache kabisa.
Data-bus ilichukua kazi zote zinazohusiana na ushirikiano na Kafka (utekelezaji na usanidi wa watumiaji na wazalishaji, ufuatiliaji, tahadhari, kukata miti, kuongeza ukubwa, nk). Kwa hivyo, kuunganishwa na wakala wa ujumbe ni rahisi iwezekanavyo.
Data-bus ilituruhusu kuchukua mbali na lugha au maktaba mahususi ya kufanya kazi na Kafka.
Data-bus iliruhusu huduma zingine kuondoa safu ya hifadhi. Labda wakati fulani tutabadilisha Kafka kuwa Pulsar, na hakuna mtu atakayegundua chochote (huduma zote zinajua tu kuhusu API ya basi ya data).
Data-bus ilichukua uthibitishaji wa taratibu za tukio.
Uthibitishaji unatekelezwa kwa kutumia basi-data.
Chini ya jalada la basi la data, tunaweza kusasisha matoleo ya Kafka kimya kimya bila kukatika, kudhibiti usanidi wa watayarishaji, watumiaji, madalali n.k.
Basi la data lilituruhusu kuongeza vipengele tulivyohitaji ambavyo haviko katika Kafka (kama vile mada za ukaguzi, ufuatiliaji wa hitilafu katika kundi, kuunda DLQ, n.k.).
Data-bus hukuruhusu kutekeleza faili kuu kwa huduma zote.
Kwa sasa, ili kuanza kutuma matukio kwa wakala wa ujumbe, unahitaji tu kuunganisha maktaba ndogo kwenye msimbo wako wa huduma. Hii ndiyo yote. Una uwezo wa kuandika, kusoma na kupima kwa mstari mmoja wa msimbo. Utekelezaji mzima umefichwa kutoka kwako, na vishikizo vichache tu vya bechi vinatoka nje. Chini ya kifuniko, huduma ya basi ya data huinua idadi inayotakiwa ya matukio ya wazalishaji na watumiaji katika Kubernetes na kuwapa usanidi unaohitajika, lakini yote haya ni wazi kwa huduma yako.
Bila shaka, hakuna risasi ya fedha, na njia hii ina vikwazo vyake.
- Data-bus inahitaji kuungwa mkono ndani ya nyumba, tofauti na maktaba za watu wengine.
- Data-bus huongeza idadi ya mwingiliano kati ya huduma na wakala wa ujumbe, ambayo husababisha utendaji wa chini ikilinganishwa na Kafka tupu.
- Sio kila kitu kinachoweza kufichwa kutoka kwa huduma kwa urahisi; hatutaki kurudia utendakazi wa KSQL au Mipasho ya Kafka kwenye basi ya data, kwa hivyo wakati mwingine lazima turuhusu huduma kwenda moja kwa moja.
Kwa upande wetu, faida zilizidi hasara, na uamuzi wa kufunika broker wa ujumbe na huduma tofauti ulihesabiwa haki. Katika mwaka wa operesheni hatukupata ajali yoyote mbaya au shida.
PS Asante kwa mpenzi wangu, Ekaterina Obalyaeva, kwa picha nzuri za makala hii. Ikiwa uliwapenda, kuna vielelezo zaidi vinakuja.
Chanzo: mapenzi.com
