1 TB/s sürətlə axtarın

TL; DR: Dörd il əvvəl mən yeni server monitorinq aləti ideyası ilə Google-dan ayrıldım. İdeya adətən təcrid olunmuş funksiyaları bir xidmətdə birləşdirmək idi toplamaq və log təhlili, metriklərin toplanması, xəbərdarlıqlar və idarə panelləri. Prinsiplərdən biri budur ki, xidmət həqiqətən olmalıdır sürətli, devoplara asan, interaktiv, xoş təcrübə təqdim edir. Bunun üçün büdcə daxilində qalarkən çox giqabaytlıq məlumat dəstlərinin saniyənin fraksiyalarında emal edilməsi tələb olunur. Mövcud jurnal idarəetmə alətləri çox vaxt yavaş və çətin olur, buna görə də biz yaxşı problemlə üzləşdik: istifadəçilərə yeni təcrübə vermək üçün aləti ağıllı şəkildə dizayn etmək.

Bu məqalə Scalyr-də köhnə məktəb metodlarını, kobud güc yanaşmasını tətbiq etməklə, lazımsız təbəqələri aradan qaldıraraq və mürəkkəb məlumat strukturlarından qaçaraq bu problemi necə həll etdiyimizi təsvir edir. Bu dərsləri öz mühəndislik problemlərinizə tətbiq edə bilərsiniz.

Köhnə Məktəb Gücü

Qeydiyyatın təhlili adətən axtarışla başlayır: müəyyən nümunəyə uyğun gələn bütün mesajları tapın. Scalyr-də bunlar bir çox serverdən onlarla və ya yüzlərlə gigabaytlıq loglardır. Müasir yanaşmalar, bir qayda olaraq, axtarış üçün optimallaşdırılmış bəzi mürəkkəb verilənlər strukturunun qurulmasını nəzərdə tutur. Mən, şübhəsiz ki, bunu Google-da görmüşəm, burada onlar bu cür işlərdə olduqca yaxşıdırlar. Lakin biz daha kobud bir yanaşma üzərində qərarlaşdıq: logların xətti skan edilməsi. Və bu işə yaradı - biz rəqiblərimizdən daha sürətli axtarış edilə bilən interfeys təqdim edirik (sonda animasiyaya baxın).

Əsas fikir ondan ibarət idi ki, müasir prosessorlar həqiqətən də sadə, sadə əməliyyatlarda çox sürətlidir. Giriş/çıxış sürətinə və şəbəkə əməliyyatlarına əsaslanan mürəkkəb, çox qatlı sistemlərdə bunu qaçırmaq asandır və bu cür sistemlər bu gün çox yayılmışdır. Beləliklə, biz təbəqələri və artıq zibilləri minimuma endirən dizayn hazırladıq. Paralel bir neçə prosessor və server ilə axtarış sürəti saniyədə 1 TB-ə çatır.

Bu məqalədən əsas çıxışlar:

  • Qəddar qüvvə axtarışı real dünyadakı genişmiqyaslı problemlərin həlli üçün əlverişli bir yanaşmadır.
  • Brute force dizayn texnikasıdır, işsiz bir həll deyil. Hər hansı bir texnika kimi, bəzi problemlərə digərlərindən daha uyğundur və zəif və ya yaxşı həyata keçirilə bilər.
  • Qəddar qüvvə nail olmaq üçün xüsusilə yaxşıdır sabit məhsuldarlıq.
  • Kobud gücdən səmərəli istifadə kodun optimallaşdırılmasını və lazımi anda kifayət qədər resursların tətbiqini tələb edir. Serverləriniz ağır qeyri-istifadəçi yükü altındadırsa və istifadəçi əməliyyatları prioritet olaraq qalırsa uyğundur.
  • Performans yalnız daxili döngə alqoritmindən deyil, bütün sistemin dizaynından asılıdır.

(Bu məqalə yaddaşda verilənlərin axtarışını təsvir edir. Əksər hallarda istifadəçi log axtarışı həyata keçirdikdə, Scalyr serverləri artıq onu keşləyiblər. Növbəti məqalədə keşlənməmiş jurnalların axtarışı müzakirə olunacaq. Eyni prinsiplər tətbiq olunur: səmərəli kod, kobud güc böyük hesablama resursları ilə).

Qəddar qüvvə üsulu

Ənənəvi olaraq, böyük bir məlumat dəsti açar söz indeksindən istifadə edərək axtarılır. Server qeydlərinə tətbiq edildikdə, bu, jurnalda hər bir unikal sözü axtarmaq deməkdir. Hər bir söz üçün bütün daxiletmələrin siyahısını tərtib etməlisiniz. Bu, bu sözlə bütün mesajları tapmağı asanlaşdırır, məsələn, "xəta", "firefox" və ya "transaction_16851951" - sadəcə indeksə baxın.

Mən Google-da bu yanaşmadan istifadə etdim və yaxşı işlədi. Lakin Scalyr-də logları bayt-bayt axtarırıq.

Niyə? Mücərrəd alqoritmik nöqteyi-nəzərdən açar söz indeksləri kobud güc axtarışlarından qat-qat səmərəlidir. Bununla belə, biz alqoritmləri satmırıq, performans satırıq. Performans yalnız alqoritmlərə deyil, həm də sistem mühəndisliyinə aiddir. Biz hər şeyi nəzərə almalıyıq: məlumatların həcmi, axtarış növü, mövcud avadanlıq və proqram konteksti. Biz qərara gəldik ki, bizim xüsusi problemimiz üçün 'grep' kimi bir şey indeksdən daha uyğundur.

İndekslər əladır, lakin məhdudiyyətləri var. Bir söz tapmaq asandır. Lakin 'googlebot' və '404' kimi bir neçə sözdən ibarət mesajları axtarmaq daha çətindir. "Yaxalanmamış istisna" kimi bir ifadənin axtarışı yalnız bu sözlə olan bütün mesajları deyil, həm də sözün xüsusi yerini qeyd edən daha çətin indeks tələb edir.

Əsl çətinlik söz axtarmadıqda gəlir. Deyək ki, siz botlardan nə qədər trafik gəldiyini görmək istəyirsiniz. İlk fikir loglarda 'bot' sözünü axtarmaqdır. Bəzi botları belə tapacaqsınız: Googlebot, Bingbot və bir çox başqaları. Amma burada “bot” söz deyil, onun bir hissəsidir. İndeksdə 'bot' üçün axtarış etsək, 'Googlebot' sözü ilə heç bir yazı tapa bilməyəcəyik. İndeksdəki hər sözü yoxlasanız və sonra tapılan açar sözlər üçün indeksi skan etsəniz, axtarış çox yavaşlayacaq. Nəticədə, bəzi log proqramları hissə-söz axtarışlarına icazə vermir və ya (ən yaxşı halda) daha aşağı performanslı xüsusi sintaksisə icazə verir. Biz bunun qarşısını almaq istəyirik.

Digər problem durğu işarələridir. Bütün sorğuları tapmaq istəyirsiniz 50.168.29.7? Tərkibində olan qeydlərin sazlanması haqqında nə demək olar [error]? Subscripts adətən durğu işarələrini atlayır.

Nəhayət, mühəndislər güclü alətləri sevirlər və bəzən problem yalnız müntəzəm ifadə ilə həll edilə bilər. Açar söz indeksi bunun üçün çox uyğun deyil.

Bundan əlavə, indekslər kompleks. Hər bir mesaj bir neçə açar söz siyahısına əlavə edilməlidir. Bu siyahılar hər zaman asanlıqla axtarılan formatda saxlanmalıdır. İfadələr, söz fraqmentləri və ya müntəzəm ifadələr olan sorğular çox siyahı əməliyyatlarına çevrilməlidir və nəticələr skan edilməli və nəticə dəsti yaratmaq üçün birləşdirilməlidir. Genişmiqyaslı, çox kirayəçili xidmət kontekstində bu mürəkkəblik alqoritmləri təhlil edərkən görünməyən performans problemləri yaradır.

Açar söz indeksləri də çox yer tutur və saxlama log idarəetmə sistemində əsas xərcdir.

Digər tərəfdən, hər bir axtarış çoxlu hesablama gücü sərf edə bilər. İstifadəçilərimiz unikal sorğular üçün yüksək sürətli axtarışları yüksək qiymətləndirirlər, lakin belə sorğular nisbətən nadir hallarda edilir. Tipik axtarış sorğuları üçün, məsələn, tablosuna görə, biz xüsusi üsullardan istifadə edirik (onları növbəti məqalədə təsvir edəcəyik). Digər sorğular kifayət qədər nadirdir ki, siz nadir hallarda birdən çox müraciət etməlisiniz. Amma bu o demək deyil ki, bizim serverlərimiz məşğul deyil: onlar yeni mesajların qəbulu, təhlili və sıxılması, xəbərdarlıqların qiymətləndirilməsi, köhnə məlumatların sıxılması və s. işləri ilə məşğuldurlar. Beləliklə, sorğuları yerinə yetirmək üçün istifadə edilə bilən kifayət qədər əhəmiyyətli prosessor ehtiyatımız var.

Kobud bir probleminiz (və çoxlu güc) varsa, kobud güc işləyir

Qəddar qüvvə kiçik daxili döngələri olan sadə problemlərdə yaxşı işləyir. Çox vaxt daxili döngəni çox yüksək sürətlə işləmək üçün optimallaşdıra bilərsiniz. Kod mürəkkəbdirsə, onu optimallaşdırmaq daha çətindir.

Axtarış kodumuz əvvəlcə kifayət qədər böyük daxili döngəyə malik idi. Mesajları 4K-da səhifələrdə saxlayırıq; hər səhifədə bəzi mesajlar (UTF-8-də) və hər mesaj üçün metadata var. Metadata dəyərin uzunluğunu, daxili mesaj identifikatorunu və digər sahələri kodlayan strukturdur. Axtarış dövrü belə görünürdü:

1 TB/s sürətlə axtarın

Bu faktiki kodun sadələşdirilmiş versiyasıdır. Ancaq burada da çoxlu obyekt yerləşdirmələri, məlumat nüsxələri və funksiya çağırışları görünür. JVM funksiya çağırışlarını optimallaşdırmaqda və efemer obyektləri ayırmaqda olduqca yaxşıdır, ona görə də bu kod layiq olduğumuzdan daha yaxşı işlədi. Test zamanı müştərilər ondan kifayət qədər uğurla istifadə etdilər. Amma sonda onu növbəti səviyyəyə qaldırdıq.

(Siz soruşa bilərsiniz ki, niyə biz mesajları birbaşa qeydlərlə işləməkdənsə, 4K səhifələr, mətn və metadata ilə bu formatda saxlayırıq. Bir çox səbəblər var ki, daxili olaraq Scalyr mühərriki daha çox paylanmış verilənlər bazasına bənzəyir. fayl sistemi.Mətn axtarışı tez-tez jurnalın təhlilindən sonra kənarlarda DBMS tipli filtrlərlə birləşdirilir. Biz eyni vaxtda minlərlə jurnalı axtara bilərik və sadə mətn faylları bizim əməliyyat, təkrarlanan, paylanmış məlumatların idarə edilməsi üçün uyğun deyil).

Başlanğıcda belə kodun kobud gücün optimallaşdırılması üçün çox uyğun olmadığı görünürdü. "Əsl iş" String.indexOf() CPU profilinə belə hakim deyildi. Yəni, bu üsulu təkbaşına optimallaşdırmaq ciddi effekt verməyəcək.

Elə olur ki, biz metadatanı hər səhifənin əvvəlində saxlayırıq və UTF-8-də bütün mesajların mətni digər ucunda yığılır. Bundan istifadə edərək, bütün səhifəni bir anda axtarmaq üçün döngəni yenidən yazdıq:

1 TB/s sürətlə axtarın

Bu versiya birbaşa görünüş üzərində işləyir raw byte[] və bütün mesajları eyni anda bütün 4K səhifəsində axtarır.

Bu kobud qüvvə metodu üçün optimallaşdırmaq daha asandır. Daxili axtarış loopu hər yazıda ayrıca deyil, bütün 4K səhifəsi üçün eyni vaxtda çağırılır. Məlumatların kopyalanması, obyektlərin ayrılması yoxdur. Və daha mürəkkəb metadata əməliyyatları yalnız nəticə müsbət olduqda çağırılır, hər mesajda deyil. Bu yolla biz bir ton yerüstü yükü aradan qaldırdıq və yükün qalan hissəsi daha da optimallaşdırma üçün yaxşı uyğun gələn kiçik daxili axtarış dövrəsində cəmləşdi.

Bizim faktiki axtarış alqoritmimiz əsaslanır Leonid Volnitskinin böyük ideyası. Bu, Boyer-Moore alqoritminə bənzəyir, hər addımda axtarış sətirinin təxminən uzunluğunu atlayır. Əsas fərq odur ki, o, yanlış uyğunluqları minimuma endirmək üçün eyni anda iki baytı yoxlayır.

Tətbiqimiz hər axtarış üçün 64K axtarış cədvəli yaratmağı tələb edir, lakin bu, axtardığımız gigabayt data ilə müqayisədə heç nə deyil. Daxili dövrə bir nüvədə saniyədə bir neçə giqabaytı emal edir. Praktikada sabit performans hər nüvədə saniyədə təxminən 1,25 GB təşkil edir və təkmilləşdirmə üçün yer var. Daxili döngə xaricində olan yuxarı yükün bir hissəsini aradan qaldırmaq mümkündür və biz Java əvəzinə C-də daxili döngə ilə sınaq keçirməyi planlaşdırırıq.

Biz güc tətbiq edirik

Biz müzakirə etdik ki, log axtarışı "təxminən" həyata keçirilə bilər, lakin bizim nə qədər "gücümüz" var? Olduqca çox.

1 nüvə: Düzgün istifadə edildikdə, müasir prosessorun tək nüvəsi özlüyündə kifayət qədər güclüdür.

8 nüvə: Hazırda biz Amazon hi1.4xlarge və i2.4xlarge SSD serverlərində işləyirik, hər biri 8 nüvəli (16 iplik). Yuxarıda qeyd edildiyi kimi, bu nüvələr adətən fon əməliyyatları ilə məşğul olur. İstifadəçi axtarış həyata keçirdikdə, fon əməliyyatları dayandırılır və axtarış üçün bütün 8 nüvə boşaldılır. Axtarış adətən bir saniyə ərzində tamamlanır, bundan sonra arxa plan işi bərpa olunur (azaltma proqramı axtarış sorğularının tıxanmasının vacib fon işinə mane olmamasını təmin edir).

16 nüvə: etibarlılıq üçün biz serverləri master/slave qruplarına təşkil edirik. Hər ustanın əmri altında bir SSD və bir EBS serveri var. Əsas server çökərsə, SSD server dərhal yerini alır. Demək olar ki, hər zaman master və slave yaxşı işləyir ki, hər bir məlumat bloku iki fərqli serverdə axtarıla bilər (EBS slave serverində zəif prosessor var, ona görə də biz bunu nəzərə almırıq). Tapşırığı onlar arasında bölürük ki, cəmi 16 nüvəmiz olsun.

Çoxlu nüvələr: Yaxın gələcəkdə biz məlumatları serverlər arasında elə paylayacağıq ki, onlar hamısı hər bir əhəmiyyətsiz sorğunun emalında iştirak etsinlər. Hər bir nüvə işləyəcək. [Qeyd: planı həyata keçirdik və axtarış sürətini 1 TB/s-ə qədər artırdıq, məqalənin sonundakı qeydə baxın].

Sadəlik etibarlılığı təmin edir

Kobud güc metodunun başqa bir üstünlüyü onun kifayət qədər ardıcıl performansıdır. Tipik olaraq, axtarış problemin təfərrüatlarına və məlumat dəstinə o qədər də həssas deyildir (təxmin edirəm ki, buna görə "kobud" adlanır).

Açar söz indeksi bəzən inanılmaz dərəcədə sürətli nəticələr verir, digər vaxtlar isə yox. Tutaq ki, sizin 50 GB-lıq qeydləriniz var, orada 'customer_5987235982' termini tam üç dəfə görünür. Bu termin üçün axtarış birbaşa indeksdən üç yeri hesablayır və dərhal tamamlanacaq. Lakin mürəkkəb joker xarakterli axtarışlar minlərlə açar sözü skan edə və uzun müddət çəkə bilər.

Digər tərəfdən, kobud güc axtarışları istənilən sorğu üçün az-çox eyni sürətlə həyata keçirilir. Uzun sözləri axtarmaq daha yaxşıdır, lakin hətta tək bir simvolu axtarmaq kifayət qədər sürətlidir.

Kobud qüvvə metodunun sadəliyi onun performansının nəzəri maksimuma yaxın olması deməkdir. Gözlənilməz disk yüklənməsi, kilid mübahisəsi, göstərici təqibi və uğursuzluğun minlərlə digər səbəbləri üçün daha az seçim var. Keçən həftə ən işlək serverimizdə Scalyr istifadəçiləri tərəfindən edilən sorğulara baxdım. 14 min müraciət olub. Onlardan düz səkkizi bir saniyədən çox çəkdi; 000% 99 millisaniyə ərzində tamamlandı (əgər log analiz alətlərindən istifadə etməmisinizsə, mənə etibar edin: sürətlidir).

Xidmətdən istifadənin asanlığı üçün stabil, etibarlı performans vacibdir. Əgər vaxtaşırı geri qalırsa, istifadəçilər onu etibarsız kimi qəbul edəcək və ondan istifadə etməkdən çəkinəcəklər.

Axtarışa daxil olun

Budur, Scalyr axtarışını hərəkətdə göstərən qısa animasiya. Hər bir ictimai Github deposunda hər hadisəni idxal etdiyimiz demo hesabımız var. Bu demoda mən bir həftəlik məlumatları araşdırıram: təxminən 600 MB xam qeydlər.

Video canlı olaraq, xüsusi hazırlıq olmadan, masaüstümdə (serverdən təxminən 5000 kilometr aralıda) qeydə alınıb. Görəcəyiniz performans əsasən buna bağlıdır veb müştəri optimallaşdırılması, həmçinin sürətli və etibarlı backend. "Yükləmə" indikatoru olmayan hər hansı bir fasilə yarandıqda, mən dayanıram ki, basmaq üzrə olduğumu oxuyasınız.

1 TB/s sürətlə axtarın

Nəticədə

Böyük həcmdə verilənləri emal edərkən yaxşı alqoritm seçmək vacibdir, lakin “yaxşı” “xülya” demək deyil. Kodunuzun praktikada necə işləyəcəyini düşünün. Alqoritmlərin nəzəri təhlili real dünyada böyük əhəmiyyət kəsb edə biləcək bəzi amilləri kənarda qoyur. Sadə alqoritmləri optimallaşdırmaq daha asandır və kənar vəziyyətlərdə daha sabitdir.

Kodun icra olunacağı kontekst haqqında da düşünün. Bizim vəziyyətimizdə fon tapşırıqlarını idarə etmək üçün kifayət qədər güclü serverlərə ehtiyacımız var. İstifadəçilər nisbətən nadir hallarda axtarışlara başlayırlar, ona görə də biz hər bir axtarışı tamamlamaq üçün lazım olan qısa müddətə bütün serverlər qrupunu borc ala bilərik.

Kobud güc metodundan istifadə edərək, bir sıra qeydlər arasında sürətli, etibarlı, çevik axtarış həyata keçirdik. Ümid edirik ki, bu ideyalar layihələriniz üçün faydalı olacaqdır.

Redaktə edin: Son bir neçə il ərzində performans artımını əks etdirmək üçün başlıq və mətn "Saniyədə 20 GB-da axtarış"dan "Saniyədə 1 TB-də axtarış"-a dəyişdirilib. Sürətdəki bu artım, ilk növbədə, artan müştəri bazamıza xidmət etmək üçün bu gün hazırladığımız EC2 serverlərinin növü və sayındakı dəyişikliklərlə bağlıdır. Tezliklə əməliyyat səmərəliliyində daha bir dramatik təkan verəcək dəyişikliklər olacaq və biz onları paylaşmaq üçün səbirsizlənirik.

Mənbə: www.habr.com

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