Badoo-da biz daim yeni texnologiyalara nəzarət edirik və onlardan sistemimizdə istifadə edib-etməməyi qiymətləndiririk. Bu araşdırmalardan birini cəmiyyətlə bölüşmək istəyirik. O, log toplama sistemi olan Loki-yə həsr olunub.
Loki qeydlərin saxlanması və baxılması üçün bir həlldir və bu yığın həmçinin onları təhlil etmək və məlumatları Prometeyə göndərmək üçün çevik bir sistem təqdim edir. May ayında yaradıcılar tərəfindən fəal şəkildə təbliğ olunan başqa bir yeniləmə buraxıldı. Loki-nin nə edə biləcəyi, hansı xüsusiyyətləri təmin etdiyi və hazırda istifadə etdiyimiz yığın olan ELK-a nə dərəcədə alternativ kimi çıxış edə biləcəyi ilə maraqlandıq.
Loki nədir
Grafana Loki tam giriş sistemi üçün komponentlər toplusudur. Digər oxşar sistemlərdən fərqli olaraq, Loki yalnız log metadatasının - etiketlərin indeksləşdirilməsi (eynilə Prometeydəki kimi) və logların yan-yana ayrı-ayrı parçalara sıxılması ideyasına əsaslanır.
Loki ilə nə edə biləcəyinizə keçməzdən əvvəl, "yalnız metadatanın indeksləşdirilməsi ideyası" ilə nə nəzərdə tutulduğunu aydınlaşdırmaq istəyirəm. Nginx jurnalından bir xətt nümunəsindən istifadə edərək, Loki yanaşmasını və Elasticsearch kimi ənənəvi həllərdəki indeksləşdirmə yanaşmasını müqayisə edək:
Ənənəvi sistemlər çoxlu unikal user_id və item_id dəyərlərinə malik sahələr daxil olmaqla bütün sıranı təhlil edir və hər şeyi böyük indekslərdə saxlayır. Bu yanaşmanın üstünlüyü ondan ibarətdir ki, siz mürəkkəb sorğuları tez yerinə yetirə bilərsiniz, çünki məlumatların demək olar ki, hamısı indeksdədir. Ancaq bunun üçün ödəməlisiniz, çünki indeks böyüyür, bu da yaddaş tələblərinə çevrilir. Nəticədə, jurnalların tam mətn indeksi jurnalların özləri ilə ölçüdə müqayisə edilə bilər. Onu tez axtarmaq üçün indeks yaddaşa yüklənməlidir. Və daha çox jurnal, indeks daha sürətli artır və daha çox yaddaş istehlak edir.
Loki yanaşması, dəyərlərinin sayı az olan sətirdən yalnız zəruri məlumatların çıxarılmasını tələb edir. Bu yolla biz kiçik bir indeks əldə edirik və məlumatları vaxt və indekslənmiş sahələr üzrə süzgəcdən keçirərək, sonra qalanları müntəzəm ifadələr və ya alt sətir axtarışları ilə skan edərək axtarış edə bilərik. Proses ən sürətli görünmür, lakin Loki sorğunu bir neçə hissəyə bölür və onları paralel olaraq yerinə yetirir, qısa müddətdə böyük həcmdə məlumatı emal edir. Onlardakı qırıqların və paralel sorğuların sayı konfiqurasiya edilə bilər; beləliklə, zaman vahidi üçün emal oluna bilən məlumatların miqdarı verilən resursların miqdarından xətti asılıdır.
Böyük sürətli indeks və kiçik paralel brute-force indeksi arasındakı bu mübadilə Loki-yə sistemin dəyərinə nəzarət etməyə imkan verir. O, ehtiyaclarınıza uyğun olaraq çevik şəkildə konfiqurasiya edilə və genişləndirilə bilər.
Loki yığını üç komponentdən ibarətdir: Promtail, Loki, Grafana. Promtail jurnalları toplayır, onları emal edir və Loki-yə göndərir. Loki onları saxlayır. Və Grafana Loki-dən məlumat tələb edə və göstərə bilər. Ümumiyyətlə, Loki yalnız qeydləri saxlamaq və onlar vasitəsilə axtarış etmək üçün istifadə edilə bilməz. Bütün yığın Prometheus üsulundan istifadə edərək daxil olan məlumatların işlənməsi və təhlili üçün böyük imkanlar təqdim edir.
Quraşdırma prosesinin təsviri tapa bilərsiniz burada.
Giriş Axtar
Siz xüsusi interfeys Grafana — Explorer-də qeydləri axtara bilərsiniz. Sorğular Prometheus tərəfindən istifadə olunan PromQL-ə çox oxşar olan LogQL dilindən istifadə edir. Prinsipcə, paylanmış grep kimi düşünülə bilər.
Axtarış interfeysi belə görünür:
Sorğunun özü iki hissədən ibarətdir: seçici və filtr. Seçici qeydlərə təyin edilmiş indeksləşdirilmiş metadata (etiketlər) üzrə axtarışdır və filtr selektor tərəfindən müəyyən edilmiş qeydləri süzgəcdən keçirən axtarış sətri və ya regexpdir. Verilmiş nümunədə: Buruq mötərizədə - seçici, sonra hər şey - filtr.
{image_name="nginx.promtail.test"} |= "index"
Loki-nin işləmə üsuluna görə siz seçici olmadan sorğu verə bilməzsiniz, lakin etiketlər özbaşına ümumiləşdirilə bilər.
Selektor əyri mötərizələrdəki dəyərin açar-dəyəridir. Siz =, != operatorlarından və ya normal ifadələrdən istifadə edərək seçiciləri birləşdirə və müxtəlif axtarış şərtlərini təyin edə bilərsiniz:
{instance=~"kafka-[23]",name!="kafka-dev"}
// Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev
Filtr seçici tərəfindən alınan bütün məlumatları süzgəcdən keçirəcək mətn və ya regexpdir.
Metriklər rejimində alınan məlumatlar əsasında ad-hoc qrafiklər əldə etmək mümkündür. Məsələn, indeks sətirini ehtiva edən girişin nginx qeydlərində baş vermə tezliyini öyrənə bilərsiniz:
Xüsusiyyətlərin tam təsviri sənədlərdə tapıla bilər LogQL.
Girişin təhlili
Günlükləri toplamağın bir neçə yolu var:
Promtail-in köməyi ilə, logların toplanması üçün yığının standart komponenti.
Loki-yə məlumat göndərə bilən Fluentd və ya Fluent Bit istifadə edin. Promtail-dən fərqli olaraq, onlar demək olar ki, hər növ log üçün hazır təhliledicilərə malikdirlər və çoxsətirli qeydləri də idarə edə bilirlər.
Promtail adətən təhlil üçün istifadə olunur. Üç şeyi edir:
Məlumat mənbələrini tapır.
Onlara etiketlər yapışdırın.
Loki-yə məlumat göndərir.
Hal-hazırda Promtail yerli fayllardan və sistem jurnalından qeydləri oxuya bilər. O, logların toplandığı hər bir maşında quraşdırılmalıdır.
Kubernetes ilə inteqrasiya var: Promtail Kubernetes REST API vasitəsilə avtomatik olaraq klasterin vəziyyətini öyrənir və qovşaqdan, xidmətdən və ya poddan qeydləri toplayır, dərhal Kubernetes-dən metadata (pod adı, fayl adı və s.) əsasında etiketlər yerləşdirir.
Siz həmçinin Boru Kəmərindən istifadə edərək jurnaldakı məlumatlar əsasında etiketlər asa bilərsiniz. Pipeline Promtail dörd növ mərhələdən ibarət ola bilər. Daha ətraflı - daxil rəsmi sənədlər, Mən dərhal bəzi nüansları qeyd edəcəm.
Təhlil mərhələləri. Bu RegEx və JSON mərhələsidir. Bu mərhələdə biz məlumatları qeydlərdən çıxarılan xəritəyə çıxarırıq. Siz sadəcə olaraq bizə lazım olan sahələri çıxarılmış xəritəyə köçürməklə və ya adlandırılmış qrupların çıxarılan xəritəyə “xəritələndiyi” müntəzəm ifadələr (RegEx) vasitəsilə JSON-dan çıxara bilərsiniz. Çıxarılan xəritə açar-dəyər yaddaşıdır, burada açar sahənin adıdır, dəyər isə jurnallardan onun dəyəridir.
Transformasiya mərhələləri. Bu mərhələdə iki seçim var: transformasiya qaydalarını təyin etdiyimiz transform və mənbə - çıxarılan xəritədən transformasiya üçün məlumat mənbəyi. Çıxarılan xəritədə belə bir sahə yoxdursa, o zaman yaradılacaq. Beləliklə, çıxarılan xəritəyə əsaslanmayan etiketlər yaratmaq mümkündür. Bu mərhələdə, biz kifayət qədər güclü istifadə edərək, çıxarılan xəritədəki məlumatları manipulyasiya edə bilərik golang şablonu. Bundan əlavə, yadda saxlamalıyıq ki, çıxarılan xəritə təhlil zamanı tam yüklənir və bu, məsələn, içindəki dəyəri yoxlamağa imkan verir: “{{if .tag}teq dəyəri varsa{end}}”. Şablon şərtləri, döngələri və Dəyişdir və Kəsmə kimi bəzi sətir funksiyalarını dəstəkləyir.
Fəaliyyət mərhələləri. Bu mərhələdə, çıxarılan ilə bir şey edə bilərsiniz:
Çıxarılan məlumatdan Loki tərəfindən indekslənəcək etiket yaradın.
Günlükdən hadisə vaxtını dəyişdirin və ya təyin edin.
Filtrləmə mərhələləri. /dev/null-a ehtiyacımız olmayan qeydləri göndərə biləcəyimiz və ya sonrakı emal üçün göndərə biləcəyimiz uyğunluq mərhələsi.
Adi nginx qeydlərinin işlənməsi nümunəsindən istifadə edərək, Promtail istifadə edərək logları necə təhlil edə biləcəyinizi göstərəcəyəm.
Test üçün nginx-proxy kimi dəyişdirilmiş nginx şəklini götürək jwilder/nginx-proxy:alpine və HTTP vasitəsilə özünü sorğulaya bilən kiçik bir daemon. Demonun müxtəlif ölçülü, fərqli HTTP statusları və müxtəlif gecikmələrlə cavab verə biləcəyi bir neçə son nöqtəsi var.
Biz /var/lib/docker/containers/ yolunda tapıla bilən doker konteynerlərindən qeydləri toplayacağıq. / -json.log
Docker-compose.yml-də biz Promtail-i quraşdırırıq və konfiqurasiya yolunu təyin edirik:
Promtail.yml-ə loglara yolu əlavə edin (konfiqurasiyada eyni şeyi bir sətirdə edən "docker" seçimi var, lakin bu o qədər də aydın olmayacaq):
scrape_configs:
- job_name: containers
static_configs:
labels:
job: containerlogs
__path__: /var/lib/docker/containers/*/*log # for linux only
Bu konfiqurasiya aktiv edildikdə, Loki bütün konteynerlərdən qeydləri alacaq. Bunun qarşısını almaq üçün docker-compose.yml-də test nginx parametrlərini dəyişdiririk - qeyd sahəsinə giriş əlavə edin:
Image_name nginx.promtail.test-ə bərabər olan bütün loglar üçün biz log sahəsini mənbə jurnalından çıxarırıq və sıra düyməsi ilə çıxarılan xəritəyə qoyuruq.
Sorğu_url-ni təhlil edin. Regexp-in köməyi ilə sorğunun məqsədini müəyyənləşdiririk: statika, fotoşəkillərə, API-yə və çıxarılan xəritədə müvafiq açarı təyin edirik.
- template:
source: request_type
template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"
Şablonda şərti operatorlardan istifadə edərək, çıxarılan xəritədə quraşdırılmış sahələri yoxlayırıq və sorğu_tipi sahəsi üçün tələb olunan dəyərləri təyin edirik: şəkil, statik, API. Əgər uğursuz olarsa, digərini təyin edin. İndi request_type sorğu növünü ehtiva edir.
Çıxarılan xəritəyə qoya bildiklərimizə əsasən api_request, virtual_host, request_type və status (HTTP statusu) etiketlərini təyin etdik.
- output:
source: nginx_log_row
Çıxışı dəyişdirin. İndi çıxarılan xəritədən təmizlənmiş nginx jurnalı Loki-yə keçir.
Yuxarıdakı konfiqurasiyanı işə saldıqdan sonra hər bir girişin jurnaldakı məlumatlara əsasən etiketləndiyini görə bilərsiniz.
Unutmayın ki, çox sayda dəyərə (kardinallıq) malik etiketlərin çıxarılması Loki-ni əhəmiyyətli dərəcədə yavaşlata bilər. Yəni indeksə, məsələn, user_id daxil etməməlisiniz. Bu barədə daha çox məqalədə oxuyunLoki-dəki etiketlər jurnal sorğularını necə daha sürətli və asan edə bilər". Lakin bu o demək deyil ki, indekslər olmadan user_id ilə axtarış edə bilməyəcəksiniz. Axtarış zamanı filtrlərdən istifadə etmək lazımdır (“məlumatlara görə tutmaq”) və buradakı indeks axın identifikatoru kimi çıxış edir.
Girişin vizuallaşdırılması
Loki LogQL istifadə edərək Grafana diaqramları üçün məlumat mənbəyi kimi çıxış edə bilər. Aşağıdakı funksiyalar dəstəklənir:
dərəcəsi - saniyədə qeydlərin sayı;
zamanla saymaq - verilmiş diapazondakı qeydlərin sayı.
Həmçinin Sum, Avg və başqaları birləşdirən funksiyalar var. Siz olduqca mürəkkəb qrafiklər qura bilərsiniz, məsələn, HTTP səhvlərinin sayının qrafiki:
Loki-nin standart məlumat mənbəyi Prometheus məlumat mənbəyindən bir qədər az funksionaldır (məsələn, əfsanəni dəyişə bilməzsiniz), lakin Loki Prometheus tipli mənbə kimi qoşula bilər. Bunun sənədləşdirilmiş davranış olub-olmadığından əmin deyiləm, lakin tərtibatçıların cavabına əsasən "Loki-ni Prometheus məlumat mənbəyi kimi necə konfiqurasiya etmək olar? · Buraxılış #1222 · qrafana/loki”, məsələn, tamamilə qanunidir və Loki PromQL ilə tam uyğundur.
Prometheus növü ilə məlumat mənbəyi kimi Loki əlavə edin və URL /loki əlavə edin:
Prometeydən gələn metriklərlə işləyirmiş kimi qrafiklər yarada bilərsiniz:
Düşünürəm ki, funksionallıqdakı uyğunsuzluq müvəqqətidir və tərtibatçılar gələcəkdə onu düzəldəcəklər.
Metriklər
Loki jurnallardan ədədi ölçüləri çıxarmaq və onları Prometeyə göndərmək imkanı verir. Məsələn, nginx jurnalı hər cavab üçün baytların sayını, həmçinin standart log formatının müəyyən modifikasiyası ilə cavab vermək üçün lazım olan saniyələri ehtiva edir. Bu məlumatlar çıxarıla və Prometeyə göndərilə bilər.
Seçim, çıxarılan xəritədən verilənlər əsasında ölçüləri müəyyən etməyə və yeniləməyə imkan verir. Bu ölçülər Loki-yə göndərilmir - onlar Promtail /metrics son nöqtəsində görünür. Prometey bu mərhələdən məlumat almaq üçün konfiqurasiya edilməlidir. Yuxarıdakı misalda request_type="api" üçün biz histoqram metrikasını toplayırıq. Bu tip göstəricilərlə faizləri əldə etmək rahatdır. Statika və fotoşəkillər üçün baytların cəmini və bayt aldığımız sətirlərin sayını orta hesabla hesablayırıq.
Bu yolla, məsələn, dörd ən yavaş sorğunu tapa bilərsiniz. Siz həmçinin bu göstəricilər üçün monitorinqi konfiqurasiya edə bilərsiniz.
Ölçəkləmə
Loki həm tək ikili rejimdə, həm də parçalanmış rejimdə ola bilər (üfüqi miqyaslı rejim). İkinci halda, o, məlumatları buludda saxlaya bilər və parçalar və indekslər ayrıca saxlanılır. 1.5 versiyasında bir yerdə saxlamaq imkanı həyata keçirilir, lakin istehsalda istifadə etmək hələ tövsiyə edilmir.
Parçalar S3-ə uyğun yaddaşda saxlanıla bilər və indeksləri saxlamaq üçün üfüqi şəkildə miqyaslana bilən verilənlər bazalarından istifadə edilə bilər: Cassandra, BigTable və ya DynamoDB. Loki-nin digər hissələri - Distribyutorlar (yazmaq üçün) və Querier (sorğular üçün) - vətəndaşlığı olmayan və həmçinin üfüqi şəkildə miqyaslıdır.
Yaranan indeks ölçüsünü yoxlamaq üçün yuxarıdakı Boru Kəmərinin konfiqurasiya edildiyi nginx konteynerindən qeydlər götürdüm. Jurnal faylı ümumi həcmi 406 MB olan 624 sətirdən ibarət idi. Qeydlər bir saat ərzində, saniyədə təxminən 109 qeyd yaradıldı.
Günlükdən iki sətir nümunəsi:
ELK tərəfindən indeksləşdirildikdə, bu, 30,3 MB indeks ölçüsü verdi:
Loki vəziyyətində bu, təqribən 128 KB indeks və təxminən 3,8 MB məlumat verdi. Qeyd etmək lazımdır ki, jurnal süni şəkildə yaradılıb və geniş çeşidli məlumatlara malik deyildi. Orijinal Docker JSON jurnalında verilənlərlə sadə bir gzip 95,4% sıxılma verdi və yalnız təmizlənmiş nginx jurnalının Loki-nin özünə göndərildiyini nəzərə alsaq, 4 MB-a sıxılma başa düşüləndir. Loki etiketləri üçün unikal dəyərlərin ümumi sayı 35 idi ki, bu da indeksin kiçik ölçüsünü izah edir. ELK üçün jurnal da təmizləndi. Beləliklə, Loki orijinal məlumatları 96%, ELK isə 70% sıxışdırdı.
Yaddaş istehlakı
Prometey və ELK-nın bütün yığınını müqayisə etsək, Loki bir neçə dəfə az "yeyir". Go xidmətinin Java xidmətindən daha az istehlak etdiyi aydındır və Heap Elasticsearch JVM ölçüsünü və Loki üçün ayrılmış yaddaşı müqayisə etmək düzgün deyil, lakin buna baxmayaraq Loki-nin daha az yaddaş istifadə etdiyini qeyd etmək lazımdır. Onun CPU üstünlüyü o qədər də açıq deyil, lakin bu da mövcuddur.
Sürət
Loki qeydləri daha sürətli "yeyir". Sürət bir çox amillərdən asılıdır - hansı növ loglardan, onları nə qədər mürəkkəb təhlil etdiyimizdən, şəbəkədən, diskdən və s. Bu, Loki-nin indeksə daha az məlumat qoyması və müvafiq olaraq indeksləşdirməyə daha az vaxt sərf etməsi ilə izah olunur. Bu halda, vəziyyət axtarış sürəti ilə tərsinə çevrilir: Loki bir neçə gigabaytdan böyük olan məlumatları nəzərəçarpacaq dərəcədə yavaşlatır, ELK üçün isə axtarış sürəti məlumatların ölçüsündən asılı deyil.
Giriş Axtar
Loki, log axtarış imkanları baxımından ELK-dan əhəmiyyətli dərəcədə aşağıdır. Müntəzəm ifadələrlə Grep güclü bir şeydir, lakin böyüklər məlumat bazasından daha aşağıdır. Sorğu diapazonunun olmaması, yalnız etiketlər üzrə aqreqasiya, etiketsiz axtarışın mümkünsüzlüyü - bütün bunlar bizi Loki-də maraqlandıran məlumatların axtarışını məhdudlaşdırır. Bu, Loki istifadə edərək heç nə tapmaq mümkün olmadığını ifadə etmir, lakin Prometheus diaqramlarında problemi ilk dəfə tapdığınız zaman loglarla işin gedişatını müəyyən edir və sonra bu etiketlərdən istifadə edərək qeydlərdə baş verənləri axtarın.
interface
Birincisi, gözəldir (üzr istəyirəm, müqavimət göstərə bilmədim). Grafana gözəl görünüşlü interfeysə malikdir, lakin Kibana daha funksionaldır.
Loki'nin müsbət və mənfi cəhətləri
Müsbət cəhətlərdən Loki-nin Prometheus ilə inteqrasiya etdiyini qeyd etmək olar, müvafiq olaraq ölçüləri və xəbərdarlıqları qutudan alırıq. O, qeydləri toplamaq və Kubernetes Podları ilə saxlamaq üçün əlverişlidir, çünki o, Prometeydən miras qalmış xidmət kəşfinə malikdir və avtomatik olaraq etiketlər əlavə edir.
Minuslardan - zəif sənədlər. Promtail-in xüsusiyyətləri və imkanları kimi bəzi şeyləri yalnız kodu öyrənmək prosesində kəşf etdim, açıq mənbənin faydası. Digər çatışmazlıq zəif təhlil imkanlarıdır. Məsələn, Loki çoxsətirli qeydləri təhlil edə bilməz. Həmçinin, çatışmazlıqlar arasında Loki-nin nisbətən gənc texnologiya olması (1.0 buraxılışı 2019-cu ilin noyabrında idi).
Nəticə
Loki kiçik və orta layihələr üçün uyğun olan 100% maraqlı texnologiyadır, logların toplanması, log axtarışı, logların monitorinqi və təhlili ilə bağlı bir çox problemləri həll etməyə imkan verir.
Biz Badoo-da Loki-dən istifadə etmirik, çünki bizdə bizə uyğun gələn və illər ərzində müxtəlif fərdi həllərlə zənginləşdirilmiş ELK yığınımız var. Bizim üçün büdrəmə blok jurnallarda axtarışdır. Gündə demək olar ki, 100 GB loglarla hər şeyi və bir az daha çoxunu tapa bilmək və bunu tez bir zamanda etmək bizim üçün vacibdir. Diaqram və monitorinq üçün biz ehtiyaclarımıza uyğunlaşdırılmış və bir-biri ilə inteqrasiya olunmuş digər həllərdən istifadə edirik. Loki yığınının nəzərəçarpacaq faydaları var, lakin o, bizə sahib olduqlarımızdan artığını verməyəcək və onun faydaları miqrasiya xərclərini tam olaraq üstələməyəcək.
Araşdırmadan sonra Loki-dən istifadə edə bilməyəcəyimiz aydın olsa da, ümid edirik ki, bu yazı seçiminizdə sizə kömək edəcək.
Məqalədə istifadə edilən kodun olduğu anbar yerləşir burada.