Analýza TSDB v Prometheus 2

Analýza TSDB v Prometheus 2

Databáze časových řad (TSDB) v Prometheus 2 je skvělým příkladem inženýrského řešení, které nabízí významná vylepšení oproti úložišti Prometheus 2 v1, pokud jde o sběr dat a rychlost provádění dotazů a efektivitu zdrojů. Implementovali jsme Prometheus 2 v Percona Monitoring and Management (PMM) a měl jsem příležitost porozumět výkonu Prometheus 2 TSDB. V tomto článku budu hovořit o výsledcích těchto pozorování.

Průměrná pracovní zátěž Prometheus

Pro ty, kteří jsou zvyklí pracovat s databázemi pro obecné účely, je typická zátěž Prometheus docela zajímavá. Rychlost akumulace dat bývá stabilní: služby, které monitorujete, obvykle odesílají přibližně stejné množství metrik a infrastruktura se mění relativně pomalu.
Žádosti o informace mohou pocházet z různých zdrojů. Některé z nich, jako například výstrahy, se také zaměřují na stabilní a předvídatelnou hodnotu. Jiné, například požadavky uživatelů, mohou způsobit špičky, i když tomu tak není u většiny zátěže.

Zátěžový test

Při testování jsem se zaměřil na schopnost akumulovat data. Nasadil jsem Prometheus 2.3.2 zkompilovaný s Go 1.10.1 (jako součást PMM 1.14) na službu Linode pomocí tohoto skriptu: StackScript. Pro co nejrealističtější generování zátěže s tímto StackScript Spustil jsem několik uzlů MySQL s reálnou zátěží (Sysbench TPC-C Test), z nichž každý emuloval 10 uzlů Linux/MySQL.
Všechny následující testy byly provedeny na serveru Linode s osmi virtuálními jádry a 32 GB paměti, na kterých bylo spuštěno 20 simulací zatížení monitorujících 800 instancí MySQL. Nebo, pokud jde o Prometheus, 440 cílů (cílů), 380 poplatků (sškrabů) za sekundu, 1,7 tisíc záznamů (vzorků) za sekundu a XNUMX milionu aktivních časových řad.

Design

Obvyklý tradiční databázový přístup, včetně toho, který používá Prometheus 1.x, je limit paměti. Pokud to nestačí zvládnout zátěž, zaznamenáte vysokou latenci a některé požadavky nebudou splněny. Využití paměti v Prometheus 2 je konfigurovatelné pomocí klíče storage.tsdb.min-block-duration, který určuje, jak dlouho budou záznamy uchovány v paměti, než budou vyprázdněny na disk (výchozí nastavení jsou 2 hodiny). Množství potřebné paměti bude záviset na počtu časových řad, štítků a škrábanců plus čistého vstupu. Pokud jde o místo na disku, Prometheus má za cíl použít 3 bajty na zápis (ukázka). Na druhou stranu jsou nároky na paměť mnohem vyšší.

I když je možné konfigurovat velikost bloku, nedoporučuje se ji nastavovat ručně, takže zbývá úkol poskytnout Prometheus tolik paměti, kolik potřebuje pro vaši pracovní zátěž.
Pokud není dostatek paměti pro podporu příchozího proudu metrik, Prometheus vypadne z paměti nebo bude chycen OOM zabijákem.
Přidání swapu pro oddálení pádu, když Prometheus dojde paměť, ve skutečnosti nepomůže, protože použití této funkce způsobuje exploze paměti. Myslím, že je to o Go, jeho garbage collectoru a o tom, jak to funguje se swapem.
Dalším zajímavým přístupem je nastavit blok hlavy tak, aby byl vyprázdněn na disk v určitou dobu, namísto počítání od začátku procesu.

Analýza TSDB v Prometheus 2

Jak můžete vidět z grafu, k vyplachování disku dochází každé dvě hodiny. Pokud změníte parametr min-block-duration na jednu hodinu, pak k těmto resetům dojde každou hodinu, počínaje půlhodinou.
Pokud chcete použít tento a další grafy ve své instalaci Prometheus, můžete použít toto přístrojová deska. Byl navržen pro PMM, ale s několika úpravami se hodí do každé instalace Prometheus.
Máme aktivní blok, nazývaný blok hlavy, který je uložen v paměti; bloky se staršími daty jsou dostupné přes mmap(). To odstraňuje potřebu konfigurovat mezipaměť samostatně, ale také to znamená, že musíte ponechat dostatek místa pro mezipaměť operačního systému, pokud chcete dotazovat data starší než blok hlavy.
Znamená to také, že spotřeba virtuální paměti Promethea bude vypadat poměrně vysoká, čehož se není třeba obávat.

Analýza TSDB v Prometheus 2

Dalším zajímavým designovým bodem je použití WAL (write advance log). Jak můžete vidět z dokumentace úložiště, Prometheus používá WAL, aby se vyhnul pádům. Konkrétní mechanismy pro zaručení přežití dat bohužel nejsou dobře zdokumentovány. Prometheus 2.3.2 vyprázdní WAL na disk každých 10 sekund a toto nastavení není uživatelsky konfigurovatelné.

těsnění

Prometheus TSDB je navrženo stejným způsobem jako úložiště LSM (Log Structured merge): blok hlavy je pravidelně vyplachován na disk, zatímco zhutňovací mechanismus spojuje více bloků dohromady, aby se zabránilo skenování příliš mnoha bloků na dotazy. Zde vidíte počet bloků, které jsem pozoroval na testovacím systému po dni zátěže.

Analýza TSDB v Prometheus 2

Pokud se chcete o úložišti dozvědět více, můžete se podívat na soubor meta.json, který obsahuje informace o dostupných blocích a o tom, jak k nim došlo.

{
       "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
}

Těsnění v Prometheus jsou svázána s časem, kdy je blok hlavy vypláchnut do disku. V tomto okamžiku může být provedeno několik takových operací.

Analýza TSDB v Prometheus 2

Zdá se, že komprimace nejsou nijak omezeny a mohou způsobit velké diskové I/O špičky během provádění.

Analýza TSDB v Prometheus 2

špičky zatížení CPU

Analýza TSDB v Prometheus 2

To má samozřejmě spíše negativní vliv na rychlost systému a je to také vážná výzva pro úložiště LSM: jak provést komprimaci pro podporu vysokých rychlostí dotazů, aniž by to způsobilo příliš velkou režii?
Docela kuriózně vypadá i využití paměti v procesu zhutňování.

Analýza TSDB v Prometheus 2

Můžeme vidět, jak po komprimaci většina paměti změní stav z mezipaměti na volnou: to znamená, že odtud byly odstraněny potenciálně cenné informace. Zajímalo by mě, jestli se to tady používá fadvice() nebo nějaká jiná minimalizační technika, nebo je to tím, že cache byla vyprázdněna od bloků zničených komprimací?

Obnova po selhání

Obnova po katastrofě vyžaduje čas a má k tomu dobrý důvod. U příchozího streamu milionu záznamů za sekundu jsem musel čekat asi 25 minut, zatímco obnova zohledňovala SSD disk.

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émem procesu obnovy je vysoká spotřeba paměti. I když server může v normální situaci pracovat stabilně se stejným množstvím paměti, pokud dojde k jeho zhroucení, nemusí se kvůli OOM zvýšit. Jediné řešení, které jsem našel, je vypnout shromažďování dat, spustit server, nechat ho obnovit a restartovat s povoleným shromažďováním.

Zahřát se

Dalším chováním, které je třeba mít na paměti během zahřívání, je poměr nízkého výkonu k vysoké spotřebě zdrojů hned po spuštění. Během některých, ale ne všech startů, jsem pozoroval vážné zatížení CPU a paměti.

Analýza TSDB v Prometheus 2

Analýza TSDB v Prometheus 2

Pokles využití paměti naznačuje, že Prometheus nemůže od začátku nakonfigurovat všechny poplatky a některé informace jsou ztraceny.
Přesné důvody vysokého využití CPU a paměti jsem nezjistil. Mám podezření, že je to způsobeno vytvářením nových časových řad v hlavovém bloku s vysokou frekvencí.

CPU špičky

Kromě zhuštění, které vytváří poměrně vysoké I/O zatížení, jsem zaznamenal každé dvě minuty vážné skoky v zatížení CPU. Shluky jsou delší při vysokém příchozím provozu a vypadají, jako by je způsobil Go garbage collector, alespoň některá jádra jsou plně zatížená.

Analýza TSDB v Prometheus 2

Analýza TSDB v Prometheus 2

Tyto skoky nejsou tak bezvýznamné. Zdá se, že když k nim dojde, interní vstupní bod a metriky Prometheus se stanou nedostupnými, což způsobí poklesy dat ve stejných časových intervalech.

Analýza TSDB v Prometheus 2

Můžete si také všimnout, že exportér Prometheus se na jednu sekundu vypne.

Analýza TSDB v Prometheus 2

Můžeme vidět korelace s garbage collection (GC).

Analýza TSDB v Prometheus 2

Závěr

TSDB v Prometheus 2 je rychlý, schopný zpracovat miliony časových řad a zároveň tisíce záznamů za sekundu pomocí poměrně skromného hardwaru. Působivé je také využití CPU a diskových I/O. Můj příklad ukázal až 200 000 metrik za sekundu na použité jádro.

Chcete-li plánovat rozšíření, musíte mít na paměti, že je dostatek paměti a musí to být skutečná paměť. Množství použité paměti, které jsem pozoroval, bylo asi 5 GB na 100 000 záznamů za sekundu příchozího streamu, což dohromady s mezipamětí operačního systému dalo asi 8 GB obsazené paměti.

Samozřejmě je ještě potřeba udělat hodně práce na zkrocení špiček CPU a disků I/O, a to není překvapivé, vzhledem k tomu, jak mladý je TSDB Prometheus 2 ve srovnání s InnoDB, TokuDB, RocksDB, WiredTiger, ale všichni měli podobné problémy na začátku jejich životního cyklu.

Zdroj: www.habr.com

Přidat komentář