Tafuta kwa kasi ya 1 TB/s

TL;DR: Miaka minne iliyopita niliacha Google nikiwa na wazo la zana mpya ya ufuatiliaji wa seva. Wazo lilikuwa kuchanganya kazi zilizotengwa kwa kawaida katika huduma moja Kusanya na uchambuzi wa kumbukumbu, ukusanyaji wa vipimo, arifa na dashibodi. Moja ya kanuni ni kwamba huduma lazima iwe kweli haraka, inayowapa washiriki uzoefu rahisi, mwingiliano na wa kufurahisha. Hii inahitaji kuchakata seti za data za gigabaiti nyingi katika sehemu za sekunde huku ikisalia ndani ya bajeti. Zana zilizopo za usimamizi wa kumbukumbu mara nyingi huwa za polepole na zenye kusuasua, kwa hivyo tulikabiliwa na changamoto nzuri: kubuni zana kwa werevu ili kuwapa watumiaji hali mpya ya matumizi.

Nakala hii inaelezea jinsi sisi katika Scalyr tulisuluhisha shida hii kwa kutumia mbinu za shule za zamani, mbinu ya nguvu ya kikatili, kuondoa tabaka zisizo za lazima na kuzuia miundo changamano ya data. Unaweza kutumia masomo haya kwa matatizo yako mwenyewe ya uhandisi.

Nguvu ya Shule ya Zamani

Uchanganuzi wa kumbukumbu kwa kawaida huanza na utafutaji: pata ujumbe wote unaolingana na mchoro fulani. Katika Scalyr, hizi ni makumi au mamia ya gigabytes ya kumbukumbu kutoka kwa seva nyingi. Mbinu za kisasa, kama sheria, zinahusisha ujenzi wa muundo fulani changamano wa data ulioboreshwa kwa utafutaji. Hakika nimeona hii kwenye Google, ambapo wao ni wazuri sana katika aina hii ya kitu. Lakini tulikaa kwa njia isiyofaa zaidi: skanning laini ya kumbukumbu. Na ilifanya kazi - tunatoa kiolesura cha kutafutwa ambacho ni maagizo ya ukubwa kwa kasi zaidi kuliko washindani wetu (angalia uhuishaji mwishoni).

Ufahamu muhimu ulikuwa kwamba wasindikaji wa kisasa wana haraka sana katika shughuli rahisi na za moja kwa moja. Hii ni rahisi kukosa katika mifumo changamano, ya tabaka nyingi ambayo inategemea kasi ya I/O na uendeshaji wa mtandao, na mifumo hiyo ni ya kawaida sana leo. Kwa hivyo tulitengeneza muundo ambao unapunguza tabaka na uchafu mwingi. Na wasindikaji na seva nyingi sambamba, kasi ya utafutaji hufikia 1 TB kwa sekunde.

Mambo muhimu kutoka kwa makala hii:

  • Utafutaji wa nguvu ni mbinu ifaayo ya kutatua matatizo makubwa ya ulimwengu halisi.
  • Nguvu isiyo na nguvu ni mbinu ya kubuni, sio suluhisho la bure la kazi. Kama mbinu yoyote, inafaa zaidi kwa shida kadhaa kuliko zingine, na inaweza kutekelezwa vibaya au vizuri.
  • Nguvu isiyo na nguvu ni nzuri sana katika kufanikisha imara tija.
  • Utumiaji mzuri wa nguvu ya kinyama unahitaji uboreshaji wa nambari na kutumia rasilimali za kutosha kwa wakati unaofaa. Inafaa ikiwa seva zako ziko chini ya mzigo mzito ambao sio wa watumiaji na shughuli za watumiaji hubaki kuwa kipaumbele.
  • Utendaji hutegemea muundo wa mfumo mzima, sio tu algorithm ya kitanzi cha ndani.

(Nakala hii inaelezea utafutaji wa data katika kumbukumbu. Mara nyingi, mtumiaji anapofanya utafutaji wa kumbukumbu, seva za Scalyr tayari zimeiweka. Makala inayofuata itajadili utafutaji wa kumbukumbu ambazo hazijahifadhiwa. Kanuni sawa hutumika: msimbo wa ufanisi, nguvu ya brute. na rasilimali kubwa za hesabu).

Mbinu ya nguvu ya brute

Kijadi, seti kubwa ya data hutafutwa kwa kutumia index ya maneno muhimu. Inapotumika kwa kumbukumbu za seva, hii inamaanisha kutafuta kila neno la kipekee kwenye logi. Kwa kila neno, unahitaji kufanya orodha ya majumuisho yote. Hii hurahisisha kupata jumbe zote zilizo na neno hili, kwa mfano 'error', 'firefox' au "transaction_16851951" - angalia tu katika faharasa.

Nilitumia mbinu hii kwa Google na ilifanya kazi vizuri. Lakini katika Scalyr tunatafuta kumbukumbu byte byte.

Kwa nini? Kutoka kwa mtazamo wa kidhahiri wa algorithmic, faharisi za maneno muhimu ni bora zaidi kuliko utafutaji wa nguvu wa kinyama. Hata hivyo, hatuuzi algoriti, tunauza utendaji. Na utendaji sio tu kuhusu algorithms, lakini pia kuhusu uhandisi wa mifumo. Ni lazima tuzingatie kila kitu: kiasi cha data, aina ya utafutaji, maunzi inapatikana na muktadha wa programu. Tuliamua kuwa kwa shida yetu mahususi, kitu kama 'grep' kilifaa zaidi kuliko faharasa.

Fahirisi ni nzuri, lakini zina mapungufu. Neno moja ni rahisi kupata. Lakini kutafuta ujumbe wenye maneno mengi, kama vile 'googlebot' na '404', ni vigumu zaidi. Kutafuta fungu la maneno kama 'ubaguzi ambao haujashughulikiwa' kunahitaji faharasa ngumu zaidi ambayo hurekodi sio tu ujumbe wote wenye neno hilo, lakini pia eneo mahususi la neno.

Ugumu wa kweli unakuja wakati hautafuti maneno. Wacha tuseme unataka kuona ni trafiki ngapi inatoka kwa roboti. Wazo la kwanza ni kutafuta magogo kwa neno 'bot'. Hivi ndivyo utapata roboti kadhaa: Googlebot, Bingbot na zingine nyingi. Lakini hapa 'bot' sio neno, lakini sehemu yake. Tukitafuta 'jibu' kwenye faharasa, hatutapata machapisho yoyote yenye neno 'Googlebot'. Ukiangalia kila neno kwenye faharasa na kisha uchanganua faharasa ya maneno muhimu yaliyopatikana, utafutaji utapungua sana. Kwa hiyo, baadhi ya programu za logi haziruhusu utafutaji wa neno la sehemu au (bora zaidi) kuruhusu syntax maalum na utendaji wa chini. Tunataka kuepuka hili.

Tatizo jingine ni uakifishaji. Je, unataka kupata maombi yote kutoka 50.168.29.7? Vipi kuhusu utatuzi wa kumbukumbu zilizo na [error]? Maandishi kwa kawaida huruka uakifishaji.

Hatimaye, wahandisi wanapenda zana zenye nguvu, na wakati mwingine tatizo linaweza kutatuliwa tu kwa kujieleza mara kwa mara. Faharasa ya neno kuu haifai sana kwa hii.

Kwa kuongeza, fahirisi changamano. Kila ujumbe unahitaji kuongezwa kwa orodha kadhaa za maneno muhimu. Orodha hizi zinapaswa kuwekwa katika muundo unaoweza kutafutwa kwa urahisi kila wakati. Hoja zilizo na vifungu vya maneno, vijisehemu vya maneno, au maneno ya kawaida yanahitaji kutafsiriwa katika utendakazi wa orodha nyingi, na matokeo kuchanganuliwa na kuunganishwa ili kutoa seti ya matokeo. Katika muktadha wa huduma ya kiwango kikubwa, ya wapangaji wengi, utata huu huzua masuala ya utendaji ambayo hayaonekani wakati wa kuchanganua algoriti.

Faharisi za maneno muhimu pia huchukua nafasi nyingi, na uhifadhi ni gharama kubwa katika mfumo wa usimamizi wa logi.

Kwa upande mwingine, kila utafutaji unaweza kutumia nguvu nyingi za kompyuta. Watumiaji wetu wanathamini utafutaji wa kasi ya juu wa hoja za kipekee, lakini hoja kama hizo hufanywa mara chache. Kwa maswali ya kawaida ya utafutaji, kwa mfano, kwa dashibodi, tunatumia mbinu maalum (tutazielezea katika makala inayofuata). Maombi mengine ni nadra vya kutosha kwamba ni nadra kuchakata zaidi ya moja kwa wakati mmoja. Lakini hii haimaanishi kuwa seva zetu hazijashughulika: zinashughulika na kazi ya kupokea, kuchambua na kukandamiza ujumbe mpya, kutathmini arifa, kukandamiza data ya zamani, na kadhalika. Kwa hivyo, tunayo usambazaji muhimu wa wasindikaji ambao unaweza kutumika kutekeleza maswali.

Nguvu ya kikatili inafanya kazi ikiwa una shida ya kikatili (na nguvu nyingi)

Nguvu ya brute hufanya kazi vizuri zaidi kwenye matatizo rahisi na vitanzi vidogo vya ndani. Mara nyingi unaweza kuboresha kitanzi cha ndani ili kukimbia kwa kasi ya juu sana. Ikiwa nambari ni ngumu, ni ngumu zaidi kuiboresha.

Msimbo wetu wa utafutaji awali ulikuwa na kitanzi kikubwa cha ndani. Tunahifadhi ujumbe kwenye kurasa za 4K; kila ukurasa una baadhi ya ujumbe (katika UTF-8) na metadata kwa kila ujumbe. Metadata ni muundo unaosimba urefu wa thamani, kitambulisho cha ujumbe wa ndani na sehemu zingine. Mzunguko wa utafutaji ulionekana kama hii:

Tafuta kwa kasi ya 1 TB/s

Hili ni toleo lililorahisishwa la msimbo halisi. Lakini hata hapa, uwekaji wa vitu vingi, nakala za data, na simu za kazi zinaonekana. JVM ni nzuri sana katika kuboresha simu za utendakazi na kugawa vitu vya muda mfupi, kwa hivyo nambari hii ilifanya kazi vizuri zaidi kuliko tulivyostahili. Wakati wa majaribio, wateja walitumia kwa mafanikio kabisa. Lakini hatimaye tuliipeleka kwenye ngazi inayofuata.

(Unaweza kuuliza kwa nini tunahifadhi ujumbe katika umbizo hili na kurasa za 4K, maandishi na metadata, badala ya kufanya kazi na kumbukumbu moja kwa moja. Kuna sababu nyingi, ambazo zinatokana na ukweli kwamba ndani ya injini ya Scalyr ni kama hifadhidata iliyosambazwa kuliko a. mfumo wa faili. Utafutaji wa maandishi mara nyingi huunganishwa na vichujio vya mtindo wa DBMS kwenye pambizo baada ya kuchanganua kumbukumbu. Tunaweza kutafuta maelfu ya kumbukumbu kwa wakati mmoja, na faili rahisi za maandishi hazifai kwa usimamizi wetu wa shughuli, kuigwa, na kusambazwa).

Hapo awali, ilionekana kuwa nambari kama hiyo haikufaa sana uboreshaji wa nguvu ya kikatili. "Kazi ya kweli" ndani String.indexOf() hata haikutawala wasifu wa CPU. Hiyo ni, kuboresha njia hii peke yake hakutaleta athari kubwa.

Inatokea kwamba tunahifadhi metadata mwanzoni mwa kila ukurasa, na maandishi ya ujumbe wote katika UTF-8 yamejaa mwisho mwingine. Kwa kutumia fursa hii, tuliandika upya kitanzi ili kutafuta ukurasa mzima mara moja:

Tafuta kwa kasi ya 1 TB/s

Toleo hili hufanya kazi moja kwa moja kwenye mtazamo raw byte[] na hutafuta ujumbe wote mara moja katika ukurasa mzima wa 4K.

Hii ni rahisi zaidi kuboresha kwa njia ya nguvu ya brute. Kitanzi cha utafutaji wa ndani kinaitwa kwa wakati mmoja kwa ukurasa mzima wa 4K, badala ya kila chapisho. Hakuna kunakili data, hakuna mgao wa vitu. Na shughuli ngumu zaidi za metadata huitwa tu wakati matokeo ni chanya, na sio kwa kila ujumbe. Kwa njia hii tumeondoa tani ya juu, na mzigo uliobaki umewekwa kwenye kitanzi kidogo cha utaftaji wa ndani, ambacho kinafaa kwa uboreshaji zaidi.

Algorithm yetu halisi ya utafutaji inategemea wazo kubwa la Leonid Volnitsky. Ni sawa na algorithm ya Boyer-Moore, kuruka takriban urefu wa kamba ya utafutaji katika kila hatua. Tofauti kuu ni kwamba inakagua ka mbili kwa wakati mmoja ili kupunguza mechi za uwongo.

Utekelezaji wetu unahitaji kuunda jedwali la utafutaji la 64K kwa kila utafutaji, lakini hilo si lolote ikilinganishwa na gigabaiti za data tunazotafuta. Kitanzi cha ndani kinashughulikia gigabytes kadhaa kwa sekunde kwenye msingi mmoja. Kwa mazoezi, utendaji thabiti ni karibu GB 1,25 kwa sekunde kwa kila msingi, na kuna nafasi ya kuboresha. Inawezekana kuondoa sehemu ya juu nje ya kitanzi cha ndani, na tunapanga kujaribu kitanzi cha ndani katika C badala ya Java.

Tunatumia nguvu

Tumejadili kwamba utafutaji wa kumbukumbu unaweza kutekelezwa "takriban", lakini tuna "nguvu" kiasi gani? Mengi kabisa.

1 msingi: Inapotumiwa kwa usahihi, msingi mmoja wa processor ya kisasa ni nguvu kabisa kwa haki yake mwenyewe.

8 kori: Kwa sasa tunaendesha seva za Amazon hi1.4xlarge na i2.4xlarge SSD, kila moja ikiwa na cores 8 (nyuzi 16). Kama ilivyoelezwa hapo juu, cores hizi kawaida huwa na shughuli nyingi za nyuma. Mtumiaji anapotafuta, shughuli za usuli husitishwa, na hivyo kutoa core zote 8 kwa utafutaji. Utafutaji kawaida hukamilika kwa sekunde iliyogawanyika, baada ya hapo kazi ya usuli huanza tena (mpango wa kusukuma huhakikisha kuwa maswali mengi ya utafutaji hayaingiliani na kazi muhimu ya usuli).

16 kori: kwa kutegemewa, tunapanga seva katika vikundi vya bwana/mtumwa. Kila bwana ana SSD moja na seva moja ya EBS chini ya amri yake. Ikiwa seva kuu itaanguka, seva ya SSD inachukua nafasi yake mara moja. Karibu wakati wote, bwana na mtumwa hufanya kazi vizuri, ili kila kizuizi cha data kinaweza kutafutwa kwenye seva mbili tofauti (seva ya watumwa ya EBS ina processor dhaifu, kwa hivyo hatuizingatii). Tunagawanya kazi kati yao, ili tuwe na jumla ya cores 16 zilizopo.

Cores nyingi: Katika siku za usoni, tutasambaza data kwenye seva kwa njia ambayo zote zitashiriki katika kuchakata kila ombi lisilo la maana. Kila msingi utafanya kazi. [Kumbuka: tulitekeleza mpango na kuongeza kasi ya utafutaji hadi 1 TB/s, angalia maelezo mwishoni mwa makala].

Urahisi huhakikisha kuegemea

Faida nyingine ya njia ya nguvu ya brute ni utendaji wake thabiti. Kwa kawaida, utafutaji sio nyeti sana kwa maelezo ya tatizo na kuweka data (nadhani ndiyo sababu inaitwa "coarse").

Faharisi ya neno kuu wakati mwingine hutoa matokeo ya haraka sana, na nyakati zingine haifanyi. Wacha tuseme una kumbukumbu za GB 50 ambapo neno 'customer_5987235982' linaonekana mara tatu haswa. Utafutaji wa neno hili huhesabu maeneo matatu moja kwa moja kutoka kwenye faharasa na utakamilika papo hapo. Lakini utafutaji changamano wa kadi-mwitu unaweza kuchanganua maelfu ya maneno muhimu na kuchukua muda mrefu.

Kwa upande mwingine, utafutaji wa nguvu wa kinyama hufanya kwa kasi zaidi au chini ya sawa kwa hoja yoyote. Kutafuta maneno marefu ni bora, lakini hata kutafuta mhusika mmoja ni haraka sana.

Unyenyekevu wa njia ya nguvu ya brute ina maana kwamba utendaji wake ni karibu na upeo wake wa kinadharia. Kuna chaguo chache za upakiaji usiotarajiwa wa diski, ugomvi wa kufuli, kutafuta pointer, na maelfu ya sababu zingine za kutofaulu. Niliangalia tu maombi yaliyotolewa na watumiaji wa Scalyr wiki iliyopita kwenye seva yetu yenye shughuli nyingi zaidi. Kulikuwa na maombi 14. Hasa wanane kati yao walichukua zaidi ya sekunde moja; 000% imekamilika ndani ya milisekunde 99 (ikiwa hujatumia zana za uchanganuzi wa kumbukumbu, niamini: ni haraka).

Utendaji thabiti na wa kuaminika ni muhimu kwa urahisi wa matumizi ya huduma. Iwapo itachelewa mara kwa mara, watumiaji wataiona kuwa haiwezi kutegemewa na watasita kuitumia.

Utafutaji wa kumbukumbu katika vitendo

Huu hapa ni uhuishaji mfupi unaoonyesha utafutaji wa Scalyr ukifanya kazi. Tuna akaunti ya onyesho ambapo tunaingiza kila tukio katika hazina ya umma ya Github. Katika onyesho hili, ninachunguza data ya wiki moja: takriban MB 600 za kumbukumbu mbichi.

Video hiyo ilirekodiwa moja kwa moja, bila maandalizi maalum, kwenye eneo-kazi langu (karibu kilomita 5000 kutoka kwa seva). Utendaji utakaouona umechangiwa kwa kiasi kikubwa uboreshaji wa mteja wa wavuti, pamoja na backend ya haraka na ya kuaminika. Wakati wowote kunapositishwa bila kiashirio cha 'kupakia', mimi husitisha ili uweze kusoma ninachotaka kubonyeza.

Tafuta kwa kasi ya 1 TB/s

Kwa kumalizia

Wakati wa kusindika kiasi kikubwa cha data, ni muhimu kuchagua algorithm nzuri, lakini "nzuri" haimaanishi "dhana." Fikiria jinsi msimbo wako utafanya kazi kwa vitendo. Uchanganuzi wa kinadharia wa algoriti huacha baadhi ya vipengele ambavyo vinaweza kuwa muhimu sana katika ulimwengu halisi. Algorithms rahisi ni rahisi kuboresha na thabiti zaidi katika hali za ukingo.

Pia fikiria juu ya muktadha ambao msimbo utatekelezwa. Kwa upande wetu, tunahitaji seva zenye nguvu za kutosha ili kudhibiti kazi za usuli. Watumiaji huanzisha utafutaji mara chache, ili tuweze kuazima kundi zima la seva kwa muda mfupi unaohitajika ili kukamilisha kila utafutaji.

Kwa kutumia mbinu ya kutumia nguvu ya kinyama, tulitekeleza utafutaji wa haraka, unaotegemewa na unaonyumbulika kwenye seti ya kumbukumbu. Tunatumahi kuwa mawazo haya ni muhimu kwa miradi yako.

Hariri: Kichwa na maandishi yamebadilika kutoka "Tafuta kwa GB 20 kwa sekunde" hadi "Tafuta kwa TB 1 kwa sekunde" ili kuonyesha ongezeko la utendaji katika miaka michache iliyopita. Ongezeko hili la kasi linatokana na mabadiliko ya aina na idadi ya seva za EC2 tunazoweka leo ili kuhudumia wateja wetu walioongezeka. Kuna mabadiliko yanakuja hivi karibuni ambayo yatatoa msukumo mwingine mkubwa katika ufanisi wa kazi, na hatuwezi kusubiri kuyashiriki.

Chanzo: mapenzi.com

Kuongeza maoni