Mi a Badoo-nál folyamatosan figyeljük az új technológiákat, és értékeljük, hogy használjuk-e őket rendszerünkben. Egy ilyen tanulmányt szeretnénk megosztani a közösséggel. A Lokinak, egy rönkgyűjtő rendszernek szentelték.
A Loki megoldást jelent a naplók tárolására és megtekintésére, és ez a verem rugalmas rendszert biztosít azok elemzéséhez és adatok Prometheusnak történő elküldéséhez. Májusban újabb frissítés jelent meg, amit az alkotók aktívan népszerűsítenek. Arra voltunk kíváncsiak, hogy a Loki mire képes, milyen funkciókat biztosít, és mennyiben tud alternatívaként működni a most használt ELK-val szemben.
Mi az a Loki
A Grafana Loki egy komplett naplózási rendszer összetevői. Más hasonló rendszerekkel ellentétben a Loki azon az elgondoláson alapul, hogy csak a napló metaadatokat - címkéket - indexeljen (csakúgy, mint a Prometheusban), és magukat a naplókat különálló darabokba tömörítse egymás mellett.
Mielőtt rátérnék arra, hogy mit tehet a Lokival, szeretném tisztázni, mit jelent a "csak a metaadatok indexelésének gondolata". Hasonlítsuk össze a Loki-megközelítést és az indexelési megközelítést a hagyományos megoldásokban, például az Elasticsearch-ben, az nginx-napló egy sorának példájával:
A hagyományos rendszerek elemzik a teljes sort, beleértve a sok egyedi user_id és item_id értéket tartalmazó mezőket is, és mindent nagy indexekben tárolnak. Ennek a megközelítésnek az az előnye, hogy gyorsan futtathat összetett lekérdezéseket, mivel szinte az összes adat az indexben található. De fizetni kell ezért, mert az index nagy lesz, ami memóriaigényt jelent. Ennek eredményeként a naplók teljes szövegű indexe méretében összevethető magával a naplókkal. A gyors kereséshez az indexet be kell tölteni a memóriába. És minél több napló, annál gyorsabban nő az index, és annál több memóriát fogyaszt.
A Loki-megközelítés megköveteli, hogy a karakterláncból csak a szükséges adatokat nyerjék ki, amelyek értékei kicsik. Így egy kis indexet kapunk, és idő és indexelt mezők szerinti szűréssel kereshetünk az adatok között, majd a többit reguláris kifejezésekkel vagy részkarakterlánc-keresésekkel vizsgáljuk. A folyamat nem tűnik a leggyorsabbnak, de a Loki a kérést több részre bontja és párhuzamosan hajtja végre, rövid időn belül nagy mennyiségű adatot feldolgozva. A bennük lévő szilánkok és párhuzamos kérések száma konfigurálható; így az időegységenként feldolgozható adatok mennyisége lineárisan függ a biztosított erőforrások mennyiségétől.
Ez a kompromisszum egy nagy gyors index és egy kis párhuzamos brute-force index között lehetővé teszi a Loki számára, hogy szabályozza a rendszer költségeit. Rugalmasan konfigurálható és az Ön igényei szerint bővíthető.
A Loki verem három összetevőből áll: Promtail, Loki, Grafana. A Promtail összegyűjti a naplókat, feldolgozza és elküldi a Lokinak. Loki megtartja őket. Grafana pedig adatokat kérhet a Lokitól és megmutathatja. A Loki általában nem csak naplók tárolására és keresésre használható. A teljes stack nagyszerű lehetőségeket kínál a bejövő adatok feldolgozására és elemzésére a Prometheus módszerrel.
A telepítési folyamat leírása megtalálható itt.
Naplókeresés
Kereshet a naplókban egy speciális Grafana — Explorer felületen. A lekérdezések a LogQL nyelvet használják, amely nagyon hasonlít a Prometheus által használt PromQL-hez. Elvileg elosztott grepnek is felfogható.
A keresőfelület így néz ki:
Maga a lekérdezés két részből áll: választóból és szűrőből. A Selector a naplókhoz rendelt indexelt metaadatok (címkék) alapján történő keresés, a szűrő pedig egy keresési karakterlánc vagy reguláris kifejezés, amely kiszűri a választó által meghatározott rekordokat. Az adott példában: Kapcsos zárójelben - a választó, minden utána - a szűrő.
{image_name="nginx.promtail.test"} |= "index"
A Loki működéséből adódóan választó nélkül nem lehet kérni, de a címkék tetszőlegesen általánossá tehetők.
A választó a kapcsos zárójelben lévő érték kulcsértéke. A kijelölőket kombinálhatja és különböző keresési feltételeket adhat meg az =, != operátorok vagy reguláris kifejezések használatával:
{instance=~"kafka-[23]",name!="kafka-dev"}
// Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev
A szűrő egy szöveg vagy reguláris kifejezés, amely kiszűri a választó által kapott összes adatot.
Lehetőség van ad-hoc grafikonok készítésére a kapott adatok alapján metrika módban. Például megtudhatja az index karakterláncot tartalmazó bejegyzés előfordulási gyakoriságát az nginx naplókban:
A funkciók teljes leírása a dokumentációban található LogQL.
Napló elemzés
A naplók gyűjtésének többféle módja van:
A Promtail segítségével, amely a rönkgyűjtésre szolgáló verem szabványos összetevője.
Használja a Fluentd-t vagy a Fluent Bit-et, amely adatokat küldhet a Lokinak. A Promtail-lel ellentétben szinte bármilyen típusú naplóhoz rendelkeznek kész elemzővel, és többsoros naplókat is tudnak kezelni.
Általában a Promtail-t használják elemzésre. Három dolgot csinál:
Megkeresi az adatforrásokat.
Ragassz rájuk címkéket.
Adatokat küld a Lokinak.
Jelenleg a Promtail képes olvasni a naplókat a helyi fájlokból és a rendszernaplóból. Fel kell szerelni minden olyan gépre, amelyről a naplókat gyűjtik.
Integráció van a Kubernetes-szel: a Promtail automatikusan megtudja a fürt állapotát a Kubernetes REST API-n keresztül, és összegyűjti a naplókat egy csomópontból, szolgáltatásból vagy podból, és azonnal közzéteszi a címkéket a Kubernetes metaadatai alapján (pod neve, fájlnév stb.).
A Pipeline segítségével a naplóból származó adatok alapján is felakaszthat címkéket. A Pipeline Promtail négyféle szakaszból állhat. További részletek - in hivatalos dokumentáció, azonnal megjegyezek néhány árnyalatot.
Elemzési szakaszok. Ez a RegEx és a JSON szakasza. Ebben a szakaszban a naplókból adatokat nyerünk ki az úgynevezett kivont térképbe. Kivonhatja a JSON-ból a szükséges mezőket egyszerűen a kibontott térképbe másolásával, vagy reguláris kifejezésekkel (RegEx), ahol a megnevezett csoportok „leképeződnek” a kibontott térképre. A kivont térkép egy kulcsérték tároló, ahol a kulcs a mező neve, az érték pedig a naplókból származó értéke.
Átalakítási szakaszok. Ennek a szakasznak két lehetősége van: transzformáció, ahol beállítjuk az átalakítási szabályokat, és forrás - az átalakítás adatforrása a kivont térképből. Ha a kibontott térképen nincs ilyen mező, akkor az létrejön. Így lehetőség van olyan címkék létrehozására, amelyek nem a kivont térképen alapulnak. Ebben a szakaszban a kivont térkép adatait egy meglehetősen hatékony eszközzel tudjuk manipulálni golang sablon. Ezenkívül emlékeznünk kell arra, hogy a kibontott térkép teljesen betöltődik az elemzés során, ami lehetővé teszi például a benne lévő érték ellenőrzését: „{{if .tag}tag value létezik{end}}”. A sablon támogatja a feltételeket, a ciklusokat és néhány karakterlánc-függvényt, mint például a Csere és a Vágás.
Akció szakaszai. Ebben a szakaszban tehet valamit a kivonattal:
Hozzon létre egy címkét a kinyert adatokból, amelyeket a Loki indexel.
Módosítsa vagy állítsa be az esemény időpontját a naplóból.
Módosítsa az adatokat (naplószöveg), amely a Lokihoz kerül.
Hozzon létre mérőszámokat.
Szűrési szakaszok. Az egyezési szakasz, ahol vagy elküldhetjük azokat a rekordokat, amelyeknek nincs szükségünk a /dev/null-ra, vagy elküldhetjük azokat további feldolgozásra.
A közönséges nginx naplók feldolgozásának példáján megmutatom, hogyan elemezheti a naplókat a Promtail segítségével.
A teszthez vegyünk egy módosított nginx képet jwilder/nginx-proxy:alpine nginx-proxyként és egy kis démont, amely képes lekérdezni magát HTTP-n keresztül. A démonnak több végpontja van, amelyekre különböző méretű, eltérő HTTP-státuszú és eltérő késleltetésű válaszokat tud adni.
A naplókat docker konténerekből fogjuk gyűjteni, amelyek a /var/lib/docker/containers/ útvonalon találhatók. / -json.log
A docker-compose.yml fájlban beállítjuk a Promtailt, és megadjuk a konfiguráció elérési útját:
Adja hozzá a naplók elérési útját a promtail.yml-hez (a konfigurációban van egy "docker" opció, amely ugyanazt egy sorban teszi, de ez nem lenne olyan nyilvánvaló):
scrape_configs:
- job_name: containers
static_configs:
labels:
job: containerlogs
__path__: /var/lib/docker/containers/*/*log # for linux only
Ha ez a konfiguráció engedélyezve van, a Loki minden tárolóból naplókat fog kapni. Ennek elkerülése érdekében módosítjuk a teszt nginx beállításait a docker-compose.yml fájlban - adjunk hozzá naplózást a címkemezőhöz:
Ha a kibontott térképbe be lehetett tenni a címkemezőt, akkor a regexp segítségével kivonjuk a kép és a tároló nevét.
- labels:
image_name:
container_name:
Címkéket rendelünk hozzá. Ha a kép_neve és a tároló_neve kulcsok megtalálhatók a kivont adatokban, akkor ezek értékei a megfelelő címkékhez lesznek rendelve.
- match:
selector: '{job="docker",container_name="",image_name=""}'
action: drop
Minden olyan naplót elvetünk, amelyen nincs beállítva a kép_neve és a tároló_neve címkék.
Minden olyan napló esetében, amelynek kép_neve egyenlő az nginx.promtail.test értékkel, bontsa ki a naplómezőt a forrásnaplóból, és helyezze be a kibontott térképbe a sorkulcs segítségével.
Kérelem_url elemzése. A regexp segítségével meghatározzuk a kérés célját: statikához, fényképekhez, API-hoz és beállítjuk a megfelelő kulcsot a kivont térképen.
- template:
source: request_type
template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"
A Template feltételes operátorainak használatával ellenőrizzük a telepített mezőket a kibontott térképen, és beállítjuk a szükséges értékeket a request_type mezőhöz: fotó, statikus, API. Másik hozzárendelése, ha nem sikerült. Most a request_type tartalmazza a kérés típusát.
Az api_request, virtual_host, request_type és status (HTTP status) címkéket aszerint állítottuk be, hogy mit sikerült a kibontott térképbe helyeznünk.
- output:
source: nginx_log_row
Kimenet módosítása. Most a kivont térképből megtisztított nginx napló a Lokihoz kerül.
A fenti konfiguráció futtatása után láthatja, hogy minden bejegyzés a naplóból származó adatok alapján van felcímkézve.
Ne feledje, hogy a nagyszámú értékkel (számossággal) rendelkező címkék kinyerése jelentősen lelassíthatja a Lokit. Vagyis ne tegye be az indexbe például a user_id értéket. Erről bővebben a cikkben olvashatHogyan tehetik gyorsabbá és egyszerűbbé a naplólekérdezéseket a Loki címkéi". De ez nem jelenti azt, hogy indexek nélkül nem lehet user_id alapján keresni. Kereséskor szűrőket kell használni (az adatok szerint „grab”), az index itt folyamazonosítóként működik.
Napló vizualizáció
A Loki a LogQL használatával adatforrásként szolgálhat a Grafana diagramokhoz. A következő funkciók támogatottak:
sebesség - rekordok száma másodpercenként;
időbeli számolás - az adott tartományban lévő rekordok száma.
Vannak még a Sum, Avg és mások összesítő függvényei. Összetett grafikonokat készíthet, például a HTTP-hibák számának grafikonját:
A Loki alapértelmezett adatforrása valamivel kevésbé működik, mint a Prometheus adatforrás (például nem módosíthatja a jelmagyarázatot), de a Loki Prometheus típusú forrásként csatlakoztatható. Nem vagyok benne biztos, hogy ez dokumentált viselkedés, de a fejlesztők válaszából ítélve "Hogyan állítsuk be a Lokit Prometheus adatforrásként? · 1222. szám · grafana/loki”, például teljesen legális, és a Loki teljesen kompatibilis a PromQL-lel.
Adja hozzá a Lokit adatforrásként Prometheus típussal, és fűzze hozzá a /loki URL-t:
Grafikonokat is készíthet, mintha a Prometheus mérőszámaival dolgoznánk:
Úgy gondolom, hogy a funkcionalitásbeli eltérés átmeneti, és a fejlesztők a jövőben kijavítják.
Metrikák
A Loki lehetőséget biztosít számszerű metrikák kinyerésére a naplókból és elküldésére a Prometheusnak. Például az nginx napló tartalmazza a válaszonkénti bájtok számát, valamint a szabványos naplóformátum bizonyos módosításával a válaszadás idejét másodpercben. Ezek az adatok kinyerhetők és elküldhetők a Prometheusnak.
Adjon hozzá egy másik szakaszt a promtail.yml fájlhoz:
Az opció lehetővé teszi metrikák meghatározását és frissítését a kivont térkép adatai alapján. Ezeket a mutatókat nem küldi el a Loki – a Promtail /metrics végpontban jelennek meg. A Prometheust úgy kell beállítani, hogy adatokat fogadjon ebből a szakaszból. A fenti példában a request_type="api" függvényhez hisztogram metrikát gyűjtünk. Az ilyen típusú mérőszámokkal kényelmesen lehet százalékos értékeket kapni. A statika és a fényképek esetében az átlag kiszámításához összegyűjtjük a bájtok összegét és azon sorok számát, amelyekben bájtokat kaptunk.
Így megtudhatja például a négy leglassabb lekérdezést. Ezen mérőszámok megfigyelését is beállíthatja.
Méretezés
A Loki lehet szimpla bináris módban és szilánkos (vízszintesen skálázható) módban is. A második esetben adatokat menthet a felhőbe, a darabokat és az indexet pedig külön tárolja. Az 1.5-ös verzióban az egy helyen történő tárolás lehetősége megvalósul, de élesben még nem javasolt használni.
A darabok S3-kompatibilis tárolóban tárolhatók, az indexek tárolására pedig vízszintesen méretezhető adatbázisok használhatók: Cassandra, BigTable vagy DynamoDB. A Loki más részei – a disztribútorok (íráshoz) és a Querier (lekérdezésekhez) – állapot nélküliek és vízszintesen is méretezhetők.
A kapott indexméret teszteléséhez naplókat vettem abból az nginx-tárolóból, amelyhez a fenti Pipeline konfigurálva volt. A naplófájl 406 624 sort tartalmazott, összesen 109 MB térfogattal. A naplókat egy órán belül generáltuk, körülbelül 100 rekordot másodpercenként.
Példa két sorra a naplóból:
Az ELK indexelésekor az index mérete 30,3 MB volt:
A Loki esetében ez körülbelül 128 KB indexet és körülbelül 3,8 MB adatot adott darabokban. Érdemes megjegyezni, hogy a naplót mesterségesen hozták létre, és nem tartalmazott sokféle adatot. Egy egyszerű gzip az eredeti Docker JSON naplón az adatokkal 95,4%-os tömörítést adott, és tekintve, hogy magának a Lokinak csak a megtisztított nginx naplót küldték el, a 4 MB-os tömörítés érthető. A Loki címkék egyedi értékeinek száma összesen 35 volt, ami megmagyarázza az index kis méretét. Az ELK esetében a naplót is törölték. Így a Loki 96%-kal, az ELK 70%-kal tömörítette az eredeti adatokat.
Memória fogyasztás
Ha összehasonlítjuk a Prometheus és az ELK teljes veremét, akkor Loki többször kevesebbet "eszik". Nyilvánvaló, hogy a Go szolgáltatás kevesebbet fogyaszt, mint a Java szolgáltatás, és a Heap Elasticsearch JVM méretének és a Loki számára lefoglalt memóriának az összehasonlítása hibás, de ennek ellenére érdemes megjegyezni, hogy a Loki sokkal kevesebb memóriát használ. CPU-előnye nem annyira nyilvánvaló, de ez is jelen van.
Sebesség
Loki gyorsabban "falja fel" a rönköket. A sebesség sok tényezőtől függ - milyen naplók, milyen kifinomultan elemezzük őket, hálózat, lemez stb. -, de határozottan nagyobb, mint az ELK-é (az én tesztemben - kb. kétszerese). Ez azzal magyarázható, hogy a Loki sokkal kevesebb adatot helyez az indexbe, és ennek megfelelően kevesebb időt fordít az indexelésre. Ebben az esetben a keresési sebességgel fordított a helyzet: néhány gigabájtnál nagyobb adat esetén a Loki érezhetően lelassul, míg az ELK-nál a keresési sebesség nem függ az adatmérettől.
Naplókeresés
A Loki lényegesen alulmúlja az ELK-t a naplókeresési képességek tekintetében. A reguláris kifejezésekkel rendelkező Grep erős dolog, de rosszabb, mint egy felnőtt adatbázis. A tartománylekérdezések hiánya, a csak címkék szerinti összesítés, a címkék nélküli keresés képtelensége - mindez korlátozza a Lokiban érdekes információk keresését. Ez nem jelenti azt, hogy a Loki segítségével semmit nem lehet találni, de meghatározza a naplókkal való munka folyamatát, amikor először talál egy problémát a Prometheus diagramokon, majd keresi meg, mi történt a naplókban ezekkel a címkékkel.
felület
Először is gyönyörű (elnézést, nem tudtam ellenállni). A Grafana szép megjelenésű felülettel rendelkezik, de a Kibana sokkal funkcionálisabb.
Loki előnyei és hátrányai
A pluszok közül megjegyezhető, hogy a Loki integrálódik a Prometheusszal, illetve a mérőszámokat és a riasztásokat a dobozból kapjuk. Kényelmes a naplók összegyűjtésére és a Kubernetes Pods tárolására, mivel rendelkezik a Prometheustól örökölt szolgáltatásfelderítéssel, és automatikusan címkéket csatol.
A mínuszok közül - rossz dokumentáció. Néhány dolgot, például a Promtail szolgáltatásait és képességeit, csak a kód tanulmányozása során fedeztem fel a nyílt forráskód előnyeire. Egy másik hátrány a gyenge elemzési képesség. Például a Loki nem tudja elemezni a többsoros naplókat. A hátrányok közé tartozik az is, hogy a Loki egy viszonylag fiatal technológia (az 1.0-s kiadás 2019 novemberében volt).
Következtetés
A Loki egy 100%-ban érdekes technológia, amely alkalmas kis és közepes projektekhez, lehetővé téve számos naplóösszesítési, naplókeresési, naplónaplózási és -elemzési probléma megoldását.
A Badoo-nál nem használunk Lokit, mert van egy nekünk megfelelő ELK stackünk, amit az évek során benőttek a különféle egyedi megoldások. Számunkra a buktató a naplókban való keresés. A napi közel 100 GB naplózás mellett fontos számunkra, hogy mindent és egy kicsit többet is megtaláljunk és gyorsan elvégezhessünk. A diagramkészítéshez és monitorozáshoz más, az igényeinkre szabott és egymással integrált megoldásokat alkalmazunk. A Loki verem kézzelfogható előnyökkel jár, de nem ad többet, mint amink van, és az előnyei sem haladják meg pontosan a migráció költségeit.
És bár a kutatás után világossá vált, hogy nem tudjuk használni a Lokit, reméljük, hogy ez a bejegyzés segít a választásban.
A cikkben használt kóddal rendelkező tároló található itt.