Sykje op 1 TB/s

TL;DR: Fjouwer jier lyn ferliet ik Google mei in idee foar in nij servermonitoring-ark. It idee wie om meast isolearre funksjes te kombinearjen yn ien tsjinst sammelje en log analyse, metriken sammeljen, warskôgings en dashboards. Ien fan 'e prinsipes is dat de tsjinst wirklik moat wêze fluch, it bieden fan devops mei in maklike, ynteraktive, noflike ûnderfining. Dit fereasket it ferwurkjen fan multi-gigabyte gegevenssets yn fraksjes fan in sekonde wylst jo binnen budzjet bliuwe. Besteande ark foar logbehear binne faak stadich en clunky, dus wy waarden konfrontearre mei in goede útdaging: tûk ûntwerp fan in ark om brûkers in nije ûnderfining te jaan.

Dit artikel beskriuwt hoe't wy by Scalyr dit probleem hawwe oplost troch âlde skoallemetoaden ta te passen, in oanpak fan brute krêft, it eliminearjen fan ûnnedige lagen en it foarkommen fan komplekse gegevensstruktueren. Jo kinne dizze lessen tapasse op jo eigen technyske problemen.

Old School Power

Log analyse begjint meastentiids mei in sykopdracht: fyn alle berjochten dy't oerienkomme mei in bepaald patroan. Yn Scalyr binne dit tsientallen of hûnderten gigabytes oan logs fan in protte servers. Moderne oanpakken omfetsje yn 'e regel de bou fan wat komplekse gegevensstruktuer optimalisearre foar sykjen. Ik haw dit grif sjoen op Google, wêr't se aardich goed binne yn dit soarte dingen. Mar wy hawwe fêstlein op in folle rûger oanpak: lineêre skennen fan logs. En it wurke - wy leverje in trochsykbere ynterface dy't oarders fan grutte flugger is dan ús konkurrinten (sjoch animaasje oan 'e ein).

It wichtichste ynsjoch wie dat moderne processors yndie heul rap binne by ienfâldige, rjochtlinige operaasjes. Dit is maklik te missen yn komplekse, multi-laach systemen dy't fertrouwe op I / O snelheid en netwurk operaasjes, en sokke systemen binne hiel gewoan hjoed. Dat wy hawwe in ûntwerp ûntwikkele dat lagen en oerstallige ôffal minimalisearret. Mei meardere processors en servers yn parallel berikt de syksnelheid 1 TB per sekonde.

Key takeaways út dit artikel:

  • Brute-force sykjen is in libbensfetbere oanpak foar it oplossen fan echte wrâld, grutskalige problemen.
  • Brute krêft is in ûntwerptechnyk, gjin wurkfrije oplossing. Lykas elke technyk is it better geskikt foar guon problemen as oaren, en kin min of goed útfierd wurde.
  • Brute krêft is benammen goed foar it berikken stâl produktiviteit.
  • Effektyf gebrûk fan brute krêft fereasket it optimalisearjen fan koade en it tapassen fan genôch boarnen op it krekte momint. It is gaadlik as jo servers ûnder swiere net-brûkersbelêsting binne en brûkersoperaasjes in prioriteit bliuwe.
  • Prestaasje hinget ôf fan it ûntwerp fan it hiele systeem, net allinich it algoritme foar binnenste lus.

(Dit artikel beskriuwt it sykjen nei gegevens yn it ûnthâld. Yn 'e measte gefallen, as in brûker in logsykjen útfiert, hawwe de Scalyr-tsjinners it al yn 'e cache bewarre. It folgjende artikel sil it sykjen nei net-cached logs beprate. Deselde prinsipes jilde: effisjinte koade, brute force mei grutte berekkeningsboarnen).

Brute force metoade

Tradysjoneel wurdt in grutte dataset socht mei in trefwurdyndeks. As tapast wurdt op serverlogs, betsjut dit sykjen nei elk unyk wurd yn it log. Foar elk wurd moatte jo in list meitsje fan alle ynklúzjes. Dit makket it maklik om alle berjochten mei dit wurd te finen, bygelyks 'flater', 'firefox' of "transaction_16851951" - sjoch mar yn 'e yndeks.

Ik brûkte dizze oanpak by Google en it wurke goed. Mar yn Scalyr sykje wy de logs byte foar byte.

Wêrom? Fanút in abstrakt algoritmysk eachpunt binne trefwurdyndeksen folle effisjinter dan sykopdrachten mei brute krêft. Wy ferkeapje lykwols gjin algoritmen, wy ferkeapje prestaasjes. En prestaasjes binne net allinich oer algoritmen, mar ek oer systeemtechnyk. Wy moatte alles beskôgje: folume fan gegevens, type sykopdracht, beskikbere hardware en softwarekontekst. Wy besletten dat foar ús spesifike probleem sokssawat as 'grep' better geskikt wie dan in yndeks.

Yndeksen binne geweldich, mar se hawwe beheiningen. Ien wurd is maklik te finen. Mar sykjen nei berjochten mei meardere wurden, lykas 'googlebot' en '404', is folle dreger. It sykjen nei in útdrukking as 'ûngefangen útsûndering' freget in mear omslachtige yndeks dy't net allinich alle berjochten mei dat wurd opnimt, mar ek de spesifike lokaasje fan it wurd.

De echte muoite komt as jo net sykje nei wurden. Litte wy sizze dat jo wolle sjen hoefolle ferkear fan bots komt. De earste gedachte is om de logs te sykjen nei it wurd 'bot'. Dit is hoe't jo guon bots sille fine: Googlebot, Bingbot en in protte oaren. Mar hjir is 'bot' gjin wurd, mar in part derfan. As wy sykje nei 'bot' yn 'e yndeks, sille wy gjin berjochten fine mei it wurd 'Googlebot'. As jo ​​elk wurd yn 'e yndeks kontrolearje en dan de yndeks scannen foar de fûnearde trefwurden, sil it sykjen sterk fertrage. As gefolch, guon log programma 's net tastean diel-wurd sykopdrachten of (op syn bêste) tastean spesjale syntaksis mei legere prestaasjes. Dit wolle wy foarkomme.

In oar probleem is ynterpunksje. Wolle jo fine alle oanfragen fan 50.168.29.7? Wat oer debuggen fan logs dy't befetsje [error]? Abonneminten slaan meastal ynterpunksje oer.

Uteinlik hâlde yngenieurs fan krêftige ark, en soms kin in probleem allinich oplost wurde mei in reguliere útdrukking. De kaaiwurdyndeks is hjir net hiel geskikt foar.

Dêrnjonken binne de yndeksen kompleks. Elk berjocht moat wurde tafoege oan ferskate trefwurdlisten. Dizze listen moatte altyd yn in maklik trochsykber formaat bewarre wurde. Fragen mei útdrukkingen, wurdfragminten of reguliere útdrukkingen moatte wurde oerset yn operaasjes mei meardere list, en de resultaten skansearre en kombineare om in resultaatset te meitsjen. Yn it ramt fan in grutskalige tsjinst mei meardere hierders soarget dizze kompleksiteit foar prestaasjesproblemen dy't net sichtber binne by it analysearjen fan de algoritmen.

Keyword-yndeksen nimme ek in soad romte yn, en opslach is in wichtige kosten yn in logbehearsysteem.

Oan 'e oare kant kin elke sykopdracht in protte komputerkrêft konsumearje. Us brûkers wurdearje hege-snelheid sykopdrachten foar unike queries, mar sokke queries wurde makke relatyf komselden. Foar typyske sykfragen, bygelyks foar in dashboard, brûke wy spesjale techniken (wy sille se beskriuwe yn it folgjende artikel). Oare oanfragen binne selden genôch dat jo selden mear dan ien tagelyk moatte ferwurkje. Mar dit betsjut net dat ús servers net drok binne: se binne dwaande mei it wurk fan it ûntfangen, analysearjen en komprimearjen fan nije berjochten, evaluearjen fan warskôgings, komprimearjen fan âlde gegevens, ensfh. Sa hawwe wy in frij signifikant oanbod fan processors dy't kinne wurde brûkt om queries út te fieren.

Brute krêft wurket as jo in brute probleem hawwe (en in protte krêft)

Brute krêft wurket it bêste op ienfâldige problemen mei lytse ynterne loops. Faak kinne jo de ynterne lus optimalisearje om op heul hege snelheden te rinnen. As de koade kompleks is, is it folle dreger om it te optimalisearjen.

Us sykkoade hie oarspronklik in frij grutte ynderlike lus. Wy bewarje berjochten op siden by 4K; elke side befettet wat berjochten (yn UTF-8) en metadata foar elk berjocht. Metadata is in struktuer dy't de lingte fan 'e wearde, ynterne berjocht-ID en oare fjilden kodearret. De syksyklus seach der sa út:

Sykje op 1 TB/s

Dit is in ferienfâldige ferzje fan 'e eigentlike koade. Mar sels hjir binne meardere objektpleatsingen, gegevenskopyen en funksjeoproppen sichtber. De JVM is aardich goed by it optimalisearjen fan funksjeoproppen en it allocearjen fan efemere objekten, dus dizze koade wurke better dan wy fertsjinnen. Tidens testen brûkten klanten it mei súkses. Mar úteinlik namen wy it nei it folgjende nivo.

(Jo kinne freegje wêrom't wy berjochten opslaan yn dit formaat mei 4K siden, tekst en metadata, ynstee fan wurkjen mei logs direkt. Tekstsykjen wurdt faak kombinearre mei DBMS-stylfilters yn 'e marzjes nei log-parsing. Wy kinne tagelyk in protte tûzenen logs tagelyk sykje, en ienfâldige teksttriemmen binne net geskikt foar ús transaksjoneel, replikearre, ferspraat gegevensbehear).

Yn earste ynstânsje like it dat sa'n koade net heul geskikt wie foar brute krêftoptimalisaasje. "Echt wurk" yn String.indexOf() net iens dominearre it CPU profyl. Dat is, it optimalisearjen fan dizze metoade allinich soe gjin signifikant effekt bringe.

It bart sa dat wy metadata opslaan oan it begjin fan elke side, en de tekst fan alle berjochten yn UTF-8 wurdt ynpakt oan 'e oare ein. Troch dit te profitearjen, hawwe wy de lus opnij skreaun om de heule side tagelyk te sykjen:

Sykje op 1 TB/s

Dizze ferzje wurket direkt op 'e werjefte raw byte[] en trochsykje alle berjochten tagelyk oer de heule 4K-side.

Dit is folle makliker te optimalisearjen foar de brute force metoade. De ynterne syklus wurdt tagelyk neamd foar de heule 4K-side, ynstee fan apart op elke post. D'r is gjin kopiearjen fan gegevens, gjin tawizing fan objekten. En mear komplekse metadata-operaasjes wurde allinich neamd as it resultaat posityf is, en net op elk berjocht. Op dizze manier hawwe wy in ton oan overhead elimineare, en de rest fan 'e lading is konsintrearre yn in lytse ynterne syklus, dy't goed geskikt is foar fierdere optimalisaasje.

Us eigentlike sykalgoritme is basearre op geweldige idee fan Leonid Volnitsky. It is fergelykber mei it Boyer-Moore-algoritme, dat by elke stap sawat de lingte fan 'e sykstring oerslaan. It wichtichste ferskil is dat it twa bytes tagelyk kontrolearret om falske wedstriden te minimalisearjen.

Us ymplemintaasje fereasket it meitsjen fan in 64K-opsyktabel foar elke sykopdracht, mar dat is neat yn ferliking mei de gigabytes oan gegevens dy't wy troch sykje. De binnenste lus ferwurket ferskate gigabytes per sekonde op ien kearn. Yn 'e praktyk is stabile prestaasjes om 1,25 GB per sekonde op elke kearn, en d'r is romte foar ferbettering. It is mooglik om te elimineren guon fan 'e overhead bûten de binnenste lus, en wy binne fan plan om te eksperimintearjen mei in binnenste lus yn C ynstee fan Java.

Wy brûke krêft

Wy hawwe besprutsen dat it sykjen fan logboeken "rûchwei" kin wurde ymplementearre, mar hoefolle "krêft" hawwe wy? Aardich wat.

1 kearn: As it goed brûkt wurdt, is in inkele kearn fan in moderne prosessor frij krêftich op himsels.

8 kearn: Wy rinne op it stuit op Amazon hi1.4xlarge en i2.4xlarge SSD-tsjinners, elk mei 8 kearnen (16 triedden). Lykas hjirboppe neamd, binne dizze kearnen normaal drok mei eftergrûnoperaasjes. As de brûker in sykopdracht útfiert, wurde eftergrûnoperaasjes ophâlden, wat alle 8 kearnen frijmeitsje foar sykjen. De sykopdracht wurdt meastentiids yn in split sekonde foltôge, wêrnei't eftergrûnwurk opnij begjint (it smoarchprogramma soarget derfoar dat de sperring fan sykfragen net ynterfereart mei wichtich eftergrûnwurk).

16 kearn: foar betrouberens, wy organisearje tsjinners yn master / slaaf groepen. Elke master hat ien SSD en ien EBS-tsjinner ûnder syn kommando. As de haadtsjinner crasht, nimt de SSD-tsjinner fuortendaliks syn plak yn. Hast de hiele tiid wurkje master en slaaf goed, sadat elk gegevensblok trochsykber is op twa ferskillende servers (de EBS-slave-tsjinner hat in swakke prosessor, dus wy beskôgje it net). Wy diele de taak tusken harren, sadat wy hawwe yn totaal 16 kearnen beskikber.

In protte kearnen: Yn de heine takomst sille wy gegevens fersprieden oer servers op sa'n manier dat se allegear meidwaan oan it ferwurkjen fan elke net-triviale fersyk. Elke kearn sil wurkje. [Noat: wy hawwe it plan útfierd en de syksnelheid fergrutte nei 1 TB / s, sjoch notysje oan 'e ein fan it artikel].

Ienfâld soarget foar betrouberens

In oar foardiel fan 'e brute force-metoade is har frij konsekwinte prestaasjes. Typysk is sykjen net heul gefoelich foar de details fan it probleem en gegevensset (ik tink dat it dêrom "grof" wurdt neamd).

De trefwurdyndeks produseart soms ongelooflijk rappe resultaten, en oare kearen net. Litte wy sizze dat jo 50 GB oan logs hawwe wêryn de term 'customer_5987235982' krekt trije kear ferskynt. In sykopdracht foar dizze term telt trije lokaasjes direkt út de yndeks en sil direkt foltôgje. Mar komplekse sykopdrachten mei jokertekens kinne tûzenen kaaiwurden scannen en in lange tiid duorje.

Oan 'e oare kant dogge brute force-sykopdrachten op min of mear deselde snelheid foar elke fraach. It sykjen nei lange wurden is better, mar sels sykjen nei ien karakter is frij fluch.

De ienfâld fan 'e brute force-metoade betsjut dat syn prestaasjes tichtby syn teoretyske maksimum binne. D'r binne minder opsjes foar ûnferwachte skiif-overloads, slûskontrôle, oanwizer jagen, en tûzenen oare redenen foar mislearring. Ik seach krekt nei de oanfragen makke troch Scalyr-brûkers ferline wike op ús drokste server. Der wiene 14 oanfragen. Krekt acht fan harren namen mear as ien sekonde; 000% foltôge binnen 99 millisekonden (as jo gjin ark foar loganalyse hawwe brûkt, fertrou my: it is fluch).

Stabile, betroubere prestaasjes binne wichtich foar it gemak fan gebrûk fan 'e tsjinst. As it periodyk bliuwt, sille brûkers it as ûnbetrouber ûnderfine en weromhâldend wêze om it te brûken.

Log sykje yn aksje

Hjir is in koarte animaasje dy't Scalyr-sykjen yn aksje toant. Wy hawwe in demo-akkount wêr't wy elk barren ymportearje yn elke iepenbiere Github-repository. Yn dizze demo ûndersiikje ik de wearde fan in wike oan gegevens: sawat 600 MB oan rauwe logs.

De fideo waard live opnommen, sûnder spesjale tarieding, op myn buroblêd (sawat 5000 kilometer fan 'e tsjinner). De prestaasjes dy't jo sille sjen is foar in grut part te tankjen web client optimalisaasje, lykas ek in rappe en betroubere backend. Wannear't d'r in pauze is sûnder in 'laden'-yndikator, is it my pauze, sadat jo kinne lêze wat ik op it punt stean te drukken.

Sykje op 1 TB/s

Yn ôfsluting

By it ferwurkjen fan grutte hoemannichten gegevens is it wichtich om in goed algoritme te kiezen, mar "goed" betsjut net "fancy". Tink oer hoe't jo koade yn 'e praktyk sil wurkje. De teoretyske analyze fan algoritmen lit guon faktoaren út dy't fan grut belang kinne wêze yn 'e echte wrâld. Ienfâldiger algoritmen binne makliker te optimalisearjen en stabiler yn rânesituaasjes.

Tink ek oer de kontekst wêryn't de koade sil wurde útfierd. Yn ús gefal hawwe wy genôch krêftige servers nedich om eftergrûntaken te behearjen. Brûkers begjinne sykjen relatyf selden, sadat wy in hiele groep servers liene kinne foar de koarte perioade dy't nedich is om elke sykopdracht te foltôgjen.

Mei help fan in brute force-metoade hawwe wy in rappe, betroubere, fleksibele sykopdracht ymplementearre oer in set logs. Wy hoopje dat dizze ideeën nuttich binne foar jo projekten.

Bewurkje: De titel en tekst binne feroare fan "Sykje mei 20 GB per sekonde" nei "Sykje mei 1 TB per sekonde" om de prestaasjesferhegingen oer de ôfrûne jierren te reflektearjen. Dizze ferheging fan snelheid is foaral te tankjen oan feroaringen yn it type en oantal EC2-tsjinners dy't wy hjoed opsette om ús ferhege klantbasis te tsjinjen. D'r komme gau feroaringen dy't in oare dramatyske ympuls sille leverje yn operasjonele effisjinsje, en wy kinne net wachtsje om se te dielen.

Boarne: www.habr.com

Add a comment