Analýza TSDB v programe Prometheus 2

Analýza TSDB v programe Prometheus 2

Databáza časových radov (TSDB) v Prometheus 2 je vynikajúcim príkladom inžinierskeho riešenia, ktoré ponúka veľké vylepšenia oproti úložisku v2 v Prometheus 1 z hľadiska rýchlosti akumulácie údajov, vykonávania dotazov a efektívnosti zdrojov. Implementovali sme Prometheus 2 v Percona Monitoring and Management (PMM) a mal som možnosť pochopiť výkon Prometheus 2 TSDB. V tomto článku budem hovoriť o výsledkoch týchto pozorovaní.

Priemerné pracovné zaťaženie Prometheus

Pre tých, ktorí sú zvyknutí na prácu s databázami na všeobecné použitie, je typická pracovná záťaž Prometheus celkom zaujímavá. Miera akumulácie údajov má tendenciu byť stabilná: služby, ktoré monitorujete, zvyčajne odosielajú približne rovnaký počet metrík a infraštruktúra sa mení pomerne pomaly.
Žiadosti o informácie môžu pochádzať z rôznych zdrojov. Niektoré z nich, napríklad upozornenia, sa tiež usilujú o stabilnú a predvídateľnú hodnotu. Iné, ako napríklad požiadavky používateľov, môžu spôsobiť zhluky, hoci to neplatí pre väčšinu pracovných zaťažení.

Test zaťaženia

Počas testovania som sa zameral na schopnosť kumulovať dáta. Nasadil som Prometheus 2.3.2 kompilovaný s Go 1.10.1 (ako súčasť PMM 1.14) v službe Linode pomocou tohto skriptu: StackScript. Pre čo najrealistickejšie generovanie záťaže použite toto StackScript Spustil som niekoľko MySQL uzlov s reálnou záťažou (Sysbench TPC-C Test), z ktorých každý emuloval 10 Linux/MySQL uzlov.
Všetky nasledujúce testy boli vykonané na serveri Linode s ôsmimi virtuálnymi jadrami a 32 GB pamäte, pričom bolo spustených 20 simulácií záťaže monitorujúcich dvesto inštancií MySQL. Alebo povedané v Prometheus, 800 cieľov, 440 zoškrabaní za sekundu, 380 tisíc záznamov za sekundu a 1,7 milióna aktívnych časových radov.

Design

Zvyčajný prístup tradičných databáz, vrátane tej, ktorú používa Prometheus 1.x, je limit pamäte. Ak nestačí zvládnuť záťaž, zaznamenáte vysoké latencie a niektoré požiadavky zlyhajú. Využitie pamäte v Prometheus 2 je konfigurovateľné pomocou kľúča storage.tsdb.min-block-duration, ktorý určuje, ako dlho budú nahrávky uchovávané v pamäti pred vymazaním na disk (predvolené sú 2 hodiny). Množstvo potrebnej pamäte bude závisieť od počtu časových radov, štítkov a škrabancov pridaných do čistého prichádzajúceho toku. Pokiaľ ide o miesto na disku, cieľom Prometheusu je použiť 3 bajty na záznam (vzorku). Na druhej strane nároky na pamäť sú oveľa vyššie.

Aj keď je možné nakonfigurovať veľkosť bloku, neodporúča sa ho konfigurovať manuálne, takže ste nútení dať Prometheus toľko pamäte, koľko si vyžaduje pre vaše pracovné zaťaženie.
Ak nie je dostatok pamäte na podporu prichádzajúceho prúdu metrík, Prometheus vypadne z pamäte alebo sa k nemu dostane OOM zabijak.
Pridanie swapu na oddialenie zlyhania, keď sa Prometheus minie pamäť, skutočne nepomôže, pretože používanie tejto funkcie spôsobuje výbušnú spotrebu pamäte. Myslím, že to má niečo spoločné s Go, jeho zberačom odpadu a spôsobom, akým rieši swap.
Ďalším zaujímavým prístupom je nakonfigurovať blok hlavy tak, aby sa v určitom čase vyprázdnil na disk, namiesto počítania od začiatku procesu.

Analýza TSDB v programe Prometheus 2

Ako môžete vidieť z grafu, preplachy na disk sa vyskytujú každé dve hodiny. Ak zmeníte parameter min-block-duration na jednu hodinu, potom sa tieto resety vyskytnú každú hodinu, počnúc pol hodinou.
Ak chcete použiť tento a ďalšie grafy vo svojej inštalácii Prometheus, môžete použiť tento prístrojová doska. Bol navrhnutý pre PMM, ale s malými úpravami sa hodí do akejkoľvek inštalácie Prometheus.
Máme aktívny blok nazývaný head block, ktorý je uložený v pamäti; bloky so staršími údajmi sú dostupné cez mmap(). To eliminuje potrebu samostatnej konfigurácie vyrovnávacej pamäte, ale tiež to znamená, že musíte ponechať dostatok miesta pre vyrovnávaciu pamäť operačného systému, ak chcete vyhľadávať údaje staršie, ako sa zmestí hlavový blok.
To tiež znamená, že spotreba virtuálnej pamäte Prometheus bude vyzerať dosť vysoká, čoho sa netreba obávať.

Analýza TSDB v programe Prometheus 2

Ďalším zaujímavým dizajnovým bodom je použitie WAL (zápis dopredu). Ako môžete vidieť z dokumentácie k úložisku, Prometheus používa WAL na predchádzanie zlyhaniam. Špecifické mechanizmy na zaručenie prežitia údajov, žiaľ, nie sú dostatočne zdokumentované. Prometheus verzia 2.3.2 vyprázdni WAL na disk každých 10 sekúnd a túto možnosť používateľ nemôže konfigurovať.

Zhutnenia

Prometheus TSDB je navrhnutý ako úložisko LSM (Log Structured Merge): blok hlavy sa pravidelne vyplachuje na disk, zatiaľ čo mechanizmus zhutňovania kombinuje viaceré bloky dohromady, aby sa zabránilo skenovaniu príliš veľa blokov počas dopytov. Tu vidíte počet blokov, ktoré som pozoroval na testovacom systéme po dni záťaže.

Analýza TSDB v programe Prometheus 2

Ak sa chcete o obchode dozvedieť viac, môžete preskúmať súbor meta.json, ktorý obsahuje informácie o dostupných blokoch a o tom, ako vznikli.

{
       "ulid": "01CPZDPD1D9R019JS87TPV5MPE",
       "minTime": 1536472800000,
       "maxTime": 1536494400000,
       "stats": {
               "numSamples": 8292128378,
               "numSeries": 1673622,
               "numChunks": 69528220
       },
       "compaction": {
               "level": 2,
               "sources": [
                       "01CPYRY9MS465Y5ETM3SXFBV7X",
                       "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                       "01CPZ6NR4Q3PDP3E57HEH760XS"
               ],
               "parents": [
                       {
                               "ulid": "01CPYRY9MS465Y5ETM3SXFBV7X",
                               "minTime": 1536472800000,
                               "maxTime": 1536480000000
                       },
                       {
                               "ulid": "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                               "minTime": 1536480000000,
                               "maxTime": 1536487200000
                       },
                       {
                               "ulid": "01CPZ6NR4Q3PDP3E57HEH760XS",
                               "minTime": 1536487200000,
                               "maxTime": 1536494400000
                       }
               ]
       },
       "version": 1
}

Zhutnenia v Prometheus sú viazané na čas, keď je blok hlavy spláchnutý na disk. V tomto bode je možné vykonať niekoľko takýchto operácií.

Analýza TSDB v programe Prometheus 2

Zdá sa, že zhutňovanie nie je žiadnym spôsobom obmedzené a môže spôsobiť veľké I/O špičky disku počas vykonávania.

Analýza TSDB v programe Prometheus 2

Špičky zaťaženia CPU

Analýza TSDB v programe Prometheus 2

To má, samozrejme, dosť negatívny vplyv na rýchlosť systému a tiež predstavuje vážnu výzvu pre úložisko LSM: ako urobiť zhutnenie, aby sa podporila vysoká miera požiadaviek bez toho, aby to spôsobovalo príliš veľa réžie?
Celkom zaujímavo vyzerá aj využitie pamäte v procese zhutňovania.

Analýza TSDB v programe Prometheus 2

Vidíme, ako po zhutnení väčšina pamäte zmení stav z Cached na Free: to znamená, že odtiaľ boli odstránené potenciálne cenné informácie. Zaujímalo by ma, či sa to tu používa fadvice() alebo nejaká iná minimalizačná technika, alebo je to preto, že cache bola uvoľnená z blokov zničených počas zhutňovania?

Obnova po zlyhaní

Zotavenie po zlyhaniach si vyžaduje čas a má to dobrý dôvod. Pri prichádzajúcom toku s miliónom záznamov za sekundu som musel čakať asi 25 minút, kým sa obnova vykonala s prihliadnutím na jednotku SSD.

level=info ts=2018-09-13T13:38:14.09650965Z caller=main.go:222 msg="Starting Prometheus" version="(version=2.3.2, branch=v2.3.2, revision=71af5e29e815795e9dd14742ee7725682fa14b7b)"
level=info ts=2018-09-13T13:38:14.096599879Z caller=main.go:223 build_context="(go=go1.10.1, user=Jenkins, date=20180725-08:58:13OURCE)"
level=info ts=2018-09-13T13:38:14.096624109Z caller=main.go:224 host_details="(Linux 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 1bee9e9b78cf (none))"
level=info ts=2018-09-13T13:38:14.096641396Z caller=main.go:225 fd_limits="(soft=1048576, hard=1048576)"
level=info ts=2018-09-13T13:38:14.097715256Z caller=web.go:415 component=web msg="Start listening for connections" address=:9090
level=info ts=2018-09-13T13:38:14.097400393Z caller=main.go:533 msg="Starting TSDB ..."
level=info ts=2018-09-13T13:38:14.098718401Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536530400000 maxt=1536537600000 ulid=01CQ0FW3ME8Q5W2AN5F9CB7R0R
level=info ts=2018-09-13T13:38:14.100315658Z caller=web.go:467 component=web msg="router prefix" prefix=/prometheus
level=info ts=2018-09-13T13:38:14.101793727Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536732000000 maxt=1536753600000 ulid=01CQ78486TNX5QZTBF049PQHSM
level=info ts=2018-09-13T13:38:14.102267346Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536537600000 maxt=1536732000000 ulid=01CQ78DE7HSQK0C0F5AZ46YGF0
level=info ts=2018-09-13T13:38:14.102660295Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536775200000 maxt=1536782400000 ulid=01CQ7SAT4RM21Y0PT5GNSS146Q
level=info ts=2018-09-13T13:38:14.103075885Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536753600000 maxt=1536775200000 ulid=01CQ7SV8WJ3C2W5S3RTAHC2GHB
level=error ts=2018-09-13T14:05:18.208469169Z caller=wal.go:275 component=tsdb msg="WAL corruption detected; truncating" err="unexpected CRC32 checksum d0465484, want 0" file=/opt/prometheus/data/.prom2-data/wal/007357 pos=15504363
level=info ts=2018-09-13T14:05:19.471459777Z caller=main.go:543 msg="TSDB started"
level=info ts=2018-09-13T14:05:19.471604598Z caller=main.go:603 msg="Loading configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499156711Z caller=main.go:629 msg="Completed loading of configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499228186Z caller=main.go:502 msg="Server is ready to receive web requests."

Hlavným problémom procesu obnovy je vysoká spotreba pamäte. Napriek tomu, že v normálnej situácii môže server pracovať stabilne s rovnakým množstvom pamäte, v prípade zlyhania sa nemusí obnoviť kvôli OOM. Jediné riešenie, ktoré som našiel, bolo zakázať zhromažďovanie údajov, spustiť server, nechať ho obnoviť a reštartovať s povoleným zberom.

Zahrejte sa

Ďalším správaním, ktoré treba mať na pamäti počas zahrievania, je vzťah medzi nízkym výkonom a vysokou spotrebou zdrojov hneď po štarte. Počas niektorých, ale nie všetkých spustení, som pozoroval vážne zaťaženie CPU a pamäte.

Analýza TSDB v programe Prometheus 2

Analýza TSDB v programe Prometheus 2

Medzery vo využívaní pamäte naznačujú, že Prometheus nemôže nakonfigurovať všetky kolekcie od začiatku a niektoré informácie sa stratia.
Na presné dôvody vysokej záťaže CPU a pamäte som neprišiel. Mám podozrenie, že je to spôsobené tvorbou nových časových radov v hlavovom bloku s vysokou frekvenciou.

Nárazy zaťaženia CPU

Okrem zhutnenia, ktoré spôsobuje pomerne vysoké zaťaženie I/O, som si každé dve minúty všimol vážne skoky v zaťažení procesora. Výbuchy sú dlhšie, keď je vstupný tok vysoký a zdá sa, že sú spôsobené zberačom odpadu Go, pričom aspoň niektoré jadrá sú plne zaťažené.

Analýza TSDB v programe Prometheus 2

Analýza TSDB v programe Prometheus 2

Tieto skoky nie sú až také bezvýznamné. Zdá sa, že keď k tomu dôjde, interný vstupný bod a metriky Prometheus sa stanú nedostupnými, čo spôsobí medzery v údajoch počas rovnakých časových období.

Analýza TSDB v programe Prometheus 2

Môžete si tiež všimnúť, že exportér Prometheus sa na jednu sekundu vypne.

Analýza TSDB v programe Prometheus 2

Môžeme si všimnúť korelácie s garbage collection (GC).

Analýza TSDB v programe Prometheus 2

Záver

TSDB v Prometheus 2 je rýchly, dokáže spracovať milióny časových radov a zároveň tisíce záznamov za sekundu pomocou pomerne skromného hardvéru. Pôsobivé je aj využitie CPU a diskových I/O. Môj príklad ukázal až 200 000 metrík za sekundu na použité jadro.

Ak chcete naplánovať rozšírenie, musíte pamätať na dostatočné množstvo pamäte, a to musí byť skutočná pamäť. Množstvo použitej pamäte, ktoré som pozoroval, bolo asi 5 GB na 100 000 záznamov za sekundu prichádzajúceho toku, čo spolu s vyrovnávacou pamäťou operačného systému dávalo asi 8 GB obsadenej pamäte.

Samozrejme, stále je potrebné vykonať veľa práce na krotení špičiek CPU a diskov I/O, a to nie je prekvapujúce vzhľadom na to, aký mladý je TSDB Prometheus 2 v porovnaní s InnoDB, TokuDB, RocksDB, WiredTiger, ale všetky mali podobné problémy na začiatku ich životného cyklu.

Zdroj: hab.com

Pridať komentár