Məruzəçinin məruzəsi ilə tanış olmağı təklif edirəm: Roman Khavrenko "ExtendedPromQL"


Qısaca özüm haqqında. Mənim adım Roman. CloudFlare-da çalışıram, Londonda yaşayıram. Amma eyni zamanda VictoriaMetrics-in saxlayıcısıyam.
Və mənim müəllifi olduğum Grafana üçün və ClickHouse üçün kiçik bir prosidir.

Birinci hissədən başlayacağıq; onun adı 'Tərcümə çətinlikləri'dir və burada mən hər hansı bir dilin, ya da sadəcə bir ünsiyyət dilinin çox vacib olduğunu danışacağam. Çünki bu, siz öz fikirlərinizi başqa bir insana və ya sistemə necə ötürdüyünüzdür, sorğu necə formulə olunur. İnternetdə insanlar hansı dilin daha yaxşı olduğu üzərində mübahisə edirlər - java, ya da başqa bir dil. Mən özüm üçün qərara gəldim ki, məqsəd üçün seçim etmək lazımdır, çünki bütün bunlar spesifikdir.

Hər şeyin başından başlayırıq. PromQL nədir? PromQL - Prometheus Sorğu Dili. Bu, Prometheus-da zaman seriyası məlumatlarını əldə etmək üçün sorğuları necə formalaşdırdığımızdır.

Zaman seriyası məlumatları nədir? Əslində, bu üç parametrdir.
Bunlar:
- Nəyə baxırıq.
- Bunun üzərində vaxt.
- Və hansı dəyəri göstərir.

Bu diaqramdan (bu mənim telefonumdan olan diaqram, addımlarımın statistikalarını göstərir) baxsaq, bu suallara tez cavab vermək mümkündür.
Addımlara baxırıq. Dəyəri görürük və bunun üzərində baxdığımız vaxta baxırıq. Yəni bu diaqramdan asanlıqla söyləyə bilərik ki, bazar günü təxminən 15 000 addım atmışam. Bu zaman seriyası məlumatlarıdır.

İndi gəlin onları 'parçalayaq' (transformasiya edəlim) başqa bir məlumat modelinə, cədvəl şəklində. Burada da nəyi gördüyümüz var. Burada əlavə məlumatları əlavə etdim, onlara meta-məlumat deyəcəyik, yəni bunu mən deyil, iki nəfər, məsələn, Jay və Silent Bob etdi. İştə, baxdığımız şey; bunun nəyi göstərdiyini və bu dəyəri nə zaman göstərdiyini.

İndi gəlin bu bütün məlumatları verilənlər bazasında saxlamağa çalışaq. Məsələn, ClickHouse sintaksisini götürdüm. Burada 'Steps' adlı bir cədvəl yaradırıq, yəni nəyi gördüyümüz. Burada baxdığımız zaman; nəyi göstərir və bəzi meta-məlumatlar var, burada kimin olduğunu, yəni Jay və Silent Bob-u saxlayacağıq.

Və bütün bunu vizuallaşdırmağa çalışmaq üçün Grafana istifadə edəcəyik, çünki birinci, bu gözəl görünür.

Bu plaginindən də istifadə edəcəyik. Bunun iki səbəbi var. Birincisi, onu mən yazmışam. Və ClickHouse-dan time series məlumatlarını Grafana-da göstərməyin nə qədər çətin olduğunu dəqiq bilirəm.

Biz Graph Panel-də göstərəcəyik. Bu, Grafana-da vaxtdan asılılığı göstərən ən populyar paneldir, buna görə də yalnız iki parametrə ehtiyacımız var.

Gəlin, Grafana-da addım statistikalarını göstərmək üçün ClickHouse-da saxladığımız məlumatlarla ən sadə sorğunu yazaq. Biz belə sadə bir sorğu yazırıq. Addımlardan seçirik. Dəyəri seçirik və bu dəyərlərin vaxtını seçirik, yəni danışdığımız üç parametr.

Və nəticədə belə bir qrafik alacağıq. Kim bilir, niyə bu qədər qəribədir?

Hə, vaxtla sıralamağı unutduq.

Və nəticədə daha yaxşısını alacağıq, amma hələ də qəribə bir qrafikdir. Kim bilirsə, niyə? Doğru, orada iki iştirakçı var və Grafana-da iki time series təqdim edirik, çünki data modelini bir daha gözdən keçirsək, hər time series unikal ad və bütün açar-dəyər etiketlərinin kombinəsidir.

Bu səbəbdən konkret bir şəxsi seçməliyik. Jay-i seçirik.

Və bir daha çəkirik. İndi artıq qrafik doğru görünür. İndi bu normal bir qrafikdir və hər şey yaxşı işləyir.

Və yəqin ki, Prometheus-da PromQL vasitəsilə təqribən eyni şeyi necə edəcəyinizi bilirsiniz. Təqribən belə. Bir az daha asandır. Və bunu böləcəyik. Biz addımları götürdük. Və Jay üzrə filtr edirik. Burada dəyəri əldə etməyimizi istəmirik və vaxt seçmirik.

İndi Jay-in və ya Silent Bob-un hərəkət sürətini hesablamağa çalışaq. ClickHouse-da runningDifference etmək lazım olacaq, yəni nöqtə cütlükləri arasında fərqi hesablayıb, bunu vaxta bölmək lazımdır ki, dəqiq sürəti əldə edə bilək. Sorğu təqribən belə görünəcək.

Və bu, təqribən belə dəyərləri göstərəcək, yəni Silent Bob və ya Jay təqribən saniyədə 1.8 addım atır.

Və Prometheus-da, bunu necə edəcəyinizi də bilirsiniz. Bu, əvvəlkindən daha asandır.
Və bunun Grafana-da asanlıqla edilməsi üçün belə bir qablaşdırma əlavə etdim, bu da PromQL-ə çox bənzəyir. Bu, Rate Macros adlanır, ya da istədiyiniz kimi adlandırın. Grafana-da sadəcə 'rate' yazırsınız, amma burada dərinlikdə bu, belə böyük bir sorğuya çevrilir. Və siz ona baxmağa belə ehtiyac duymursunuz, o bir yerdə var, amma siz çoxlu vaxt qazanırsınız, çünki belə böyük SQL sorğuları yazmaq həmişə çətindir. Asanlıqla səhv edə bilərsiniz və sonra nələrin baş verdiyini uzun müddət anlamaya bilərsiniz.

Bu, bir slayda sığmayan və iki kolonaya bölməyə məcbur olduğum bir sorğudur. Bu da ClickHouse-da eyni 'rate'-i həyata keçirən bir sorğudur, lakin həm Silent Bob, həm də Jay üçün zaman seriyaları vardır ki, paneldə iki zaman seriyası olsun. Bu, mənim fikrimcə artıq çox çətindir.

Prometheus-da bu sum (rate) olacaq. ClickHouse üçün RateColumns adlı ayrıca bir makro yaratdım, bu da Prometheus-da bir sorğuya bənzəyir.

Biz baxdıq və görünür PromQL bu qədər gözəldir, amma əlbəttə ki, onun bəzi məhdudiyyətləri var.
Bunlar:
- Məhdud SELECT.
- Sərhəd JOIN.
- HAVING dəstəyi yoxdur.
Və əgər siz onunla uzun müddət işləsəniz, bilirsiniz ki, bəzən PromQL-da bir şeyi etmək çox çətindir, amma SQL-də demək olar ki, hər şeyi edə bilərsiniz, çünki indi müzakirə etdiyimiz bütün variantları SQL-də etmək mümkün idi. Amma bunun istifadəsi rahat olardı mı? Bu, məni düşünməyə vadar edir ki, həmişə ən güclü dil ən rahat ola bilmir.

Buna görə bəzən işlərə uyğun dil seçmək lazımdır. Bu, Batman'ın Superman ilə döyüşü kimidir. Aydındır ki, Superman daha güclüdür, amma Batman onu məğlub edə bildi, çünki o daha praktikdir və nə etdiyini tam bilirdi.

Növbəti hissə isə PromQL-i genişləndirməkdir.

Yenidən VictoriaMetrics haqqında. VictoriaMetrics nədir? Bu, zaman seriyaları üçün verilənlər bazasıdır, açıq mənbəlidir, biz onu tək və klaster versiyalarında paylayırıq. Bizim benchmarklarımıza görə, bazarda mövcud olanların ən sürətlisidir və sıxılma baxımından da oxşar şəkildə, yəni canlı insanlar sıxılmanı 0,4 bayt nöqtə başına bildirirlər, Prometheus-da isə bu 1,2-1,4-dür.
Biz yalnız Prometheus-u dəstəkləmirik. Biz InfluxDB, Graphite, OpenTSDB-nı da dəstəkləyirik.
Bizə "yazmaq" mümkündür, yəni köhnə məlumatları köçürmək olar.
Və biz Prometheus və Grafana ilə mükəmməl işləyirik, yəni PromQL mühərrikini dəstəkləyirik. Və Grafana-da sadəcə Prometheus endpointini VictoriaMetrics ilə dəyişərək, bütün paneliniz əvvəlki kimi işləyəcək.
Lakin, VictoriaMetrics sizə əlavə xüsusiyyətlərdən də istifadə etməyə imkan verir.
Biz əlavə etdiyimiz funksiyaların üzərindən tez keçəcəyik.

Omit interval param – Grafana-da interval parametrlərini atlaya bilərsiniz. Paneldə zoom-in/out zamanı qəribə qrafiklər əldə etmək istəmirsinizsə, dəyişəni istifadə etməyiniz tövsiyə olunur. $__interval. Bu, Grafana'nın daxili dəyişkənidir və o, məlumat aralığını özbaşına seçir. VictoriaMetrics də bu aralığın nə cür olmalı olduğunu başa düşə bilir. Və siz bütün sorğularınızı güncəlləməyə ehtiyac duymursunuz. Bu, çox daha asan olacaq.

İkinci funksiya - interval referencing. Bu intervalı ifadələrinizdə istifadə edə bilərsiniz. Onu vurmaq, bölmək, ötürmək, ona istinad etmək mümkündür.

Daha sonra rollup function ailəsi. Rollup function, hər hansı bir zaman seriyanızı üç ayrı zaman seriyasına çevirir. Bunlar min, max və avg-dir. Mən bunu çox rahat hesab edirəm, çünki bəzən bu, ara çıxmaları (outliers) və qeyri-dəqiqlikləri göstərə bilər.

Və yalnız irate və ya rate etsəniz, zaman seriyasının gözlədiyiniz kimi davranmadığı bəzi halları atlaya bilərsiniz. Bu funksiya ilə, məsələn, max dəyərinin avg-dən çox fərqli olduğunu görmək daha asandır.

Daha sonra default dəyişəni. Default, o deməkdir ki, cari zamanda zaman seriyası olmadıqda Grafana-da hansı dəyəri göstərməyimiz lazım olacaq. Bu nə vaxt baş verir? Məsələn, siz bir səhv metrikası ixrac edirsiniz. Və sizdə elə bir gözəl tətbiq var ki, başladığınızda sizi səhv olmur və hətta üç saat və ya bir gün ərzində səhv olmur. Və sizdə successful ilə error arasındakı nisbətləri göstərən dashboardlar var. Bunlar sizə heç nə göstərməyəcək, çünki sizdə error metrikası yoxdur. Və default-da istədiyiniz hər şeyi göstərə bilərsiniz.

Keep_last_Value – metrikalar itdikdə sonuncu dəyəri saxlayır. Əgər Prometheus növbəti scrapping zamanı onu 5 dəqiqə ərzində tapmasa, burada sonuncu dəyərini yadda saxlamağa çalışacağıq və qrafikləriniz yenidən pozulmayacaq.

Scrape_interval – Prometheus'un metrikalarınızı nə qədər tez topladığını göstərir. Burada bir keçilməni görə bilərsiniz, məsələn.

Label replace – populyar bir funksiyadır. Ancaq biz hesab edirik ki, o, bir az çətindir, çünki bir çox arqument qəbul edir. Sizə yalnız 5 arqumenti xatırlamağa deyil, həm də onların ardıcıllığını xatırlamağa ehtiyac var.

Ona görə də niyə onları daha sadə etməyək? Yəni, aydın sintaksisli kiçik funksiyalara ayıraq.

Və indi ən maraqlı hissə. Niyə biz bunu genişləndirilmiş PromQL hesab edirik? Çünki Biz Ümumi Cədvəl İfadələrini dəstəkləyirik. Siz QR-koddan keçə bilərsiniz (), misallarla, VictoriaMetrics-in quraşdırılmasına ehtiyac olmadan sadəcə brauzerdə sorğuları yerinə yetirə biləcəyiniz playground-ı nəzərdən keçirə bilərsiniz.

Bəs bu nədir? Yuxarıdakı sorğu – olduqca populyar bir sorğudur. Düşünürəm ki, bir çox şirkətdəki hər bir paneldə eyni filtrdən istifadə edirsiniz. Adətən belədir. Amma sizə yeni bir filtr əlavə etmək lazım olduqda, hər paneli yeniləməli, ya da dashboard-u yükləyib, JSON-da açmalı, find replace etməlisiniz, bu da vaxt alır. Niyə bu dəyəri dəyişkəndə saxlayıb onu yenidən istifadə etməyəsiniz? Bu, mənim fikrimcə, daha sadə və daha aydındır.

Məsələn, mən Grafa-də bütün sorğularda filtr əlavə etməli olduğumda, dashboard çox böyük ola bilər və ya bir neçəsi ola bilər. Və bu problemi necə həll etmək istəyirəm?

Bu problemi belə həll edirəm: mən commonFilter-i yaradıram və orada bu filtrin tərifini verib, sonra onu sorğularda yenidən istifadə edirəm. Amma siz indi eyni şeyi edirsinizsə, bu işləməyəcək, çünki Grafana sizə sorğu dəyişənləri daxilində dəyişkənlər istifadə etməyə icazə vermir. Bu, bir az qəribədir.

Ona görə də belə bir variant yaratdım ki, bu da bunu etməyə imkan verir. Əgər bu sizə maraqlıdırsa və ya bu funksiyanı istəyirsinizsə, dəstəkləyin və ya sevmirsinizsə, dislike edin.

Daha sonra genişləndirilmiş PromQL haqqında. Burada biz yalnız dəyişkən müəyyən etmirik, əslində bir funksiyanı birbaşa təyin edirik. Və ona ru (resource usage) deyirik. Bu funksiya boş resursları, resurs məhdudiyyətini və filtrini qəbul edir. Sintaksis çox sadədir. Bu funksiyanı istifadə etmək və sərbəst yaddaşın faizi hesablanmasını etmək çox asandır. Yəni, bizdə nə qədər yaddaş var, hansı məhdudiyyət var və necə filtr etmək lazımdır. Dəyərlərinizi təkrar istifadə edərək, bunu yazmağınız bu qədər asan olsaydı, çox böyük bir sorğuya çevriləcəkdi.

Və burada böyük bir sorğunun nümunəsi var. Bu, Grafana üçün NodeExporter-in rəsmi panelindən gətirilib. Ancaq burada nə baş verdiyini zəif anlayıram. Yəni, əlbəttə, diqqətlə baxanda anlayıram, amma mötərizələrin sayı dərhal başa düşmək motivasiyasını azaldır. Niyə də bunu daha sadə və aydın etməyək?

Məsələn, belə edə bilərik, əhəmiyyətli şeyləri və ya hissələri dəyişkənlərə ayıraraq. Və sonra öz əsas riyaziyyatımızı tətbiq edə bilərik. Bu artıq proqramlaşdırmaya daha çox bənzəyir, bu da mənim gələcəkdə Grafana-da görmək istədiyim bir şeydir.

Bu, ikinci nümunədir, əgər artıq bu ru funksiyamız olsaydı, biz bunu daha da asan edə bilərik, çünki bu, VictoriaMetrics-də artıq mövcuddur. Və siz sadəcə, CTE-də elan etdiyiniz qiyməti köçürürsünüz.

Mən artıq düzgün proqramlaşdırma dilindən istifadə etməyin vacibliyini qeyd etmişdim. Yəqin ki, hər şirkətdə Grafana-da özünəməxsus işlər gedir. Və yəqin ki, siz Grafana-ya öz inkişaf etdiricilərinizə giriş verirsiniz və inkişaf etdiricilər özlərinə aid olan bir şeylər edirlər. Və hamısı bunu fərqli şəkildə edir. Eyni standartlara gətirmək istəyirdik.
Tutaq ki, sizdə sadəcə sistem mühəndisləri deyil, bəlkə də devops və ya SRE mütəxəssisləri var. Bəlkə sizdə monitorinqi, Grafana-nı bilən mütəxəssislər var, yəni illərlə bununla işləyirlər və düzgün edilməsi üçün nə etməli olduqlarını bilirlər. Və artıq bunu 100 dəfə yazıb bütün bunları başa salıblar, amma nədənsə heç kim dinləmir.
Bəs, əgər onlar bu bilikləri birbaşa Grafana-ya yerləşdirə bilsəydilər ki, digər istifadəçilər funksiyalardan istifadə edə bilsinlər? Və əgər sərbəst yaddaşın faizini hesablamaq lazım olsaydı, sadəcə funksiyanı tətbiq edərdilər. Bəs, əgər ixracatçıların yaradıcıları, məhsulları ilə birlikdə, onların metrikanları ilə işləmək üçün bir funksiyalar dəsti təqdim etsələrdi, çünki onlar bu metrikanların nə olduğunu və necə düzgün hesablandığını yaxşıca bilirdilər?
Əslində, bunun heç biri mövcud deyil. Bunu mən özüm etdim. Bu, Grafana-da kitabxana dəstəyidir. Tutaq ki, NodeExporter-i hazırlayan uşaqlar, mənim danışdığım şeyi etdilər. Və eyni zamanda, funksiyalar dəsti də təqdim etdilər.

Yəni, bu belə görünür. Siz bu kitabxananı Grafana'ya qoşursunuz, redaktə etməyə girirsiniz və burada JSON-da bu metriklə necə işləyəcəyiniz çox sadə yazılıb. Yəni, müəyyən bir funksiya dəsti, onların tərifi və hansı şəkildə həyata keçirildikləri.

Məncə, bu faydalı ola bilər, çünki o zaman Grafana'ya belə yazacaqsınız. Və Grafana sizə "deyir" ki, belə bir funksiya var bu kitabxanadan – gəl bunu istifadə edək. Məncə, bu, çox gözəl olardı.

VictoriaMetrics haqqında bir az. Biz çox maraqlı şeylər edirik. Sıxılma, digər zaman seriyası məlumat tətbiqləri ilə rəqabətimiz, PromQL ilə necə işləməyi açıqlamağımız barədə yazılarımızı oxuyun, çünki burada hələ çoxlar üçün yeni olanlar var, və eyni zamanda şaquli genişlənmə və Thanos ilə mübarizə məsələlərini də.

Suallar:
Sualıma sadə bir həyat hekayəsilə başlayacağam. Mən Grafana istifadə etməyə başladıqda, 5 sətirdən ibarət çox təsir edici bir sorğu yazdım. Nəticədə çox təsir edici bir qrafik əldə olundu. Bu qrafik demək olar ki, production-a keçəcəkdi. Amma yaxından baxdıqda anlaşıldı ki, bu qrafik reallıqla heç bir əlaqəsi olmayan tam bir nağıldır, baxmayaraq ki, sayılar gözlədiyimiz diapazona düşür. Və sualım. Bizdə kitabxanalar var, funksiyalarımız var, bəs Grafana üçün testləri necə yazırıq? Siz çətin bir sorğu yazmısınız ki, biznes qərarına təsir edir – həqiqi server konteyneri sifariş etməliyik, ya da yox. Və necə bilirik ki, qrafiki çizen funksiya reallığa bənzəyir. Təşəkkürlər.
Sual üçün təşəkkür edirəm. Burada iki hissə var. Birinci – mənim təcrübəmə görə, əksər istifadəçilər qrafiklərinə baxanda onların onlara nə göstərdiyini başa düşmürlər. Nədənsə insanlar qrafiklərdə baş verən hər hansı bir anomaliyanı, hətta bu, funksiyanın daxili səhvidirsə belə, izah etməkdə çox yaxşıdırlar. Və ikinci hissə – məncə, bu cür funksiyaların istifadəsi sizin probleminizi həll etmək üçün daha yaxşı olardı, əvəzinə hər bir proqramçınızın öz tələbat planlaması etməsi və müəyyən bir ehtimal ilə səhv etməsi.
Necə yoxlamaq olar?
Necə yoxlamaq olar? Bəlkə də, heç necə.
Grafana'da bir test şəklində.
Grafana burada nə əlaqəsi var? Grafana bu sorğunu birbaşa DataSource'a çevirir.
Parametrlərə bir az əlavə edərək.
Xeyr, Grafana-da heç nə əlavə edilmir. Orada GET-parametrləri ola bilər, məsələn, step. O açıq-aydın göstərilmir, amma onu özünüz yenidən təyin edə bilərsiniz, təyin etməyə bilərsiniz, amma avtomatik əlavə olunur. Burada siz testlər yaza bilməzsiniz. Düşünürəm ki, burada Grafanaya həqiqət mənbəyi kimi etibar etməyə dəyər deyil.
Təşəkkür edirəm, hesabat üçün! Sıxma üçün təşəkkür edirəm! Siz grafdə dəyişkənlərin mappingindən danışırsınız, Grafana-da dəyişkəni dəyişkən olaraq istifadə etmək mümkün deyil. Mənim dediyimi anlayırsınızmı?
Bəli.
Bu, əvvəlcə mənim üçün baş ağrısı idi, Grafana-da alert yaratmaq istəyəndə. Hər bir host üçün ayrıca alert yaratmaq lazımdır. Siz etdiyiniz bu şey, Grafana-dakı alertlər üçün işləyirmi?
Əgər Grafana dəyişkənlərə başqa cür müraciət etmirsə, onda – bəli, işləyəcək. Amma mənim məsləhətim, Grafana-da alerting istifadə etməməkdir, sizə daha yaxşı alertmanager istifadə etmək tövsiyə olunur.
Bəli, mən onu istifadə edirəm, amma sadəcə Grafana-da tənzimləmə daha asan göründü, amma məsləhət üçün təşəkkür edirəm!
Mənbə: habr.com
