Pagsusuri ng TSDB sa Prometheus 2

Pagsusuri ng TSDB sa Prometheus 2

Ang time series database (TSDB) sa Prometheus 2 ay isang mahusay na halimbawa ng isang engineering solution na nag-aalok ng malalaking pagpapahusay sa v2 storage sa Prometheus 1 sa mga tuntunin ng bilis ng akumulasyon ng data, pagpapatupad ng query, at kahusayan ng mapagkukunan. Ipinatupad namin ang Prometheus 2 sa Percona Monitoring and Management (PMM) at nagkaroon ako ng pagkakataon na maunawaan ang pagganap ng Prometheus 2 TSDB. Sa artikulong ito ay magsasalita ako tungkol sa mga resulta ng mga obserbasyon na ito.

Average na Prometheus Workload

Para sa mga ginagamit sa pagharap sa mga database ng pangkalahatang layunin, ang karaniwang Prometheus workload ay medyo kawili-wili. Ang rate ng akumulasyon ng data ay malamang na maging stable: kadalasan ang mga serbisyong sinusubaybayan mo ay nagpapadala ng humigit-kumulang sa parehong bilang ng mga sukatan, at ang imprastraktura ay nagbabago nang medyo mabagal.
Ang mga kahilingan para sa impormasyon ay maaaring magmula sa iba't ibang mapagkukunan. Ang ilan sa mga ito, tulad ng mga alerto, ay nagsusumikap din para sa isang matatag at predictable na halaga. Ang iba, gaya ng mga kahilingan ng user, ay maaaring magdulot ng mga pagsabog, bagama't hindi ito ang kaso para sa karamihan ng mga workload.

I-load ang pagsubok

Sa panahon ng pagsubok, nakatuon ako sa kakayahang makaipon ng data. Nag-deploy ako ng Prometheus 2.3.2 na pinagsama-sama sa Go 1.10.1 (bilang bahagi ng PMM 1.14) sa serbisyo ng Linode gamit ang script na ito: StackScript. Para sa pinaka-makatotohanang henerasyon ng pagkarga, gamit ito StackScript Naglunsad ako ng ilang MySQL node na may totoong load (Sysbench TPC-C Test), bawat isa ay tumulad sa 10 Linux/MySQL node.
Ang lahat ng mga sumusunod na pagsubok ay isinagawa sa isang Linode server na may walong virtual core at 32 GB ng memorya, na nagpapatakbo ng 20 load simulation na sinusubaybayan ang dalawang daang MySQL instances. O, sa mga termino ng Prometheus, 800 target, 440 scrapes bawat segundo, 380 thousand records bawat segundo, at 1,7 milyong aktibong serye ng oras.

Disenyo

Ang karaniwang diskarte ng mga tradisyonal na database, kabilang ang ginagamit ng Prometheus 1.x, ay ang limitasyon ng memorya. Kung hindi sapat ang paghawak ng load, makakaranas ka ng mataas na latency at mabibigo ang ilang kahilingan. Ang paggamit ng memory sa Prometheus 2 ay maaaring i-configure sa pamamagitan ng key storage.tsdb.min-block-duration, na tumutukoy kung gaano katagal ang mga pag-record ay pananatilihin sa memorya bago i-flush sa disk (ang default ay 2 oras). Ang halaga ng memory na kinakailangan ay depende sa bilang ng mga serye ng oras, mga label, at mga scrap na idinagdag sa net na papasok na stream. Sa mga tuntunin ng espasyo sa disk, layunin ng Prometheus na gumamit ng 3 byte bawat tala (sample). Sa kabilang banda, ang mga kinakailangan sa memorya ay mas mataas.

Bagama't posibleng i-configure ang laki ng block, hindi inirerekomenda na i-configure ito nang manu-mano, kaya napipilitan kang bigyan ang Prometheus ng maraming memorya na kinakailangan nito para sa iyong workload.
Kung walang sapat na memorya upang suportahan ang papasok na stream ng mga sukatan, mawawala sa memorya ang Prometheus o ang pumatay sa OOM ay makakarating dito.
Ang pagdaragdag ng swap upang maantala ang pag-crash kapag naubusan ng memory ang Prometheus ay hindi talaga nakakatulong, dahil ang paggamit ng function na ito ay nagdudulot ng sumasabog na pagkonsumo ng memorya. Sa tingin ko, may kinalaman ito kay Go, sa basurero nito at sa paraan ng pakikitungo nito sa swap.
Ang isa pang kawili-wiling diskarte ay ang pag-configure ng head block upang ma-flush sa disk sa isang tiyak na oras, sa halip na bilangin ito mula sa simula ng proseso.

Pagsusuri ng TSDB sa Prometheus 2

Tulad ng nakikita mo mula sa graph, ang mga flushes sa disk ay nangyayari bawat dalawang oras. Kung babaguhin mo ang parameter ng min-block-duration sa isang oras, ang mga pag-reset na ito ay magaganap bawat oras, simula pagkatapos ng kalahating oras.
Kung gusto mong gamitin ito at ang iba pang mga graph sa iyong pag-install ng Prometheus, magagamit mo ito dashboard. Idinisenyo ito para sa PMM ngunit, na may maliliit na pagbabago, umaangkop sa anumang pag-install ng Prometheus.
Mayroon kaming aktibong bloke na tinatawag na head block na nakaimbak sa memorya; ang mga bloke na may mas lumang data ay magagamit sa pamamagitan ng mmap(). Inaalis nito ang pangangailangang i-configure ang cache nang hiwalay, ngunit nangangahulugan din na kailangan mong mag-iwan ng sapat na espasyo para sa cache ng operating system kung gusto mong mag-query ng data na mas luma kaysa sa kung ano ang maaaring i-accommodate ng head block.
Nangangahulugan din ito na ang pagkonsumo ng virtual na memorya ng Prometheus ay magmumukhang mataas, na hindi dapat alalahanin.

Pagsusuri ng TSDB sa Prometheus 2

Ang isa pang kawili-wiling punto ng disenyo ay ang paggamit ng WAL (write ahead log). Tulad ng nakikita mo mula sa dokumentasyon ng imbakan, ginagamit ng Prometheus ang WAL upang maiwasan ang mga pag-crash. Ang mga partikular na mekanismo para sa paggarantiya ng data survivability, sa kasamaang-palad, ay hindi mahusay na dokumentado. Ang bersyon ng Prometheus 2.3.2 ay nag-flush ng WAL sa disk bawat 10 segundo at ang opsyong ito ay hindi na-configure ng user.

Mga compaction

Ang Prometheus TSDB ay idinisenyo tulad ng isang LSM (Log Structured Merge) na tindahan: ang head block ay pana-panahong ini-flush sa disk, habang ang isang compaction mechanism ay pinagsasama-sama ang maraming block upang maiwasan ang pag-scan ng masyadong maraming block sa panahon ng mga query. Dito makikita mo ang bilang ng mga bloke na naobserbahan ko sa sistema ng pagsubok pagkatapos ng isang araw ng pagkarga.

Pagsusuri ng TSDB sa Prometheus 2

Kung gusto mong matuto nang higit pa tungkol sa tindahan, maaari mong suriin ang meta.json file, na mayroong impormasyon tungkol sa mga block na available at kung paano ito naging.

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

Ang mga compaction sa Prometheus ay nakatali sa oras na ang head block ay na-flush sa disk. Sa puntong ito, maaaring isagawa ang ilang mga naturang operasyon.

Pagsusuri ng TSDB sa Prometheus 2

Lumilitaw na ang mga compaction ay hindi limitado sa anumang paraan at maaaring magdulot ng malalaking disk I/O spike sa panahon ng pagpapatupad.

Pagsusuri ng TSDB sa Prometheus 2

Mga spike ng load ng CPU

Pagsusuri ng TSDB sa Prometheus 2

Siyempre, ito ay medyo negatibong epekto sa bilis ng system, at nagdudulot din ng seryosong hamon para sa pag-iimbak ng LSM: paano gagawin ang compaction upang suportahan ang mataas na mga rate ng kahilingan nang hindi nagdudulot ng labis na overhead?
Ang paggamit ng memorya sa proseso ng compaction ay mukhang medyo kawili-wili.

Pagsusuri ng TSDB sa Prometheus 2

Makikita natin kung paano, pagkatapos ng compaction, ang karamihan sa memorya ay nagbabago ng estado mula sa Cached patungong Libre: nangangahulugan ito na ang potensyal na mahalagang impormasyon ay inalis mula doon. Nagtataka kung ito ay ginagamit dito fadvice() o ilang iba pang pamamaraan ng pag-minimize, o dahil ba ang cache ay napalaya mula sa mga bloke na nawasak sa panahon ng compaction?

Pagbawi pagkatapos ng kabiguan

Ang pagbawi mula sa mga pagkabigo ay nangangailangan ng oras, at para sa magandang dahilan. Para sa isang papasok na stream ng isang milyong mga rekord sa bawat segundo, kailangan kong maghintay ng mga 25 minuto habang isinasagawa ang pagbawi na isinasaalang-alang ang SSD drive.

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

Ang pangunahing problema ng proseso ng pagbawi ay mataas na pagkonsumo ng memorya. Sa kabila ng katotohanan na sa isang normal na sitwasyon ang server ay maaaring gumana nang matatag na may parehong halaga ng memorya, kung ito ay nag-crash ay maaaring hindi ito mabawi dahil sa OOM. Ang tanging solusyon na nakita ko ay huwag paganahin ang pagkolekta ng data, ilabas ang server, hayaan itong mabawi at i-reboot nang pinagana ang koleksyon.

Nagpapainit

Ang isa pang pag-uugali na dapat tandaan sa panahon ng warm-up ay ang kaugnayan sa pagitan ng mababang pagganap at mataas na pagkonsumo ng mapagkukunan pagkatapos mismo ng pagsisimula. Sa ilan, ngunit hindi lahat ay nagsisimula, napansin ko ang isang seryosong pagkarga sa CPU at memorya.

Pagsusuri ng TSDB sa Prometheus 2

Pagsusuri ng TSDB sa Prometheus 2

Ang mga gaps sa paggamit ng memorya ay nagpapahiwatig na ang Prometheus ay hindi maaaring i-configure ang lahat ng mga koleksyon mula sa simula, at ang ilang impormasyon ay nawala.
Hindi ko naisip ang eksaktong mga dahilan para sa mataas na CPU at memory load. Pinaghihinalaan ko na ito ay dahil sa paglikha ng bagong serye ng oras sa head block na may mataas na dalas.

Dumadami ang pagkarga ng CPU

Bilang karagdagan sa mga compaction, na lumilikha ng medyo mataas na I/O load, napansin ko ang mga seryosong spike sa CPU load tuwing dalawang minuto. Mas mahaba ang mga pagsabog kapag mataas ang daloy ng input at lumilitaw na dulot ng tagakolekta ng basura ni Go, na may hindi bababa sa ilang mga core na ganap na na-load.

Pagsusuri ng TSDB sa Prometheus 2

Pagsusuri ng TSDB sa Prometheus 2

Ang mga pagtalon na ito ay hindi gaanong mahalaga. Lumilitaw na kapag nangyari ang mga ito, magiging hindi available ang panloob na entry point at mga sukatan ng Prometheus, na nagiging sanhi ng mga gaps ng data sa parehong mga yugto ng panahon.

Pagsusuri ng TSDB sa Prometheus 2

Maaari mo ring mapansin na ang Prometheus exporter ay nagsasara nang isang segundo.

Pagsusuri ng TSDB sa Prometheus 2

Mapapansin natin ang mga ugnayan sa pangongolekta ng basura (GC).

Pagsusuri ng TSDB sa Prometheus 2

Konklusyon

Ang TSDB sa Prometheus 2 ay mabilis, may kakayahang pangasiwaan ang milyun-milyong serye ng oras at kasabay nito ang libu-libong mga talaan bawat segundo gamit ang medyo katamtamang hardware. Kahanga-hanga rin ang paggamit ng CPU at disk I/O. Ang aking halimbawa ay nagpakita ng hanggang 200 sukatan bawat segundo sa bawat core na ginamit.

Upang magplano ng pagpapalawak, kailangan mong tandaan ang tungkol sa sapat na dami ng memorya, at ito ay dapat na tunay na memorya. Ang dami ng memorya na ginamit na aking naobserbahan ay humigit-kumulang 5 GB sa bawat 100 na talaan bawat segundo ng papasok na stream, na kasama ng cache ng operating system ay nagbigay ng humigit-kumulang 000 GB ng occupied memory.

Siyempre, marami pa ring gawaing dapat gawin upang mapaamo ang CPU at disk I/O spike, at hindi ito nakakagulat kung ihahambing ang batang TSDB Prometheus 2 sa InnoDB, TokuDB, RocksDB, WiredTiger, ngunit lahat sila ay may katulad na mga problema sa maagang yugto ng kanilang buhay.

Pinagmulan: www.habr.com

Magdagdag ng komento