Prometheus 2'de TSDB Analizi

Prometheus 2'de TSDB Analizi

Prometheus 2'deki zaman serisi veritabanı (TSDB), veri biriktirme hızı, sorgu yürütme ve kaynak verimliliği açısından Prometheus 2'deki v1 depolamaya göre büyük iyileştirmeler sunan mühendislik çözümünün mükemmel bir örneğidir. Percona Monitoring and Management (PMM)'de Prometheus 2'yi uyguluyorduk ve Prometheus 2 TSDB'nin performansını anlama fırsatı buldum. Bu yazımda bu gözlemlerin sonuçlarından bahsedeceğim.

Ortalama Prometheus İş Yükü

Genel amaçlı veritabanlarıyla uğraşmaya alışkın olanlar için tipik Prometheus iş yükü oldukça ilgi çekicidir. Veri birikim hızı genellikle sabittir: genellikle izlediğiniz hizmetler yaklaşık olarak aynı sayıda ölçüm gönderir ve altyapı nispeten yavaş değişir.
Bilgi talepleri çeşitli kaynaklardan gelebilir. Uyarılar gibi bazıları da istikrarlı ve öngörülebilir bir değer için çaba gösterir. Kullanıcı istekleri gibi diğerleri patlamalara neden olabilir, ancak çoğu iş yükü için durum böyle değildir.

Yük testi

Test sırasında veri biriktirme yeteneğine odaklandım. Go 2.3.2 ile derlenen Prometheus 1.10.1'yi (PMM 1.14'ün bir parçası olarak) şu betiği kullanarak Linode hizmetine dağıttım: StackScript. En gerçekçi yük üretimi için bunu kullanarak StackScript Her biri 10 Linux/MySQL düğümünü taklit eden, gerçek yükte (Sysbench TPC-C Testi) birkaç MySQL düğümü başlattım.
Aşağıdaki testlerin tümü, sekiz sanal çekirdeğe ve 32 GB belleğe sahip, iki yüz MySQL örneğini izleyen 20 yük simülasyonu çalıştıran bir Linode sunucusunda gerçekleştirildi. Veya Prometheus terimleriyle 800 hedef, saniyede 440 kazıma, saniyede 380 bin kayıt ve 1,7 milyon aktif zaman serisi.

Dizayn

Prometheus 1.x tarafından kullanılan da dahil olmak üzere geleneksel veritabanlarının olağan yaklaşımı, hafıza sınırı. Yükü idare etmek yeterli değilse yüksek gecikmeler yaşarsınız ve bazı istekler başarısız olur. Prometheus 2'deki bellek kullanımı anahtarla yapılandırılabilir storage.tsdb.min-block-duration, diske aktarılmadan önce kayıtların bellekte ne kadar süreyle tutulacağını belirler (varsayılan 2 saattir). Gereken bellek miktarı, net gelen akışa eklenen zaman serileri, etiketler ve notların sayısına bağlı olacaktır. Disk alanı açısından Prometheus, kayıt (örnek) başına 3 bayt kullanmayı amaçlamaktadır. Öte yandan bellek gereksinimleri çok daha yüksektir.

Blok boyutunu yapılandırmak mümkün olsa da manuel olarak yapılandırmanız önerilmez, bu nedenle Prometheus'a iş yükünüz için ihtiyaç duyduğu kadar bellek vermek zorunda kalırsınız.
Gelen metrik akışını destekleyecek yeterli bellek yoksa, Prometheus'un belleği tükenecek veya OOM katili ona ulaşacaktır.
Prometheus'un belleği tükendiğinde çökmeyi geciktirmek için takas eklemek pek işe yaramaz çünkü bu işlevin kullanılması aşırı bellek tüketimine neden olur. Bunun Go'yla, çöp toplayıcısıyla ve takasla başa çıkma şekliyle ilgili olduğunu düşünüyorum.
Bir başka ilginç yaklaşım, kafa bloğunu sürecin başlangıcından itibaren saymak yerine belirli bir zamanda diske aktarılacak şekilde yapılandırmaktır.

Prometheus 2'de TSDB Analizi

Grafikten de görebileceğiniz gibi, diske temizleme işlemi her iki saatte bir gerçekleşir. Min-block-duration parametresini bir saat olarak değiştirirseniz, bu sıfırlamalar yarım saatten sonra başlamak üzere her saat başı gerçekleşecektir.
Prometheus kurulumunuzda bu ve diğer grafikleri kullanmak istiyorsanız bunu kullanabilirsiniz. Gösterge Paneli. PMM için tasarlandı ancak küçük değişikliklerle her türlü Prometheus kurulumuna uyar.
Bellekte saklanan, kafa bloğu adı verilen aktif bir bloğumuz var; daha eski verilere sahip bloklara şu adresten ulaşılabilir: mmap(). Bu, önbelleği ayrı ayrı yapılandırma ihtiyacını ortadan kaldırır ancak aynı zamanda, ana bloğun alabileceğinden daha eski verileri sorgulamak istiyorsanız işletim sistemi önbelleği için yeterli alan bırakmanız gerektiği anlamına da gelir.
Bu aynı zamanda Prometheus sanal bellek tüketiminin de oldukça yüksek görüneceği anlamına geliyor ki bu da endişelenecek bir durum değil.

Prometheus 2'de TSDB Analizi

Bir başka ilginç tasarım noktası da WAL'ın (önceden yazma günlüğü) kullanılmasıdır. Depolama belgelerinden görebileceğiniz gibi Prometheus, çökmeleri önlemek için WAL kullanıyor. Verilerin hayatta kalmasını garanti etmeye yönelik spesifik mekanizmalar ne yazık ki iyi bir şekilde belgelenmemiştir. Prometheus sürüm 2.3.2, WAL'yi her 10 saniyede bir diske temizler ve bu seçenek kullanıcı tarafından yapılandırılamaz.

Sıkıştırmalar

Prometheus TSDB, bir LSM (Log Yapılandırılmış Birleştirme) deposu gibi tasarlanmıştır: kafa bloğu periyodik olarak diske aktarılırken, bir sıkıştırma mekanizması, sorgular sırasında çok fazla bloğun taranmasını önlemek için birden fazla bloğu bir araya getirir. Burada bir günlük yükleme sonrasında test sisteminde gözlemlediğim blok sayısını görebilirsiniz.

Prometheus 2'de TSDB Analizi

Mağaza hakkında daha fazla bilgi edinmek isterseniz mevcut bloklar ve nasıl oluştukları hakkında bilgilerin yer aldığı meta.json dosyasını inceleyebilirsiniz.

{
       "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'taki sıkıştırmalar kafa bloğunun diske atıldığı zamana bağlıdır. Bu noktada bu tür birkaç işlem gerçekleştirilebilir.

Prometheus 2'de TSDB Analizi

Sıkıştırmaların hiçbir şekilde sınırlı olmadığı ve yürütme sırasında büyük disk G/Ç ani artışlarına neden olabileceği görülmektedir.

Prometheus 2'de TSDB Analizi

CPU yükünde ani artışlar

Prometheus 2'de TSDB Analizi

Elbette bunun sistemin hızı üzerinde oldukça olumsuz bir etkisi var ve aynı zamanda LSM depolaması için ciddi bir zorluk teşkil ediyor: Çok fazla ek yüke neden olmadan yüksek istek hızlarını desteklemek için sıkıştırma nasıl yapılmalı?
Sıkıştırma işleminde belleğin kullanımı da oldukça ilginç görünüyor.

Prometheus 2'de TSDB Analizi

Sıkıştırma sonrasında belleğin çoğunun durumunun Önbelleğe Alınmış durumdan Serbest duruma nasıl geçtiğini görebiliriz: bu, potansiyel olarak değerli bilgilerin oradan kaldırıldığı anlamına gelir. Burada kullanılıp kullanılmadığını merak ediyorum fadvice() veya başka bir küçültme tekniği mi, yoksa önbelleğin sıkıştırma sırasında tahrip edilen bloklardan arındırılmasından mı kaynaklanıyor?

Arızadan sonra kurtarma

Başarısızlıklardan kurtulmak zaman alır ve bunun iyi bir nedeni vardır. Saniyede bir milyon kayıttan oluşan bir akış için, SSD sürücüsü dikkate alınarak kurtarma işlemi gerçekleştirilirken yaklaşık 25 dakika beklemek zorunda kaldım.

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

Kurtarma işleminin temel sorunu yüksek bellek tüketimidir. Normal bir durumda sunucu aynı miktarda bellekle istikrarlı bir şekilde çalışabilmesine rağmen, çökerse OOM nedeniyle iyileşemeyebilir. Bulduğum tek çözüm, veri toplamayı devre dışı bırakmak, sunucuyu açmak, kurtarmasına izin vermek ve toplama etkinken yeniden başlatmaktı.

Isınmak

Isınma sırasında akılda tutulması gereken bir diğer davranış, başlangıçtan hemen sonra düşük performans ile yüksek kaynak tüketimi arasındaki ilişkidir. Tüm başlatmalarda olmasa da bazı başlatmalarda CPU ve bellek üzerinde ciddi bir yük gözlemledim.

Prometheus 2'de TSDB Analizi

Prometheus 2'de TSDB Analizi

Bellek kullanımındaki boşluklar, Prometheus'un tüm koleksiyonları baştan yapılandıramadığını ve bazı bilgilerin kaybolduğunu gösterir.
Yüksek CPU ve bellek yükünün kesin nedenlerini çözemedim. Bunun baş blokta yüksek frekanslı yeni zaman serilerinin oluşmasından kaynaklandığını düşünüyorum.

CPU yükünde artışlar

Oldukça yüksek bir G/Ç yükü oluşturan sıkıştırmalara ek olarak, her iki dakikada bir CPU yükünde ciddi artışlar olduğunu fark ettim. Giriş akışı yüksek olduğunda patlamalar daha uzun oluyor ve Go'nun çöp toplayıcısından kaynaklanıyor gibi görünüyor; en azından bazı çekirdekler tam yüklü.

Prometheus 2'de TSDB Analizi

Prometheus 2'de TSDB Analizi

Bu sıçramalar o kadar da önemsiz değil. Bunlar meydana geldiğinde, Prometheus'un dahili giriş noktası ve ölçümleri kullanılamaz hale geliyor ve bu da aynı dönemlerde veri boşluklarına neden oluyor.

Prometheus 2'de TSDB Analizi

Ayrıca Prometheus ihracatçısının bir saniyeliğine kapandığını da fark edebilirsiniz.

Prometheus 2'de TSDB Analizi

Çöp toplama (GC) ile korelasyonları fark edebiliriz.

Prometheus 2'de TSDB Analizi

Sonuç

Prometheus 2'deki TSDB hızlıdır, oldukça mütevazı bir donanım kullanarak milyonlarca zaman serisini ve aynı zamanda saniyede binlerce kaydı işleyebilir. CPU ve disk I/O kullanımı da etkileyici. Örneğim, kullanılan çekirdek başına saniyede 200 metriğe kadar gösterdi.

Genişlemeyi planlamak için yeterli miktarda belleği hatırlamanız gerekir ve bu gerçek bellek olmalıdır. Gözlemlediğim kadarıyla kullanılan bellek miktarı, gelen akışın saniye başına 5 kaydı başına yaklaşık 100 GB idi; bu, işletim sistemi önbelleğiyle birlikte yaklaşık 000 GB dolu bellek sağlıyordu.

Elbette, CPU ve disk I/O ani artışlarını dizginlemek için hala yapılması gereken çok iş var ve TSDB Prometheus 2'nin InnoDB, TokuDB, RocksDB, WiredTiger ile karşılaştırıldığında ne kadar genç olduğu göz önüne alındığında bu şaşırtıcı değil, ancak hepsinde benzer özellikler vardı. Yaşam döngüsünün başlarında sorunlar.

Kaynak: habr.com

Yorum ekle