TSDB analiza u Prometeju 2

TSDB analiza u Prometeju 2

Baza podataka vremenskih serija (TSDB) u Prometheusu 2 izvrstan je primjer inženjerskog rješenja koje nudi velika poboljšanja u odnosu na v2 pohranu u Prometheusu 1 u smislu akumulacije podataka i brzine izvršavanja upita te učinkovitosti resursa. Implementirali smo Prometheus 2 u Percona Monitoring and Management (PMM) i imao sam priliku razumjeti performanse Prometheusa 2 TSDB. U ovom ću članku govoriti o rezultatima tih promatranja.

Prosječno radno opterećenje Prometheusa

Za one koji su navikli raditi s bazama podataka opće namjene, tipično Prometheusovo radno opterećenje prilično je zanimljivo. Brzina prikupljanja podataka obično je stabilna: obično usluge koje nadzirete šalju približno isti broj metrika, a infrastruktura se mijenja relativno sporo.
Zahtjevi za informacijama mogu doći iz različitih izvora. Neki od njih, poput upozorenja, također teže stabilnoj i predvidljivoj vrijednosti. Drugi, kao što su korisnički zahtjevi, mogu uzrokovati pucanje, iako to nije slučaj za većinu radnih opterećenja.

Test opterećenja

Tijekom testiranja usredotočio sam se na sposobnost prikupljanja podataka. Postavio sam Prometheus 2.3.2 kompajliran s Go 1.10.1 (kao dio PMM-a 1.14) na servis Linode pomoću ove skripte: StackScript. Za najrealističniju generaciju opterećenja, koristite ovo StackScript Pokrenuo sam nekoliko MySQL čvorova sa stvarnim opterećenjem (Sysbench TPC-C Test), od kojih je svaki emulirao 10 Linux/MySQL čvorova.
Svi sljedeći testovi izvedeni su na Linode poslužitelju s osam virtualnih jezgri i 32 GB memorije, uz pokretanje 20 simulacija opterećenja koje prate dvjesto MySQL instanci. Ili, Prometejevim rječnikom rečeno, 800 ciljeva, 440 struganja u sekundi, 380 tisuća zapisa u sekundi i 1,7 milijuna aktivnih vremenskih serija.

Dizajn

Uobičajeni pristup tradicionalnih baza podataka, uključujući onu koju koristi Prometheus 1.x, je da se ograničenje memorije. Ako to nije dovoljno za podnošenje opterećenja, doživjet ćete velike latencije i neki zahtjevi neće uspjeti. Korištenje memorije u Prometheusu 2 može se konfigurirati putem tipke storage.tsdb.min-block-duration, koji određuje koliko dugo će se snimke čuvati u memoriji prije ispiranja na disk (zadano je 2 sata). Količina potrebne memorije ovisit će o broju vremenskih nizova, oznaka i struganja dodanih u neto dolazni tok. Što se tiče prostora na disku, Prometheus ima za cilj koristiti 3 bajta po zapisu (uzorku). S druge strane, memorijski zahtjevi su puno veći.

Iako je moguće konfigurirati veličinu bloka, ne preporučuje se ručno konfigurirati, tako da ste prisiljeni dati Prometheusu onoliko memorije koliko je potrebno za vaše radno opterećenje.
Ako nema dovoljno memorije za podršku dolaznog toka metrike, Prometheus će ispasti iz memorije ili će OOM ubojica doći do njega.
Dodavanje swapa za odgodu rušenja kada Prometheusu ponestane memorije zapravo ne pomaže, jer korištenje ove funkcije uzrokuje eksplozivnu potrošnju memorije. Mislim da je to povezano s Goom, njegovim skupljačem smeća i načinom na koji se nosi sa swapom.
Još jedan zanimljiv pristup je konfigurirati glavni blok da se ispere na disk u određeno vrijeme, umjesto da se broji od početka procesa.

TSDB analiza u Prometeju 2

Kao što možete vidjeti na grafikonu, ispiranje na disk događa se svaka dva sata. Ako promijenite parametar min-block-duration na jedan sat, ta će se poništavanja događati svaki sat, počevši nakon pola sata.
Ako želite koristiti ovaj i druge grafikone u svojoj Prometheus instalaciji, možete koristiti ovaj nadzorna ploča. Dizajniran je za PMM, ali uz male izmjene uklapa se u bilo koju Prometheus instalaciju.
Imamo aktivni blok koji se zove glavni blok koji je pohranjen u memoriji; blokovi sa starijim podacima dostupni su putem mmap(). Ovo eliminira potrebu za zasebnim konfiguriranjem predmemorije, ali također znači da morate ostaviti dovoljno prostora za predmemoriju operativnog sustava ako želite postavljati upite o podacima starijim od onoga što glavni blok može primiti.
To također znači da će Prometheusova potrošnja virtualne memorije izgledati prilično visoka, što ne treba brinuti.

TSDB analiza u Prometeju 2

Još jedna zanimljiva točka dizajna je korištenje WAL-a (write ahead log). Kao što možete vidjeti iz dokumentacije za pohranu, Prometheus koristi WAL kako bi izbjegao padove. Specifični mehanizmi za jamčenje opstojnosti podataka, nažalost, nisu dobro dokumentirani. Prometheus verzija 2.3.2 ispire WAL na disk svakih 10 sekundi i ovu opciju korisnik ne može konfigurirati.

Zbijanja

Prometheus TSDB dizajniran je kao LSM (Log Structured Merge) pohrana: glavni blok se povremeno ispire na disk, dok mehanizam sažimanja kombinira više blokova zajedno kako bi se izbjeglo skeniranje previše blokova tijekom upita. Ovdje možete vidjeti broj blokova koje sam primijetio na testnom sustavu nakon dana opterećenja.

TSDB analiza u Prometeju 2

Ako želite saznati više o trgovini, možete pregledati datoteku meta.json koja sadrži informacije o dostupnim blokovima i kako su nastali.

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

Zbijanja u Prometheusu vezana su uz vrijeme ispiranja bloka glave na disk. U ovom trenutku može se provesti nekoliko takvih operacija.

TSDB analiza u Prometeju 2

Čini se da zbijanja nisu ni na koji način ograničena i mogu uzrokovati velike I/O skokove diska tijekom izvođenja.

TSDB analiza u Prometeju 2

skokovi opterećenja CPU-a

TSDB analiza u Prometeju 2

Naravno, to ima prilično negativan utjecaj na brzinu sustava, a također predstavlja ozbiljan izazov za LSM pohranu: kako izvesti sažimanje da bi se podržale visoke stope zahtjeva bez izazivanja prevelikih troškova?
Korištenje memorije u procesu zbijanja također izgleda prilično zanimljivo.

TSDB analiza u Prometeju 2

Možemo vidjeti kako, nakon sažimanja, većina memorije mijenja stanje iz Predmemorirano u Slobodno: to znači da su potencijalno vrijedne informacije odatle uklonjene. Zanima me koristi li se ovdje fadvice() ili neka druga tehnika minimiziranja, ili je to zato što je predmemorija oslobođena blokova uništenih tijekom sažimanja?

Oporavak nakon neuspjeha

Za oporavak od neuspjeha potrebno je vrijeme, i to s dobrim razlogom. Za dolazni tok od milijun zapisa u sekundi, morao sam čekati oko 25 minuta dok se oporavak izvodio uzimajući u obzir SSD pogon.

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."

Glavni problem procesa oporavka je velika potrošnja memorije. Unatoč činjenici da u normalnoj situaciji poslužitelj može raditi stabilno s istom količinom memorije, ako se sruši, možda se neće oporaviti zbog OOM-a. Jedino rješenje koje sam pronašao bilo je onemogućiti prikupljanje podataka, pokrenuti poslužitelj, pustiti ga da se oporavi i ponovno pokrenuti s omogućenim prikupljanjem.

Zagrijavanje

Još jedno ponašanje koje treba imati na umu tijekom zagrijavanja je odnos između niske izvedbe i velike potrošnje resursa odmah nakon starta. Tijekom nekih, ali ne svih pokretanja, primijetio sam ozbiljno opterećenje CPU-a i memorije.

TSDB analiza u Prometeju 2

TSDB analiza u Prometeju 2

Rupe u korištenju memorije pokazuju da Prometheus ne može konfigurirati sve zbirke od početka, a neke informacije su izgubljene.
Nisam otkrio točne razloge velikog opterećenja procesora i memorije. Sumnjam da je to zbog stvaranja novih vremenskih serija u bloku glave s visokom frekvencijom.

skokovi opterećenja CPU-a

Osim zbijanja, koja stvaraju prilično veliko I/O opterećenje, primijetio sam ozbiljne skokove u opterećenju CPU-a svake dvije minute. Burstovi su duži kada je ulazni protok visok i čini se da ih uzrokuje Go sakupljač smeća, pri čemu su barem neke jezgre potpuno učitane.

TSDB analiza u Prometeju 2

TSDB analiza u Prometeju 2

Ti skokovi i nisu tako beznačajni. Čini se da kada se to dogodi, Prometheusova interna ulazna točka i metrika postaju nedostupni, uzrokujući praznine u podacima tijekom tih istih vremenskih razdoblja.

TSDB analiza u Prometeju 2

Također možete primijetiti da se Prometheus izvoznik gasi na jednu sekundu.

TSDB analiza u Prometeju 2

Možemo uočiti korelacije sa skupljanjem smeća (GC).

TSDB analiza u Prometeju 2

Zaključak

TSDB u Prometheusu 2 je brz, sposoban rukovati milijunima vremenskih serija i istovremeno tisućama zapisa u sekundi koristeći prilično skroman hardver. CPU i disk I/O iskoristivost je također impresivna. Moj primjer pokazao je do 200 000 metrika u sekundi po korištenoj jezgri.

Da biste planirali proširenje, morate se sjetiti dovoljne količine memorije, a to mora biti prava memorija. Količina korištene memorije koju sam primijetio bila je oko 5 GB na 100 000 zapisa u sekundi dolaznog toka, što je zajedno s predmemorijom operativnog sustava davalo oko 8 GB zauzete memorije.

Naravno, ima još puno posla da se ukrote CPU i disk I/O skokovi, a to ne čudi s obzirom na to koliko je TSDB Prometheus 2 mlad u usporedbi s InnoDB-om, TokuDB-om, RocksDB-om, WiredTigerom, ali svi su imali slično probleme rano u svom životnom ciklusu.

Izvor: www.habr.com

Dodajte komentar