Anàlisi de TSDB a Prometheus 2

Anàlisi de TSDB a Prometheus 2

La base de dades de sèries temporals (TSDB) de Prometheus 2 és un gran exemple de solució d'enginyeria que ofereix millores significatives respecte a l'emmagatzematge de Prometheus 2 v1 en termes de recollida de dades i velocitat d'execució de consultes i eficiència dels recursos. Estàvem implementant Prometheus 2 a Percona Monitoring and Management (PMM) i vaig tenir l'oportunitat d'entendre el rendiment de Prometheus 2 TSDB. En aquest article parlaré dels resultats d'aquestes observacions.

Càrrega de treball mitjana de Prometheus

Per a aquells acostumats a tractar amb bases de dades de propòsit general, la càrrega de treball típica de Prometheus és força interessant. La taxa d'acumulació de dades acostuma a ser estable: normalment els serveis que controleu envien aproximadament la mateixa quantitat de mètriques i la infraestructura canvia relativament lentament.
Les sol·licituds d'informació poden provenir de diverses fonts. Alguns d'ells, com les alertes, també tenen com a objectiu un valor estable i previsible. Altres, com les sol·licituds dels usuaris, poden provocar pics, tot i que aquest no és el cas de la major part de la càrrega de treball.

Prova de càrrega

Durant les proves, em vaig centrar en la capacitat d'acumular dades. Vaig implementar Prometheus 2.3.2 compilat amb Go 1.10.1 (com a part de PMM 1.14) en un servei Linode mitjançant aquest script: StackScript. Per a la generació de càrrega més realista, amb això StackScript Vaig executar diversos nodes MySQL amb una càrrega real (Sysbench TPC-C Test), cadascun dels quals emulava 10 nodes Linux/MySQL.
Totes les proves següents es van realitzar en un servidor Linode amb vuit vCore i 32 GB de memòria, executant 20 simulacions de càrrega monitoritzant 800 instàncies MySQL. O, pel que fa a Prometeu, 440 objectius (objectius), 380 tarifes (scrapes) per segon, 1,7 mil registres (mostres) per segon i XNUMX milions de sèries temporals actives.

Disseny

L'enfocament de base de dades tradicional habitual, inclòs el que fa servir Prometheus 1.x, és límit de memòria. Si no n'hi ha prou per gestionar la càrrega, experimentaràs una alta latència i algunes sol·licituds no es compliran. L'ús de la memòria a Prometheus 2 es pot configurar mitjançant una tecla storage.tsdb.min-block-duration, que determina quant de temps es mantindran els registres a la memòria abans d'esborrar-los al disc (el valor per defecte és 2 hores). La quantitat de memòria necessària dependrà del nombre de sèries temporals, etiquetes i scrapes, més l'entrada neta. Pel que fa a l'espai en disc, Prometheus pretén utilitzar 3 bytes per escriptura (mostra). D'altra banda, els requisits de memòria són molt més elevats.

Tot i que és possible configurar la mida del bloc, no es recomana configurar-lo manualment, de manera que us queda la tasca de donar a Prometheus tanta memòria com necessiti per a la vostra càrrega de treball.
Si no hi ha prou memòria per suportar el flux entrant de mètriques, Prometheus caurà de la memòria o serà atrapat per un assassí OOM.
Afegir un intercanvi per retardar l'accident quan Prometheus s'esgota la memòria no ajuda realment, perquè utilitzar aquesta funció provoca explosions de memòria. Crec que es tracta de Go, el seu col·lector d'escombraries, i de com funciona amb l'intercanvi.
Un altre enfocament interessant és configurar el bloc de capçal perquè s'encarregui al disc en un moment determinat, en lloc de comptar-lo des del moment en què va començar el procés.

Anàlisi de TSDB a Prometheus 2

Com podeu veure al gràfic, els buids al disc es produeixen cada dues hores. Si canvieu el paràmetre min-block-duration a una hora, aquests restabliments es faran cada hora, començant en mitja hora.
Si voleu utilitzar aquest i altres gràfics a la vostra instal·lació de Prometheus, podeu utilitzar-lo panell. Va ser dissenyat per a PMM, però amb algunes modificacions s'adapta a qualsevol instal·lació de Prometheus.
Tenim un bloc actiu, anomenat bloc cap, que s'emmagatzema a la memòria; els blocs amb dades més antigues estan disponibles mitjançant mmap(). Això elimina la necessitat de configurar la memòria cau per separat, però també significa que heu de deixar prou espai per a la memòria cau del sistema operatiu si voleu consultar dades més antigues que el bloc de capçalera.
També vol dir que el consum de memòria virtual de Prometheus semblarà bastant alt, cosa que no cal preocupar-se.

Anàlisi de TSDB a Prometheus 2

Un altre punt de disseny interessant és l'ús de WAL (write ahead log). Com podeu veure a la documentació del dipòsit, Prometheus utilitza WAL per evitar bloquejos. Els mecanismes específics per garantir la supervivència de les dades, malauradament, no estan ben documentats. Prometheus 2.3.2 buida WAL al disc cada 10 segons i aquesta configuració no es pot configurar per l'usuari.

Foques

Prometheus TSDB està dissenyat de la mateixa manera que l'emmagatzematge LSM (Log Structured merge): el bloc principal s'envia periòdicament al disc, mentre que el mecanisme de compactació fusiona diversos blocs per evitar escanejar massa blocs a les consultes. Aquí podeu veure el nombre de blocs que vaig observar al sistema de prova després d'un dia de càrrega.

Anàlisi de TSDB a Prometheus 2

Si voleu obtenir més informació sobre l'emmagatzematge, podeu consultar el fitxer meta.json, que conté informació sobre els blocs disponibles i com es van produir.

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

Els segells de Prometheus estan lligats al moment en què el bloc del cap s'aboca al disc. En aquest punt, es poden dur a terme diverses operacions d'aquest tipus.

Anàlisi de TSDB a Prometheus 2

Sembla que les compactacions no estan limitades de cap manera i poden provocar grans pics d'E/S de disc durant l'execució.

Anàlisi de TSDB a Prometheus 2

Pics de càrrega de la CPU

Anàlisi de TSDB a Prometheus 2

Per descomptat, això té un efecte força negatiu en la velocitat del sistema i també és un repte seriós per als emmagatzematges LSM: com fer compactacions per suportar altes velocitats de consulta sense causar massa sobrecàrrega?
L'ús de la memòria en el procés de compactació també sembla força curiós.

Anàlisi de TSDB a Prometheus 2

Podem veure com, després de la compactació, la major part de la memòria canvia d'estat de Cached a Free: vol dir que la informació potencialment valuosa s'ha eliminat d'allà. És curiós si s'utilitza aquí fadvice() o alguna altra tècnica de minimització, o és perquè la memòria cau s'ha buidat de blocs destruïts per la compactació?

Recuperació d'errors

La recuperació de desastres requereix temps i per una bona raó. Per a un flux entrant d'un milió de registres per segon, vaig haver d'esperar uns 25 minuts mentre la recuperació tenia en compte la unitat 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."

El principal problema del procés de recuperació és l'elevat consum de memòria. Tot i que el servidor pot funcionar de manera estable amb la mateixa quantitat de memòria en una situació normal, si es bloqueja, és possible que no augmenti a causa de l'OOM. L'única solució que he trobat és desactivar la recollida de dades, activar el servidor, deixar que es recuperi i reiniciar amb la recollida activada.

Escalfant

Un altre comportament a tenir en compte durant l'escalfament és la relació entre el baix rendiment i l'alt consum de recursos just després de l'inici. Durant alguns inicis, però no tots, vaig observar una càrrega greu a la CPU i la memòria.

Anàlisi de TSDB a Prometheus 2

Anàlisi de TSDB a Prometheus 2

Les caigudes en l'ús de la memòria indiquen que Prometheus no pot configurar totes les tarifes des del principi i que es perd part d'informació.
No he esbrinat els motius exactes de l'elevat ús de la CPU i la memòria. Sospito que això es deu a la creació de noves sèries temporals al bloc de capçalera amb una freqüència elevada.

Punts de CPU

A més de les densificacions, que creen una càrrega d'E/S força alta, he notat pics greus en la càrrega de la CPU cada dos minuts. Les ràfegues són més llargues amb un gran trànsit entrant i sembla que són causades pel col·lector d'escombraries Go, almenys alguns nuclis estan completament carregats.

Anàlisi de TSDB a Prometheus 2

Anàlisi de TSDB a Prometheus 2

Aquests salts no són tan insignificants. Sembla que quan es produeixen, el punt d'entrada intern de Prometheus i les mètriques no estan disponibles, provocant caigudes de dades en els mateixos intervals de temps.

Anàlisi de TSDB a Prometheus 2

També podeu notar que l'exportador de Prometheus s'apaga durant un segon.

Anàlisi de TSDB a Prometheus 2

Podem veure correlacions amb la recollida d'escombraries (GC).

Anàlisi de TSDB a Prometheus 2

Conclusió

TSDB a Prometheus 2 és ràpid, capaç de gestionar milions de sèries temporals i alhora milers d'escriptures per segon utilitzant un maquinari força modest. La utilització d'E/S de la CPU i del disc també és impressionant. El meu exemple mostrava fins a 200 mètriques per segon per nucli utilitzat.

Per planificar l'expansió, cal recordar que hi ha prou memòria i que ha de ser memòria real. La quantitat de memòria utilitzada, que vaig observar, era d'uns 5 GB per cada 100 registres per segon del flux entrant, que, en total amb la memòria cau del sistema operatiu, donava uns 000 GB de memòria ocupada.

Per descomptat, encara queda molta feina per fer per controlar els pics d'E/S de la CPU i del disc, i això no és sorprenent, tenint en compte com es compara el jove TSDB Prometheus 2 amb InnoDB, TokuDB, RocksDB, WiredTiger, però tots tenien problemes similars al començament del seu cicle de vida.

Font: www.habr.com

Afegeix comentari