Որոնել 1 ՏԲ/վ արագությամբ

TL;DR. Չորս տարի առաջ ես թողեցի Google-ը սերվերի մոնիտորինգի նոր գործիք ստեղծելու գաղափարով: Գաղափարն այն էր, որ սովորաբար մեկուսացված գործառույթները միավորվեն մեկ ծառայության մեջ հավաքածու և գրանցամատյանների վերլուծություն, չափումների հավաքածու, ահազանգեր և վահանակներ: Սկզբունքներից մեկն այն է, որ ծառայությունը պետք է լինի իսկապես արագ, տրամադրելով devops-ին հեշտ, ինտերակտիվ, հաճելի փորձ: Սա պահանջում է մշակել բազմագիգաբայթ տվյալների հավաքածուներ վայրկյանի կոտորակներում՝ մնալով բյուջեի սահմաններում: Տեղեկամատյանների կառավարման գոյություն ունեցող գործիքները հաճախ դանդաղ են և կոպիտ, այնպես որ մենք բախվեցինք լավ մարտահրավերի.

Այս հոդվածը նկարագրում է, թե ինչպես մենք Scalyr-ում լուծեցինք այս խնդիրը՝ կիրառելով հին դպրոցական մեթոդներ, բիրտ ուժի մոտեցում, վերացնելով ավելորդ շերտերը և խուսափելով տվյալների բարդ կառուցվածքներից: Դուք կարող եք կիրառել այս դասերը ձեր սեփական ինժեներական խնդիրների համար:

Old School Power

Մատյանների վերլուծությունը սովորաբար սկսվում է որոնումից՝ գտնել բոլոր հաղորդագրությունները, որոնք համապատասխանում են որոշակի օրինակին: Scalyr-ում սրանք տասնյակ կամ հարյուրավոր գիգաբայթ տեղեկամատյաններ են բազմաթիվ սերվերներից: Ժամանակակից մոտեցումները, որպես կանոն, ներառում են որոնման համար օպտիմալացված տվյալների ինչ-որ բարդ կառուցվածքի կառուցում։ Ես, անշուշտ, դա տեսել եմ Google-ում, որտեղ նրանք բավականին լավ են տիրապետում նման բաներին: Բայց մենք որոշեցինք շատ ավելի կոպիտ մոտեցում՝ գերանների գծային սկանավորում: Եվ դա ստացվեց. մենք տրամադրում ենք որոնելի ինտերֆեյս, որն ավելի արագ է, քան մեր մրցակիցները (տես անիմացիան վերջում):

Հիմնական պատկերացումն այն էր, որ ժամանակակից պրոցեսորներն իսկապես շատ արագ են աշխատում պարզ, պարզ գործողություններում: Սա հեշտ է բաց թողնել բարդ, բազմաշերտ համակարգերում, որոնք հիմնված են I/O արագության և ցանցային գործառնությունների վրա, և նման համակարգերն այսօր շատ տարածված են: Այսպիսով, մենք մշակեցինք դիզայն, որը նվազագույնի է հասցնում շերտերն ու ավելորդ բեկորները: Զուգահեռաբար մի քանի պրոցեսորների և սերվերների դեպքում որոնման արագությունը հասնում է 1 ՏԲ վայրկյանում:

Այս հոդվածի հիմնական կետերը.

  • Brute-force որոնումը կենսունակ մոտեցում է իրական աշխարհի, լայնածավալ խնդիրների լուծման համար:
  • Կոպիտ ուժը նախագծման տեխնիկա է, այլ ոչ թե աշխատանքից ազատ լուծում: Ինչպես ցանկացած տեխնիկա, այն ավելի հարմար է որոշ խնդիրների, քան մյուսները, և կարող է վատ կամ լավ իրականացվել:
  • Դաժան ուժը հատկապես լավ է հասնելու համար կայուն արտադրողականություն։
  • Կոպիտ ուժի արդյունավետ օգտագործումը պահանջում է կոդի օպտիմիզացում և բավարար ռեսուրսների ճիշտ ժամանակին կիրառում: Այն հարմար է, եթե ձեր սերվերները ծանրաբեռնված են ոչ օգտատերերի տակ, և օգտագործողի գործողությունները մնում են առաջնահերթություն:
  • Կատարումը կախված է ամբողջ համակարգի նախագծումից, այլ ոչ միայն ներքին օղակի ալգորիթմից:

(Այս հոդվածը նկարագրում է հիշողության մեջ տվյալների որոնումը: Շատ դեպքերում, երբ օգտատերը կատարում է գրանցամատյանների որոնում, Scalyr սերվերներն արդեն պահում են այն: Հաջորդ հոդվածում կքննարկվի չքեշավորված տեղեկամատյանների որոնումը: Գործում են նույն սկզբունքները. արդյունավետ կոդ, կոպիտ ուժ: մեծ հաշվողական ռեսուրսներով):

Կոպիտ ուժի մեթոդ

Ավանդաբար տվյալների մեծ հավաքածու որոնվում է հիմնաբառերի ինդեքսով: Երբ կիրառվում է սերվերի տեղեկամատյանների վրա, դա նշանակում է որոնել մատյանում յուրաքանչյուր եզակի բառ: Յուրաքանչյուր բառի համար անհրաժեշտ է կազմել բոլոր ընդգրկումների ցուցակը: Սա հեշտացնում է այս բառով բոլոր հաղորդագրությունները գտնելը, օրինակ՝ «սխալ», «firefox» կամ «transaction_16851951», պարզապես նայեք ինդեքսում:

Ես օգտագործեցի այս մոտեցումը Google-ում և այն լավ աշխատեց: Բայց Scalyr-ում մենք բայթ առ բայթ որոնում ենք տեղեկամատյանները:

Ինչո՞ւ։ Վերացական ալգորիթմական տեսանկյունից հիմնաբառերի ինդեքսները շատ ավելի արդյունավետ են, քան բիրտ ուժի որոնումները: Այնուամենայնիվ, մենք չենք վաճառում ալգորիթմներ, մենք վաճառում ենք կատարումը: Եվ կատարումը ոչ միայն ալգորիթմների, այլ նաև համակարգերի ճարտարագիտության մասին է: Մենք պետք է հաշվի առնենք ամեն ինչ՝ տվյալների ծավալը, որոնման տեսակը, հասանելի ապարատային և ծրագրային համատեքստը: Մենք որոշեցինք, որ մեր կոնկրետ խնդրի համար «grep»-ի նման մի բան ավելի հարմար է, քան ինդեքսը:

Ինդեքսները հիանալի են, բայց ունեն սահմանափակումներ: Մեկ բառը հեշտ է գտնել: Սակայն բազմաթիվ բառերով հաղորդագրություններ որոնելը, ինչպիսիք են «googlebot» և «404», շատ ավելի դժվար է: «Չբռնված բացառություն» արտահայտությունը որոնելը պահանջում է ավելի ծանր ինդեքս, որը գրանցում է ոչ միայն այդ բառով բոլոր հաղորդագրությունները, այլև բառի կոնկրետ գտնվելու վայրը:

Իրական դժվարությունը գալիս է, երբ բառեր չես փնտրում։ Ենթադրենք, դուք ուզում եք տեսնել, թե որքան տրաֆիկ է գալիս բոտերից: Առաջին միտքը տեղեկամատյաններում փնտրելն է «bot» բառը: Այսպես դուք կգտնեք որոշ բոտեր՝ Googlebot, Bingbot և շատ ուրիշներ: Բայց այստեղ «բոտը» բառ չէ, այլ դրա մի մասը։ Եթե ​​ինդեքսում «bot» որոնենք, «Googlebot» բառով գրառումներ չենք գտնի: Եթե ​​դուք ստուգեք ինդեքսի յուրաքանչյուր բառը, ապա սկանավորեք ինդեքսը գտնված հիմնաբառերի համար, որոնումը զգալիորեն կդանդաղի: Արդյունքում, որոշ տեղեկամատյանների ծրագրեր թույլ չեն տալիս մասամբ որոնումներ կատարել կամ (լավագույն դեպքում) թույլ են տալիս հատուկ շարահյուսություն ավելի ցածր կատարողականությամբ: Մենք ցանկանում ենք խուսափել սրանից։

Մեկ այլ խնդիր է կետադրությունը: Ցանկանու՞մ եք գտնել բոլոր հարցումները 50.168.29.7? Ինչ վերաբերում է վրիպազերծման տեղեկամատյաններին, որոնք պարունակում են [error]? Բաժանորդները սովորաբար բաց են թողնում կետադրական նշանները:

Ի վերջո, ինժեներները սիրում են հզոր գործիքներ, և երբեմն խնդիրը կարող է լուծվել միայն սովորական արտահայտությամբ: Հիմնաբառերի ինդեքսն այնքան էլ հարմար չէ դրա համար:

Բացի այդ, ցուցանիշները համալիր. Յուրաքանչյուր հաղորդագրություն պետք է ավելացվի մի քանի հիմնաբառերի ցանկում: Այս ցուցակները պետք է միշտ պահվեն հեշտությամբ որոնելի ձևաչափով: Բառակապակցություններով, բառերի բեկորներով կամ կանոնավոր արտահայտություններով հարցումները պետք է թարգմանվեն բազմացանկի գործողություններով, իսկ արդյունքները սկանավորվեն և համակցվեն՝ արդյունքի հավաքածու ստեղծելու համար: Լայնածավալ, բազմաբնակարան վարձակալող ծառայության համատեքստում այս բարդությունը ստեղծում է կատարողականի խնդիրներ, որոնք տեսանելի չեն ալգորիթմները վերլուծելիս:

Հիմնաբառերի ինդեքսները նույնպես շատ տեղ են զբաղեցնում, և պահեստավորումը հիմնական ծախսն է տեղեկամատյանների կառավարման համակարգում:

Մյուս կողմից, յուրաքանչյուր որոնում կարող է սպառել շատ հաշվողական հզորություն: Մեր օգտատերերը գնահատում են եզակի հարցումների գերարագ որոնումները, սակայն նման հարցումները կատարվում են համեմատաբար հազվադեպ: Տիպիկ որոնման հարցումների համար, օրինակ, վահանակի համար, մենք օգտագործում ենք հատուկ տեխնիկա (դրանք կնկարագրենք հաջորդ հոդվածում): Այլ հարցումները բավական հազվադեպ են լինում, որ դուք հազվադեպ եք ստիպված լինում միաժամանակ մեկից ավելի մշակել: Բայց դա չի նշանակում, որ մեր սերվերները զբաղված չեն. նրանք զբաղված են նոր հաղորդագրություններ ստանալու, վերլուծելու և սեղմելու, ծանուցումների գնահատման, հին տվյալների սեղմման և այլնի աշխատանքով: Այսպիսով, մենք ունենք պրոցեսորների բավականին զգալի մատակարարում, որոնք կարող են օգտագործվել հարցումներ կատարելու համար:

Կոպիտ ուժն աշխատում է, եթե դուք ունեք կոպիտ խնդիր (և մեծ ուժ)

Կոպիտ ուժը լավագույնս աշխատում է փոքր ներքին օղակներով պարզ խնդիրների դեպքում: Հաճախ դուք կարող եք օպտիմիզացնել ներքին օղակը շատ բարձր արագությամբ աշխատելու համար: Եթե ​​կոդը բարդ է, ապա այն օպտիմալացնելը շատ ավելի դժվար է։

Մեր որոնման կոդը ի սկզբանե ուներ բավականին մեծ ներքին օղակ: Մենք հաղորդագրությունները պահում ենք էջերում 4K; յուրաքանչյուր էջ պարունակում է որոշ հաղորդագրություններ (UTF-8-ում) և մետատվյալներ յուրաքանչյուր հաղորդագրության համար: Մետատվյալները կառույց է, որը կոդավորում է արժեքի երկարությունը, ներքին հաղորդագրության ID-ն և այլ դաշտերը: Որոնման ցիկլը այսպիսի տեսք ուներ.

Որոնել 1 ՏԲ/վ արագությամբ

Սա իրական կոդի պարզեցված տարբերակն է: Բայց նույնիսկ այստեղ տեսանելի են բազմաթիվ օբյեկտների տեղադրում, տվյալների պատճեններ և գործառույթների կանչեր: JVM-ը բավականին լավ է օպտիմիզացնում գործառույթների կանչերը և տեղաբաշխում է ժամանակավոր օբյեկտները, ուստի այս կոդը ավելի լավ աշխատեց, քան մենք արժանի էինք: Փորձարկման ժամանակ հաճախորդները բավականին հաջողությամբ օգտագործեցին այն։ Բայց ի վերջո մենք այն տեղափոխեցինք հաջորդ մակարդակ:

(Կարող եք հարցնել, թե ինչու ենք մենք այս ձևաչափով հաղորդագրությունները պահում 4K էջերով, տեքստով և մետատվյալներով, այլ ոչ թե ուղղակիորեն տեղեկամատյանների հետ աշխատելու: Շատ պատճառներ կան, որոնք հանգում են նրան, որ Scalyr շարժիչը ներսից ավելի շատ նման է բաշխված տվյալների բազայի, քան տվյալների բազայի: ֆայլային համակարգ: Տեքստի որոնումը հաճախ զուգակցվում է DBMS ոճի ֆիլտրերի հետ մատյանների վերլուծությունից հետո: Մենք կարող ենք միաժամանակ որոնել հազարավոր տեղեկամատյաններ, և պարզ տեքստային ֆայլերը հարմար չեն մեր գործարքային, կրկնօրինակված, բաշխված տվյալների կառավարման համար):

Սկզբում թվում էր, որ նման ծածկագիրը այնքան էլ հարմար չէ բիրտ ուժի օպտիմալացման համար։ «Իրական աշխատանք». String.indexOf() նույնիսկ չի գերակշռել պրոցեսորի պրոֆիլում: Այսինքն՝ միայն այս մեթոդի օպտիմալացումը էական ազդեցություն չէր բերի։

Պատահում է, որ մենք պահում ենք մետատվյալները յուրաքանչյուր էջի սկզբում, իսկ UTF-8-ի բոլոր հաղորդագրությունների տեքստը փաթեթավորվում է մյուս ծայրում: Օգտվելով դրանից՝ մենք նորից գրեցինք հանգույցը՝ ամբողջ էջը միանգամից որոնելու համար.

Որոնել 1 ՏԲ/վ արագությամբ

Այս տարբերակը աշխատում է անմիջապես դիտման վրա raw byte[] և միանգամից որոնում է բոլոր հաղորդագրությունները ողջ 4K էջում:

Սա շատ ավելի հեշտ է օպտիմալացնել կոպիտ ուժի մեթոդի համար: Ներքին որոնման հանգույցը կոչվում է միաժամանակ ամբողջ 4K էջի համար, այլ ոչ թե յուրաքանչյուր գրառման առանձին: Չկա տվյալների պատճենում, օբյեկտների տեղաբաշխում: Իսկ ավելի բարդ մետատվյալների գործողությունները կոչվում են միայն այն դեպքում, երբ արդյունքը դրական է, այլ ոչ թե յուրաքանչյուր հաղորդագրության: Այս կերպ մենք վերացրել ենք մի տոննա գլխավճար, իսկ մնացած բեռը կենտրոնացած է ներքին որոնման փոքր օղակում, որը լավ հարմար է հետագա օպտիմալացման համար:

Մեր իրական որոնման ալգորիթմը հիմնված է Լեոնիդ Վոլնիցկու հիանալի գաղափարը. Այն նման է Boyer-Moore ալգորիթմին՝ յուրաքանչյուր քայլում շրջանցելով որոնման տողի մոտավորապես երկարությունը։ Հիմնական տարբերությունն այն է, որ այն միաժամանակ ստուգում է երկու բայթ՝ նվազագույնի հասցնելու կեղծ համընկնումները:

Մեր իրականացումը պահանջում է ստեղծել 64K որոնման աղյուսակ յուրաքանչյուր որոնման համար, բայց դա ոչինչ է այն գիգաբայթ տվյալների համեմատ, որոնք մենք որոնում ենք: Ներքին օղակը մեկ միջուկի վրա մեկ վայրկյանում մի քանի գիգաբայթ է մշակում: Գործնականում յուրաքանչյուր միջուկի վրա կայուն կատարումը կազմում է վայրկյանում 1,25 ԳԲ, և բարելավման տեղ կա: Հնարավոր է վերացնել ներքին օղակից դուրս գտնվող վերադիրների մի մասը, և մենք նախատեսում ենք փորձարկել C-ում ներքին հանգույցով Java-ի փոխարեն:

Մենք ուժ ենք կիրառում

Մենք քննարկել ենք, որ տեղեկամատյանների որոնումը կարող է իրականացվել «մոտավորապես», բայց որքա՞ն «ուժ» ունենք: Բավականին շատ.

1 միջուկԵրբ ճիշտ օգտագործվում է, ժամանակակից պրոցեսորի մեկ միջուկն ինքնին բավականին հզոր է:

8 միջուկՄենք ներկայումս աշխատում ենք Amazon hi1.4xlarge և i2.4xlarge SSD սերվերների վրա, որոնցից յուրաքանչյուրը ունի 8 միջուկ (16 թելեր): Ինչպես նշվեց վերևում, այս միջուկները սովորաբար զբաղված են ֆոնային գործառնություններով: Երբ օգտատերը որոնում է կատարում, ֆոնային գործողությունները կասեցվում են՝ ազատելով բոլոր 8 միջուկները որոնման համար: Որոնումը սովորաբար ավարտվում է մի պառակտման վայրկյանում, որից հետո ֆոնային աշխատանքը վերսկսվում է (խեղդող ծրագիրը ապահովում է, որ որոնման հարցումների տարափը չի խանգարի կարևոր ֆոնային աշխատանքին):

16 միջուկՀուսալիության համար մենք սերվերները կազմակերպում ենք գլխավոր/ստրուկ խմբերի: Յուրաքանչյուր վարպետ իր հրամանատարության տակ ունի մեկ SSD և մեկ EBS սերվեր: Եթե ​​հիմնական սերվերը խափանում է, SSD սերվերը անմիջապես զբաղեցնում է իր տեղը: Գրեթե միշտ վարպետը և ստրուկը լավ են աշխատում, այնպես որ տվյալների յուրաքանչյուր բլոկ հնարավոր է որոնել երկու տարբեր սերվերների վրա (EBS ստրուկ սերվերն ունի թույլ պրոցեսոր, ուստի մենք դա չենք համարում): Մենք առաջադրանքը բաժանում ենք նրանց միջև, որպեսզի ընդհանուր առմամբ հասանելի լինի 16 միջուկ։

Շատ միջուկներՄոտ ապագայում մենք կտարածենք տվյալները սերվերների վրա այնպես, որ նրանք բոլորը մասնակցեն յուրաքանչյուր ոչ տրիվիալ հարցումների մշակմանը: Յուրաքանչյուր միջուկ կաշխատի: [Նշում: մենք իրականացրեցինք պլանը և ավելացրինք որոնման արագությունը մինչև 1 ՏԲ/վ, տես հոդվածի վերջում նշված նշումը].

Պարզությունն ապահովում է հուսալիություն

Կոպիտ ուժի մեթոդի մեկ այլ առավելություն նրա բավականին հետևողական կատարումն է: Որպես կանոն, որոնումը շատ զգայուն չէ խնդրի մանրամասների և տվյալների հավաքածուի նկատմամբ (կարծում եմ, դրա համար էլ այն կոչվում է «կոպիտ»):

Հիմնաբառերի ինդեքսը երբեմն տալիս է անհավատալի արագ արդյունքներ, իսկ երբեմն՝ ոչ: Ենթադրենք, դուք ունեք 50 ԳԲ տեղեկամատյաններ, որոնցում «customer_5987235982» տերմինը հայտնվում է ուղիղ երեք անգամ: Այս տերմինի որոնումը հաշվում է երեք տեղ անմիջապես ինդեքսից և կավարտվի անմիջապես: Սակայն նիշերի բարդ որոնումները կարող են սկանավորել հազարավոր հիմնաբառեր և երկար ժամանակ տևել:

Մյուս կողմից, բիրտ ուժի որոնումները կատարվում են քիչ թե շատ նույն արագությամբ ցանկացած հարցման համար: Երկար բառեր որոնելը ավելի լավ է, բայց նույնիսկ մեկ նիշ փնտրելը բավականին արագ է:

Կոպիտ ուժի մեթոդի պարզությունը նշանակում է, որ դրա կատարումը մոտ է իր տեսական առավելագույնին: Սկավառակի անսպասելի ծանրաբեռնվածության, կողպեքի վեճի, ցուցիչի հետապնդման և ձախողման հազարավոր այլ պատճառների ավելի քիչ տարբերակներ կան: Ես պարզապես նայեցի անցյալ շաբաթ Scalyr-ի օգտատերերի խնդրանքներին մեր ամենազբաղված սերվերում: 14 հարցում է եղել։ Դրանցից ուղիղ ութը մեկ վայրկյանից ավելի տևեց. 000%-ն ավարտվել է 99 միլիվայրկյանում (եթե չեք օգտագործել մատյանների վերլուծության գործիքները, վստահեք ինձ. դա արագ է).

Կայուն, հուսալի կատարումը կարևոր է ծառայության հեշտ օգտագործման համար: Եթե ​​այն պարբերաբար ուշանա, օգտատերերը այն կընկալեն որպես անվստահելի և դժկամությամբ կօգտագործեն այն:

Մուտքագրեք որոնումը գործողության մեջ

Ահա մի կարճ անիմացիա, որը ցույց է տալիս Scalyr որոնումը գործողության մեջ: Մենք ունենք ցուցադրական հաշիվ, որտեղ մենք ներմուծում ենք յուրաքանչյուր իրադարձություն Github-ի յուրաքանչյուր հանրային պահեստում: Այս ցուցադրությունում ես ուսումնասիրում եմ մեկ շաբաթվա տվյալները՝ մոտավորապես 600 ՄԲ չմշակված տեղեկամատյաններ:

Տեսանյութը ձայնագրվել է ուղիղ եթերում, առանց հատուկ պատրաստման, իմ աշխատասեղանին (սերվերից մոտ 5000 կիլոմետր հեռավորության վրա)։ Կատարումը, որը դուք կտեսնեք, հիմնականում պայմանավորված է վեբ հաճախորդի օպտիմիզացում, ինչպես նաև արագ և հուսալի backend: Ամեն անգամ, երբ կա դադար առանց «բեռնման» ցուցիչի, դա ես եմ դադարեցնում, որպեսզի կարողանաք կարդալ այն, ինչ ես պատրաստվում եմ սեղմել:

Որոնել 1 ՏԲ/վ արագությամբ

Վերջում

Մեծ քանակությամբ տվյալներ մշակելիս կարևոր է ընտրել լավ ալգորիթմ, բայց «լավը» չի նշանակում «շքեղ»: Մտածեք, թե ինչպես է ձեր կոդը գործնականում աշխատելու: Ալգորիթմների տեսական վերլուծությունը բաց է թողնում որոշ գործոններ, որոնք կարող են մեծ նշանակություն ունենալ իրական աշխարհում։ Ավելի պարզ ալգորիթմներն ավելի հեշտ են օպտիմիզացվում և ավելի կայուն են եզրային իրավիճակներում:

Մտածեք նաև այն համատեքստի մասին, որում կկատարվի կոդը: Մեր դեպքում մեզ անհրաժեշտ են բավականաչափ հզոր սերվերներ՝ ֆոնային առաջադրանքները կառավարելու համար: Օգտատերերը որոնումներ են սկսում համեմատաբար հազվադեպ, այնպես որ մենք կարող ենք սերվերների մի ամբողջ խումբ վերցնել յուրաքանչյուր որոնումն ավարտելու համար անհրաժեշտ կարճ ժամանակահատվածի համար:

Օգտագործելով բիրտ ուժի մեթոդը, մենք իրականացրեցինք արագ, հուսալի, ճկուն որոնում մի շարք տեղեկամատյաններում: Հուսով ենք, որ այս գաղափարները օգտակար կլինեն ձեր նախագծերի համար:

Խմբագրել: Վերնագիրը և տեքստը փոխվել են «Որոնել վայրկյանում 20 ԳԲ արագությամբ» «Որոնել վայրկյանում 1 ՏԲ արագությամբ»՝ վերջին մի քանի տարիների ընթացքում կատարողականի բարձրացումն արտացոլելու համար: Արագության այս աճը հիմնականում պայմանավորված է EC2 սերվերների տեսակի և քանակի փոփոխություններով, որոնք մենք այսօր տեղադրում ենք՝ սպասարկելու մեր ավելացած հաճախորդների բազան: Շուտով կլինեն փոփոխություններ, որոնք կապահովեն գործառնական արդյունավետության ևս մեկ կտրուկ խթան, և մենք անհամբեր սպասում ենք դրանք կիսելուն:

Source: www.habr.com

Добавить комментарий