1 ТБ/с жылдамдықпен іздеу

TL; DR: Төрт жыл бұрын мен Google-дан серверді бақылаудың жаңа құралы туралы идеямен кеттім. Бұл идея әдетте оқшауланған функцияларды бір қызметке біріктіру болды жинақ және журналды талдау, көрсеткіштерді жинау, ескертулер және бақылау тақталары. Қағидалардың бірі – қызмет шынайы болуы керек жылдам, devops жеңіл, интерактивті, жағымды тәжірибемен қамтамасыз ету. Бұл бюджет шегінде бола отырып, бірнеше гигабайттық деректер жиынын секундтың бөліктерінде өңдеуді талап етеді. Қолданыстағы журналдарды басқару құралдары жиі баяу және қиын, сондықтан біз жақсы қиындыққа тап болдық: пайдаланушыларға жаңа тәжірибе беру үшін құралды ақылмен жобалау.

Бұл мақалада біз Скалирде ескі мектеп әдістерін, қатал күш әдісін қолдану, қажетсіз қабаттарды жою және күрделі деректер құрылымдарын болдырмау арқылы бұл мәселені қалай шешкеніміз сипатталған. Сіз бұл сабақтарды өзіңіздің инженерлік есептерге қолдана аласыз.

Ескі мектеп күші

Журналды талдау әдетте іздеуден басталады: белгілі бір үлгіге сәйкес келетін барлық хабарларды табыңыз. Скалирде бұл көптеген серверлерден ондаған немесе жүздеген гигабайт журналдар. Қазіргі заманғы тәсілдер, әдетте, іздеу үшін оңтайландырылған кейбір күрделі деректер құрылымын құруды қамтиды. Мен мұны Google-да көрдім, мұнда олар мұндай нәрседе өте жақсы. Бірақ біз әлдеқайда өрескел тәсілге тоқтадық: журналдарды сызықтық сканерлеу. Және бұл жұмыс істеді - біз бәсекелестерімізге қарағанда жылдамырақ іздеуге болатын интерфейсті береміз (соңындағы анимацияны қараңыз).

Негізгі түсінік қазіргі заманғы процессорлардың қарапайым, қарапайым операцияларда өте жылдам екендігі болды. Енгізу/шығару жылдамдығына және желілік операцияларға сүйенетін күрделі, көп деңгейлі жүйелерде мұны оңай жіберіп алу және мұндай жүйелер бүгінде өте кең таралған. Сондықтан біз қабаттар мен артық қоқыстарды азайтатын дизайнды жасадық. Параллельді бірнеше процессорлар мен серверлермен іздеу жылдамдығы секундына 1 ТБ жетеді.

Осы мақаланың негізгі қорытындылары:

  • Қатыгез күшпен іздеу – бұл нақты дүниедегі ауқымды мәселелерді шешудің өміршең тәсілі.
  • Қатал күш - бұл жұмыссыз шешім емес, дизайн әдісі. Кез келген техника сияқты, ол кейбір мәселелерге басқаларға қарағанда жақсырақ келеді және нашар немесе жақсы орындалуы мүмкін.
  • Қатыгез күш әсіресе қол жеткізу үшін жақсы тұрақты өнімділік.
  • Қатал күшті тиімді пайдалану кодты оңтайландыруды және қажетті уақытта жеткілікті ресурстарды қолдануды талап етеді. Бұл сіздің серверлеріңіз пайдаланушыға жатпайтын ауыр жүктеме астында болса және пайдаланушы операциялары басымдылық болып қала берсе қолайлы.
  • Өнімділік тек ішкі цикл алгоритміне емес, бүкіл жүйенің дизайнына байланысты.

(Бұл мақала жадтағы деректерді іздеуді сипаттайды. Көп жағдайда пайдаланушы журналды іздеуді орындаған кезде, Scalyr серверлері оны кэштеп қойған. Келесі мақалада кэштелмеген журналдарды іздеу талқыланады. Дәл осындай принциптер қолданылады: тиімді код, қатал күш үлкен есептеу ресурстарымен).

Қатал күш әдісі

Дәстүрлі түрде үлкен деректер жиыны кілт сөз индексі арқылы ізделеді. Сервер журналдарына қолданылғанда, бұл журналдағы әрбір бірегей сөзді іздеуді білдіреді. Әрбір сөз үшін барлық кірмелердің тізімін жасау керек. Бұл осы сөзден тұратын барлық хабарларды табуды жеңілдетеді, мысалы, «қате», «firefox» немесе «transaction_16851951» – жай ғана индексті қараңыз.

Мен бұл әдісті Google-да қолдандым және ол жақсы жұмыс істеді. Бірақ Scalyr-де біз журналдарды байт бойынша іздейміз.

Неліктен? Абстрактілі алгоритмдік тұрғыдан алғанда, кілт сөздердің индекстері дөрекі күшпен іздеуге қарағанда әлдеқайда тиімді. Дегенмен, біз алгоритмдерді сатпаймыз, өнімділікті сатамыз. Ал өнімділік тек алгоритмдерге ғана емес, сонымен қатар жүйелік инженерияға да қатысты. Біз бәрін ескеруіміз керек: деректер көлемі, іздеу түрі, қол жетімді аппараттық және бағдарламалық қамтамасыз ету контексті. Біз нақты мәселеміз үшін «grep» сияқты нәрсе индекске қарағанда жақсырақ деп шештік.

Индекстер керемет, бірақ олардың шектеулері бар. Бір сөзді табу оңай. Бірақ «googlebot» және «404» сияқты бірнеше сөзден тұратын хабарларды іздеу әлдеқайда қиын. «Ұсталмаған ерекшелік» сияқты фразаны іздеу сол сөзбен барлық хабарларды ғана емес, сонымен қатар сөздің нақты орнын жазатын анағұрлым ауыр индексті қажет етеді.

Нағыз қиындық сөз іздемегенде келеді. Сіз боттардан қанша трафик келетінін көргіңіз келеді делік. Бірінші ой - журналдардан «бот» сөзін іздеу. Осылайша сіз кейбір боттарды таба аласыз: Googlebot, Bingbot және басқалары. Бірақ бұл жерде «бот» сөз емес, оның бір бөлігі. Егер индексте «бот» деп іздесек, «Googlebot» сөзі бар жазбаларды таппаймыз. Егер сіз индекстегі әрбір сөзді тексеріп, содан кейін табылған кілт сөздер үшін индексті сканерлесеңіз, іздеу айтарлықтай баяулайды. Нәтижесінде, кейбір журнал бағдарламалары ішінара сөз іздеуге рұқсат бермейді немесе (ең жақсы жағдайда) өнімділігі төмен арнайы синтаксиске рұқсат береді. Біз мұны болдырмауды қалаймыз.

Тағы бір мәселе тыныс белгілері. Барлық сұрауларды тапқыңыз келе ме? 50.168.29.7? Құрамындағы журналдарды жөндеу туралы не деуге болады [error]? Жазбалар әдетте тыныс белгілерін өткізіп жібереді.

Ақырында, инженерлер қуатты құралдарды жақсы көреді, кейде мәселені тек тұрақты өрнек арқылы шешуге болады. Бұл үшін индекс кілт сөзі өте қолайлы емес.

Сонымен қатар, индекстер кешен. Әрбір хабарлама бірнеше кілт сөздер тізіміне қосылуы керек. Бұл тізімдер әрқашан оңай іздеуге болатын форматта сақталуы керек. Фразалар, сөз фрагменттері немесе тұрақты өрнектері бар сұрауларды көп тізім әрекеттеріне аудару керек және нәтижелер жиынын жасау үшін нәтижелерді сканерлеу және біріктіру қажет. Кең ауқымды, көп жалға алушы қызмет контекстінде бұл күрделілік алгоритмдерді талдау кезінде көрінбейтін өнімділік мәселелерін жасайды.

Кілтсөз индекстері де көп орын алады, ал сақтау журналды басқару жүйесінде негізгі шығын болып табылады.

Екінші жағынан, әрбір іздеу көп есептеу қуатын тұтынуы мүмкін. Біздің пайдаланушылар бірегей сұраулар үшін жоғары жылдамдықты іздеуді бағалайды, бірақ мұндай сұраулар салыстырмалы түрде сирек жасалады. Әдеттегі іздеу сұраулары үшін, мысалы, бақылау тақтасы үшін біз арнайы әдістерді қолданамыз (біз оларды келесі мақалада сипаттайтын боламыз). Басқа сұраулар сирек кездеседі, сондықтан бір уақытта бірден көп өңдеуге тура келеді. Бірақ бұл біздің серверлер бос емес дегенді білдірмейді: олар жаңа хабарламаларды қабылдау, талдау және қысу, ескертулерді бағалау, ескі деректерді қысу және т.б. жұмысымен айналысады. Осылайша, бізде сұраныстарды орындау үшін пайдалануға болатын процессорлардың айтарлықтай жеткілікті қоры бар.

Егер сізде өрескел проблема (және көп күш) болса, қатал күш жұмыс істейді.

Дөрекі күш шағын ішкі ілмектері бар қарапайым мәселелерде жақсы жұмыс істейді. Көбінесе сіз өте жоғары жылдамдықта жұмыс істеу үшін ішкі циклды оңтайландыра аласыз. Егер код күрделі болса, оны оңтайландыру әлдеқайда қиын.

Біздің іздеу кодымызда бастапқыда айтарлықтай үлкен ішкі цикл болды. Біз хабарламаларды 4K форматында беттерде сақтаймыз; әрбір бетте кейбір хабарламалар (UTF-8) және әрбір хабарламаға арналған метадеректер бар. Метадеректер – мәннің ұзындығын, ішкі хабар идентификаторын және басқа өрістерді кодтайтын құрылым. Іздеу циклі келесідей болды:

1 ТБ/с жылдамдықпен іздеу

Бұл нақты кодтың жеңілдетілген нұсқасы. Бірақ мұнда да бірнеше нысанды орналастыру, деректер көшірмелері және функция шақырулары көрінеді. JVM функционалдық шақыруларды оңтайландыруда және эфемерлі нысандарды бөлуде өте жақсы, сондықтан бұл код біз лайық болғаннан жақсы жұмыс істеді. Тестілеу кезінде тұтынушылар оны сәтті қолданды. Бірақ соңында біз оны келесі деңгейге көтердік.

(Сіз неге хабарларды журналдармен тікелей жұмыс істемей, 4K беттерімен, мәтінімен және метадеректерімен осы форматта сақтайтынымызды сұрай аласыз. Көптеген себептер бар, олардың ішінде Scalyr қозғалтқышы бөлінген дерекқорға қарағанда көбірек ұқсайды. файлдық жүйе.Мәтінді іздеу журналды талдаудан кейін жиі шеттерде ДҚБЖ стиліндегі сүзгілермен біріктіріледі. Біз бір уақытта мыңдаған журналдарды іздей аламыз және қарапайым мәтіндік файлдар транзакциялық, репликацияланған, таратылған деректерді басқаруға жарамайды).

Бастапқыда мұндай код дөрекі күштерді оңтайландыру үшін өте қолайлы емес сияқты көрінді. «Нағыз жұмыс». String.indexOf() тіпті процессор профиліне үстемдік етпеді. Яғни, бұл әдісті оңтайландырудың өзі айтарлықтай нәтиже бермейді.

Осылайша, біз метадеректерді әр беттің басында сақтаймыз, ал UTF-8 ішіндегі барлық хабарлардың мәтіні екінші жағында жинақталған. Осы мүмкіндікті пайдаланып, біз бүкіл бетті бірден іздеу үшін циклды қайта жаздық:

1 ТБ/с жылдамдықпен іздеу

Бұл нұсқа тікелей көріністе жұмыс істейді raw byte[] және бүкіл 4K бетінде барлық хабарларды бірден іздейді.

Бұл қатал күш әдісі үшін оңтайландыру әлдеқайда оңай. Ішкі іздеу циклі әр жазбада бөлек емес, бүкіл 4K беті үшін бір уақытта шақырылады. Деректерді көшіру, объектілерді бөлу жоқ. Ал күрделі метадеректер операциялары әрбір хабарламада емес, нәтиже оң болғанда ғана шақырылады. Осылайша, біз бір тонна үстеме шығындарды алып тастадық, ал жүктің қалған бөлігі әрі қарай оңтайландыру үшін өте қолайлы шағын ішкі іздеу циклінде шоғырланған.

Біздің нақты іздеу алгоритмі негізделген Леонид Вольницкийдің тамаша идеясы. Ол Бойер-Мур алгоритміне ұқсас, әр қадамда іздеу жолының ұзындығын шамамен өткізіп жібереді. Негізгі айырмашылығы, ол жалған сәйкестіктерді азайту үшін бір уақытта екі байтты тексереді.

Біздің енгізуіміз әрбір іздеу үшін 64K іздеу кестесін жасауды талап етеді, бірақ бұл біз іздеп жатқан гигабайт деректермен салыстырғанда ештеңе емес. Ішкі цикл бір ядрода секундына бірнеше гигабайтты өңдейді. Іс жүзінде тұрақты өнімділік әрбір ядрода секундына шамамен 1,25 ГБ құрайды және жақсартуға мүмкіндік бар. Ішкі циклдің сыртындағы үстеме шығындардың бір бөлігін жоюға болады және біз Java-ның орнына C-дегі ішкі циклмен тәжірибе жасауды жоспарлап отырмыз.

Біз күш қолданамыз

Біз журналды іздеуді «шамамен» жүзеге асыруға болатынын талқыладық, бірақ бізде қаншалықты «қуат» бар? Біршама.

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% 111 миллисекунд ішінде орындалды (егер сіз журналды талдау құралдарын пайдаланбаған болсаңыз, маған сеніңіз: бұл тез).

Қызметті пайдаланудың қарапайымдылығы үшін тұрақты, сенімді өнімділік маңызды. Егер ол мерзімді түрде артта қалса, пайдаланушылар оны сенімсіз деп қабылдайды және оны пайдаланғысы келмейді.

Жүйеге іздеу әрекеті

Мұнда Scalyr іздеу әрекетін көрсететін қысқа анимация берілген. Бізде демонстрациялық тіркелгіміз бар, біз әрбір жалпы Github репозиторийіндегі әрбір оқиғаны импорттаймыз. Бұл демонстрацияда мен бір апталық деректерді тексеремін: шамамен 600 МБ өңделмеген журналдар.

Бейне менің жұмыс үстелімде (серверден шамамен 5000 шақырым жерде) арнайы дайындықсыз тікелей эфирде түсірілді. Сіз көретін өнімділік негізінен осыған байланысты веб-клиентті оңтайландыру, сонымен қатар жылдам және сенімді сервер. «Жүктеу» индикаторы жоқ үзіліс болған кезде, мен басайын деп тұрғанымды оқуыңыз үшін кідіртемін.

1 ТБ/с жылдамдықпен іздеу

Қорытындылай келе

Деректердің үлкен көлемін өңдеу кезінде жақсы алгоритмді таңдау маңызды, бірақ «жақсы» «сәнді» дегенді білдірмейді. Сіздің кодыңыз іс жүзінде қалай жұмыс істейтіні туралы ойланыңыз. Алгоритмдердің теориялық талдауы нақты әлемде маңызды болуы мүмкін кейбір факторларды қалдырады. Қарапайым алгоритмдерді оңтайландыру оңай және шеткі жағдайларда тұрақтырақ.

Сондай-ақ, код орындалатын контекст туралы ойланыңыз. Біздің жағдайда фондық тапсырмаларды басқару үшін жеткілікті қуатты серверлер қажет. Пайдаланушылар іздеуді салыстырмалы түрде сирек бастайды, сондықтан біз әрбір іздеуді аяқтау үшін қажет қысқа мерзімге бүкіл серверлер тобын қарызға аламыз.

Қатал күш әдісін қолдана отырып, біз журналдар жиынтығы бойынша жылдам, сенімді, икемді іздеуді жүзеге асырдық. Бұл идеялар сіздің жобаларыңыз үшін пайдалы болады деп үміттенеміз.

Өңдеу: Тақырып пен мәтін соңғы бірнеше жылдағы өнімділіктің жоғарылауын көрсету үшін "Секундына 20 ГБ іздеу" орнынан "Секундына 1 ТБ іздеу" болып өзгертілді. Жылдамдықтың бұл ұлғаюы, ең алдымен, біздің ұлғайған тұтынушы базамызға қызмет көрсету үшін біз бүгін салып жатқан EC2 серверлерінің түрі мен санының өзгеруіне байланысты. Жақында операциялық тиімділіктің тағы бір күрт өсуін қамтамасыз ететін өзгерістер болады және біз оларды бөлісуді күте алмаймыз.

Ақпарат көзі: www.habr.com

пікір қалдыру