TSDB анализ в Prometheus 2

TSDB анализ в Prometheus 2

Базата данни с времеви редове (TSDB) в Prometheus 2 е чудесен пример за инженерно решение, което предлага значителни подобрения спрямо Prometheus 2 storage v1 по отношение на събирането на данни и скоростта на изпълнение на заявките и ефективността на ресурсите. Внедрявахме Prometheus 2 в Percona Monitoring and Management (PMM) и имах възможност да разбера ефективността на Prometheus 2 TSDB. В тази статия ще говоря за резултатите от тези наблюдения.

Prometheus Средно натоварване

За тези, които са свикнали да работят с бази данни с общо предназначение, типичното работно натоварване на Prometheus е доста интересно. Скоростта на натрупване на данни има тенденция към стабилна стойност: обикновено услугите, които наблюдавате, изпращат приблизително еднакво количество показатели, а инфраструктурата се променя относително бавно.
Заявките за информация могат да идват от различни източници. Някои от тях, като предупрежденията, също се стремят към стабилна и предвидима стойност. Други, като потребителски заявки, могат да причинят скокове, въпреки че това не е така за по-голямата част от работното натоварване.

Тест за натоварване

По време на тестването се съсредоточих върху способността за натрупване на данни. Разположих Prometheus 2.3.2, компилиран с Go 1.10.1 (като част от PMM 1.14) на услуга Linode, използвайки този скрипт: StackScript. За най-реалистично генериране на натоварване, с това StackScript Изпълних няколко MySQL възела с реално натоварване (Sysbench TPC-C Test), всеки от които емулира 10 Linux/MySQL възела.
Всички следните тестове бяха извършени на Linode сървър с осем vCores и 32 GB памет, изпълнявайки 20 симулации на натоварване, наблюдаващи 800 MySQL инстанции. Или, по отношение на Prometheus, 440 цели (цели), 380 такси (скрейпове) в секунда, 1,7 хиляди записа (проби) в секунда и XNUMX милиона активни времеви серии.

Дизайн

Обичайният традиционен подход към базата данни, включително този, използван от Prometheus 1.x, е да ограничение на паметта. Ако не е достатъчно, за да се справи с натоварването, ще изпитате голямо забавяне и някои заявки няма да бъдат изпълнени. Използването на паметта в Prometheus 2 може да се конфигурира чрез ключ storage.tsdb.min-block-duration, което определя колко дълго записите ще се съхраняват в паметта, преди да бъдат изхвърлени на диска (по подразбиране е 2 часа). Количеството необходима памет ще зависи от броя на времевите серии, етикетите и изтриванията, плюс нетния вход. По отношение на дисковото пространство, Prometheus цели да използва 3 байта на запис (проба). От друга страна, изискванията за памет са много по-високи.

Въпреки че е възможно да конфигурирате размера на блока, не се препоръчва да го задавате ръчно, така че вие ​​оставате със задачата да дадете на Prometheus толкова памет, колкото е необходима за вашето работно натоварване.
Ако няма достатъчно памет за поддържане на входящия поток от показатели, Prometheus ще изчезне от паметта или ще бъде хванат от OOM убиец.
Добавянето на swap за забавяне на срива, когато паметта на Prometheus свърши, всъщност не помага, защото използването на тази функция причинява експлозии на паметта. Мисля, че става въпрос за Go, неговия събирач на боклук и как работи със swap.
Друг интересен подход е да настроите главния блок да се изхвърля на диска в определено време, вместо да го броите от момента, в който процесът е започнал.

TSDB анализ в Prometheus 2

Както можете да видите от графиката, флъшовете към диска се случват на всеки два часа. Ако промените параметъра min-block-duration на един час, тогава тези нулирания ще се извършват на всеки час, започвайки след половин час.
Ако искате да използвате тази и други графики във вашата инсталация на Prometheus, можете да използвате тази табло. Той е проектиран за PMM, но с няколко модификации се вписва във всяка инсталация на Prometheus.
Имаме активен блок, наречен главен блок, който се съхранява в паметта; блоковете с по-стари данни са достъпни чрез mmap(). Това премахва необходимостта от отделно конфигуриране на кеша, но също така означава, че трябва да оставите достатъчно място за кеша на операционната система, ако искате да заявите данни, по-стари от главния блок.
Това също означава, че потреблението на виртуална памет на Prometheus ще изглежда доста високо, което не е повод за притеснение.

TSDB анализ в Prometheus 2

Друга интересна точка на дизайна е използването на WAL (дневник за запис напред). Както можете да видите от документацията на хранилището, Prometheus използва WAL, за да избегне сривове. Специфичните механизми за гарантиране на оцеляването на данните, за съжаление, не са добре документирани. Prometheus 2.3.2 изхвърля WAL на диск на всеки 10 секунди и тази настройка не може да се конфигурира от потребителя.

Уплътнения

Prometheus TSDB е проектиран по същия начин като LSM (Log Structured merge) съхранение: главният блок се изплаква периодично на диска, докато механизмът за уплътняване обединява множество блокове заедно, за да избегне сканирането на твърде много блокове при заявки. Тук можете да видите броя на блоковете, които наблюдавах на тестовата система след ден натоварване.

TSDB анализ в Prometheus 2

Ако искате да научите повече за съхранението, можете да разгледате файла meta.json, който съдържа информация за наличните блокове и как са възникнали.

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

Печатите в Prometheus са обвързани с времето, когато главният блок се промива към диска. В този момент могат да се извършат няколко такива операции.

TSDB анализ в Prometheus 2

Изглежда, че уплътняването не е ограничено по никакъв начин и може да причини големи I/O пикове на диска по време на изпълнение.

TSDB анализ в Prometheus 2

Пикове в натоварването на процесора

TSDB анализ в Prometheus 2

Разбира се, това има доста негативен ефект върху скоростта на системата и също така е сериозно предизвикателство за LSM хранилищата: как да направите компресии, за да поддържате високи скорости на заявки, без да причинявате твърде много разходи?
Използването на памет в процеса на уплътняване също изглежда доста любопитно.

TSDB анализ в Prometheus 2

Можем да видим как след компресиране повечето от паметта променя състоянието от Кеширана на Свободна: това означава, че потенциално ценна информация е премахната от там. Интересно дали се използва тук fadvice() или някаква друга техника за минимизиране, или е защото кешът е бил изпразнен от блокове, унищожени от уплътняването?

Възстановяване при срив

Възстановяването след бедствие отнема време и има основателна причина. За входящ поток от милион записа в секунда трябваше да изчакам около 25 минути, докато възстановяването вземаше предвид 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."

Основният проблем на процеса на възстановяване е високата консумация на памет. Въпреки че сървърът може да работи стабилно със същото количество памет в нормална ситуация, ако се срине, може да не се издигне поради OOM. Единственото решение, което намерих, е да изключа събирането на данни, да активирам сървъра, да го оставя да се възстанови и да рестартирам с активирано събиране.

Загрявам

Друго поведение, което трябва да имате предвид по време на загряване, е съотношението между ниска производителност и висока консумация на ресурси веднага след стартиране. При някои, но не при всички стартирания наблюдавах сериозно натоварване на процесора и паметта.

TSDB анализ в Prometheus 2

TSDB анализ в Prometheus 2

Спадовете в използването на паметта показват, че Prometheus не може да конфигурира всички такси от самото начало и част от информацията се губи.
Не открих точните причини за високото натоварване на процесора и паметта. Подозирам, че това се дължи на създаването на нови времеви редове в главния блок с висока честота.

пикове на процесора

В допълнение към уплътненията, които създават доста високо I/O натоварване, забелязах сериозни пикове в натоварването на процесора на всеки две минути. Избухванията са по-дълги с голям входящ трафик и изглеждат като причинени от Go garbage collector, поне някои ядра са напълно заредени.

TSDB анализ в Prometheus 2

TSDB анализ в Prometheus 2

Тези скокове не са толкова незначителни. Изглежда, че когато се появят, вътрешната входна точка и показателите на Prometheus стават недостъпни, причинявайки спадове на данните в същите интервали от време.

TSDB анализ в Prometheus 2

Може също да забележите, че износителят на Prometheus се изключва за една секунда.

TSDB анализ в Prometheus 2

Можем да видим корелации със събирането на отпадъци (GC).

TSDB анализ в Prometheus 2

Заключение

TSDB в Prometheus 2 е бърз, способен да обработва милиони времеви серии и в същото време хиляди записи в секунда, използвайки доста скромен хардуер. Използването на процесора и I/O на диска също е впечатляващо. Моят пример показа до 200 000 метрики в секунда на използвано ядро.

За да планирате разширение, трябва да запомните, че има достатъчно памет и трябва да е истинска памет. Количеството използвана памет, което наблюдавах, беше около 5 GB на 100 000 записа в секунда от входящия поток, което общо с кеша на операционната система дава около 8 GB заета памет.

Разбира се, има още много работа за овладяване на I/O скоковете на процесора и диска и това не е изненадващо, като се има предвид колко млад е TSDB Prometheus 2 в сравнение с InnoDB, TokuDB, RocksDB, WiredTiger, но всички те имаха подобни проблеми в началото на техния жизнен цикъл.

Източник: www.habr.com

Добавяне на нов коментар