Dalam waktu singkat, Prometheus telah menjadi salah satu alat pemantauan paling populer. Terima kasih, khususnya, dan kecepatan tinggi kerjanya. Penyimpanan lokalnya bagus untuk penyimpanan metrik jangka pendek dan bekerja dengannya. Terkadang Anda ingin agar metrik tetap terdistribusi selama berbulan-bulan dan bertahun-tahun, secara otomatis memotong data lama, tetapi tanpa mengubah antarmuka untuk bekerja dengannya.
Hanya tentang ini, decoding laporan oleh Alexey Palazhchenko di RootConf 2018. Dalam laporan: Prometheus, TSDB Penyimpanan Lokal, Remote Storage Prometheus, PromQL, TSDB, Clickhouse, PromHouse, InfluxDB kecil.
Siapa yang peduli, tolong, di bawah kucing.
Teman! Halo semuanya! Nama saya Alexey Palazhchenko. Saya bekerja di Percona. Saya ingin memberi tahu Anda tentang penyimpanan metrik jangka panjang di Prometheus.

Saya bekerja di Percona dan membuat produk yang disebut pemantauan dan manajemen percona. Ini adalah solusi kemas yang ditetapkan pelanggan kami untuk mereka sendiri. PMM sepenuhnya open source. Ini terdiri dari Prometheus, Grafana untuk grafik, perangkat lunak analisis kueri khusus, dan pembungkus kami sendiri yang memungkinkan Anda melakukan manajemen. Misalnya, Anda dapat menambahkan target gesek ke Prometheus. Ini adalah sumber baru dari mana ia akan mengambil metrik tanpa harus memasukkan wadah atau mesin virtual secara manual dan mengedit file konfigurasi.
Penting untuk dipahami bahwa ini bukan SaaS. Kami tidak memiliki produksi. Produksi kami terletak dengan pelanggan kami. Bereksperimen dengan itu tidak terlalu baik. Kami memiliki hal terdekat yang dapat disebut produksi - ini adalah https://pmmdemo.percona.com/ . Pada saat laporan, pmmdemo.percona.com harus ditutup karena GDPR.
Kami memberikan PMM kepada pelanggan - solusi kotak: wadah buruh pelabuhan atau mesin virtual. Mereka semua menyukai Prometheus. Beberapa orang yang pertama kali melihat Prometheus menemukan model tarikan. Untuk pemula, ini merepotkan. Umumnya percakapan besar terpisah. Anda dapat berdebat tentang metode tarik atau dorong. Rata-rata, ini tentang hal yang sama.
Beberapa hal di Prometheus sangat keren.
Bahasa permintaan Prometheus benar-benar hal yang keren yang tidak memiliki analog di mana pun.
Hal kedua yang Anda sukai adalah penemuan layanan. Jika Anda memiliki semacam infrastruktur dinamis, kubernet, maka secara otomatis Anda tidak perlu menambahkan semua target untuk pemantauan dengan tangan Anda. Jika statis - ini juga dapat dilakukan dengan cukup sederhana. Anda perlu menggunakan file konfigurasi.
Pelanggan Prometheus menyukainya. Mereka ingin mempertahankan metrik lebih lama dan lebih lama. Seseorang menggunakan Prometheus hanya untuk pemantauan operasional. Tetapi seseorang ingin mempertahankan metrik lebih lama, menonton dinamika, dibandingkan dengan grafik setahun yang lalu. Pada saat yang sama, tujuan penyimpanan metrik jangka panjang bukanlah tujuan untuk proyek Prometheus. Awalnya, ini dibuat untuk menyimpan metrik untuk waktu yang singkat. SoundCloud menyimpan metrik hanya dalam beberapa hari. Ada mekanisme di Prometheus yang memungkinkan Anda melakukan ini lebih lama, tetapi mereka diatur sedikit di samping. Oleh karena itu, kita dapat membuat keputusan untuk ekosistem Prometheus tanpa mengubah inti sistem itu sendiri. Berdasarkan mereka, kita dapat membuat keputusan sendiri dalam ekosistem yang sama.

Ini bukan laporan tentang solusi yang sudah jadi. Ini adalah laporan tentang pengalaman kami, tentang rasa sakit kami, tentang upaya kami. Jika Anda berharap setelah laporan ini Anda mengunduh wadah repositori atau buruh pelabuhan, jalankan dan itu akan berfungsi, maka ini tidak terjadi. Tetapi pada saat yang sama cukup dekat untuk menjadi demikian. Kami memiliki beberapa dasar. Semuanya adalah opensource. Anda bisa mencobanya. Mereka belum siap untuk diproduksi. Tetapi dengan informasi yang ada di laporan ini, Anda bisa mengerti mengapa, jadi apa yang bisa dilakukan dengan lebih baik. Anda dapat membuat keputusan sendiri yang cocok untuk Anda.

Bagaimana metrik disimpan di Prometheus? Ada penyimpanan lokal. Ada penyimpanan jarak jauh. Ini sebenarnya adalah dua dunia yang berbeda. Mereka berpotongan lemah. Karena itu, laporan ini juga dibagi menjadi 2 bagian.

Jika Anda berada di laporan sebelumnya di aula utama, di mana ada intro yang baik di Prometheus, Anda tahu bahwa penyimpanan lokal adalah perpustakaan terpisah yang disebut TSDB. TSDB tidak ada hubungannya dengan OpenTSDB. TSDB adalah paket Go terpisah yang dapat Anda gunakan dari program Go Anda. Di tingkat perpustakaan TSDB, tidak ada klien atau server.
Perpustakaan ini dioptimalkan untuk bekerja dengan data deret waktu. Misalnya, TSDB memiliki penyandian delta, yang memungkinkan Anda untuk menyimpan bukan nomor itu sendiri, tetapi perubahan di antara angka-angka ini. Ini memungkinkan Anda untuk menyimpan 1 byte, bukan 16 byte. 1 byte untuk waktu dan 1 byte untuk nilai. Artinya, Anda menyimpan rata-rata 1 atau 2 byte justru karena kompresi yang baik ini.
TSDB dioptimalkan untuk model tarikan. Data hanya ditambahkan di sana. Prometheus tidak dapat menulis data historis. Tidak ada API untuk ini. Delta maksimum adalah sekitar 5 menit. Jika datanya lebih lama, itu tidak akan diterima.
Tidak ada built-in downsampling tsdb # 313 di TSDB. Ada masalah terbuka di mana ada diskusi tentang fakta bahwa secara umum ada proyek yang melakukan sesuatu Prometheus dan ada downsampling di sana. Sejauh ini, solusinya adalah bahwa TSDB tidak akan menambahkan downsampling.

Bagaimana kita mendapatkan data dari TSDB? TSDB adalah database pada disk. Anda dapat bekerja dengannya jika Anda menulis program Go. Tetapi jika Anda tidak menulis program di Go, maka ada API JSON yang memungkinkan Anda membuat kueri permintaan. Jika Anda pernah menggunakan Prometheus dan setidaknya sekali membuat bagan, Anda tahu API Kueri standar, di mana ada parameter kueri tempat Anda dapat menjalankan kueri PromQL dan waktu opsional. Jika tidak ada waktu, maka waktu saat ini diambil.
Kueri tertentu disorot pada slide, yang jarang Anda lihat dalam kehidupan nyata. Ini adalah retasan. Ini memungkinkan kami untuk mencabut semua metrik yang dimiliki Prometheus. Bagaimana cara kerjanya? Pada tingkat PromQL dikatakan bahwa tidak mungkin untuk menulis ekspresi seperti itu yang akan menangkap semua server waktu. Ini ditulis langsung dalam aturan. Aturan lain mengatakan bahwa Anda tidak dapat membuat pencocokan di mana semua nilai kosong. Jika Anda hanya menulis kawat gigi, ini tidak akan berhasil. Jika Anda menulis nama tidak sama dengan apa pun (bukan nilai kosong), maka itu tidak akan berfungsi. Tapi ini peretasan nyata yang memungkinkan Anda melakukan ini. Namun, itu bahkan tidak terdokumentasi secara khusus. Ada komentar dalam kode itu sendiri yang berfungsi.
Kueri kedua adalah query_range, yang melakukan hal yang sama, tetapi mengembalikan data Anda dalam rentang dan dengan beberapa langkah. Ini pada dasarnya membuat kueri beberapa kali untuk setiap langkah dari awal hingga akhir. Ini adalah API yang digunakan untuk menggambar. API pertama digunakan untuk mendapatkan nilai instan.

Kami memiliki API untuk mengambil metadata. Jika kami ingin mendapatkan semua nama metrik, kami membuat kueri seperti ini, di mana kecocokan adalah array metrik. Mungkin ada beberapa argumen, tetapi dalam hal ini kami melewati pertandingan yang sama, yang semuanya kembali kepada kami.
API meta kedua, yang mengembalikan nilai semua label kepada kami. Jika kita ingin melihat daftar semua pekerjaan, alih-alih label_name kita menulis pekerjaan dan mendapatkan daftar ini. API ini mengembalikan JSON kepada kami.

Ada API lain yang mengembalikan semua metrik Prometheus itu sendiri dalam format yang asli untuk eksportir. Format ini disebut expfmt. Di Prometheus sendiri, ada API Federasi yang memungkinkan Anda untuk membuat permintaan seperti itu. Untuk apa ini? Opsi termudah, jika Anda memiliki beberapa kode yang sudah berfungsi dengan expfmt, maka Anda tidak perlu melatihnya lagi untuk bekerja dengan beberapa API JSON kustom. Format ini jauh lebih mudah untuk streaming, karena jika Anda memiliki JSON di suatu tempat di tingkat atas objek, paling sering Anda perlu menguraikan objek ini secara keseluruhan. Di sini bisa dilakukan baris demi baris.
Yang paling penting adalah API yang terpisah. Ini berfungsi seperti ekspor nyata. Anda dapat mengambil Prometheus lainnya untuk mengikisnya. Ini adalah pekerjaan biasa dengan parameter yang biasa. Anda harus melewati parameter - url permintaan. Jika Anda membuat permintaan ikal, Anda akan mendapatkan yang sama di sini. Kami mendapatkan semua metrik untuk nilai waktu saat ini. Satu-satunya peringatan: Anda harus menetapkan honor_labels agar Prometheus, yang akan membatalkan Prometheus lain melalui API ini, tidak menggosok nilai label pekerjaan dan instance. Menggunakan API Federasi ini, Anda dapat memuat semua data dari satu Prometheus ke yang lain.

Bagaimana ini bisa digunakan?
Pertama, hal terpenting untuk dikatakan adalah Anda tidak perlu melakukan ini. TSDB dioptimalkan untuk berbagai mode operasi. Jika Anda memiliki Prometheus yang mengikis banyak data, maka ia melakukan banyak I / O. Jika Anda menggunakan API Federasi, maka jumlah output input akan meningkat sekitar 2 kali. Ada nuansa. Tergantung pada seberapa sering Anda mengikis di federate dan seberapa sering Anda mengikis target. Jika waktu belum diubah, maka ini benar-benar menggandakan beban. Karena itu, jika Anda ingin skala Prometheus Anda dan memungkinkan federasi, maka Anda akan membunuhnya. Beban akan berlipat ganda.
Momen kedua. Anda akan melewatkan data. Anda akan mendapatkan konflik data. Kenapa begitu API ini, seperti hampir semua API di Prometheus, bukan atom. Jika data baru tiba, goresan baru akan berakhir pada saat permintaan gabungan Anda masih dalam proses, Anda bisa mendapatkan satu data untuk satu seri waktu dan data baru untuk yang lain. Jika ini adalah deret waktu yang tidak terkait, maka umumnya tidak menakutkan. Tetapi jika Anda memiliki ringkasan atau histogram, yang pada tingkat expfmt diwakili oleh beberapa metrik dasar, maka akan ada ketidakkonsistenan di antara mereka.

Bagaimana kita bisa menyelesaikan masalah atom ini? Prometheus memiliki aturan rekaman yang memungkinkan Anda membuat seri waktu baru dari seri waktu yang ada. Ini bisa dilakukan lebih jarang. Ini adalah salah satu cara untuk melakukan downsampling. Misalnya, memo target setiap detik, tetapi kemudian kami ingin melakukan agregasi node_cpu dalam satu menit. Pengelompokan dalam Prometheus 2.0 memungkinkan Anda melakukan agregasi ini secara berurutan. Aturan yang berada di grup yang sama dijalankan secara ketat secara berurutan. Pada saat ini tidak ada masalah atomisitas, tidak ada masalah bahwa data akan berubah dalam proses. Tetapi ini tidak menyelesaikan masalah dari fakta bahwa itu dapat diterima beberapa data lain yang secara logis terhubung dengan ini, tetapi tidak terhubung dari sudut pandang model data. Belum ada atomisitas murni. Ada masalah terbuka tentang topik ini. Anda dapat melakukan snapshot. Anda dapat membuat kueri PromQL ke database TSDB dan menjatuhkan semua sampel yang kurang dari beberapa nilai waktu yang dimulai dalam evaluasi dari nilai yang diperoleh. Ini akan menjadi cara termudah, tetapi sejauh ini belum dilakukan.
Penting untuk dipahami bahwa aturan pencatatan perlu dilakukan pada Prometheus bawah, dan bukan pada yang dilakukan federasi. Jika tidak, Anda akan melewati puncak, pemantauan Anda tidak akan berfungsi dengan benar.

Bagaimana kita bisa menggunakan kombinasi dari hal-hal ini untuk melakukan downsampling dan penyimpanan jangka panjang.
Yang pertama. Kami baru saja mengatur federasi dan mengunduh semua data dari Prometheus itu. Ekspresi reguler yang aneh ini seperti zoidberg - sebenarnya hanya titik dua. Tanda bintang di kiri dan kanan usus besar. Kami menggunakan nama standar untuk aturan perekaman, yang menambahkan titik dua di tengah. Saat membagi nama asli, akan ada tingkat agregasi di sebelah kiri dan fungsi di sebelah kanan. Metrik usus besar normal tidak. Jika ada titik dua, maka ini adalah tanda bahwa ini adalah agregasi. Setelah itu, kami menggunakan nama metrik ini dalam grafik kami. Jika kita ingin jadwal kita, dashboard kita dalam grafana bekerja dengan Prometheus utama, dan dengan mereka yang lebih tinggi, kita dapat menggunakan ekspresi atau . Kami mengambil satu metrik atau lainnya, tergantung yang mana. Kita dapat menipu dan menggunakan penamaan ulang untuk mengganti nama metrik baru dengan nama lama. Ini adalah pendekatan yang agak berbahaya. Anda dapat mengeja lampiran biasa dengan salah dan Anda akan mengalami konflik rangkaian waktu. Prometheus akan menulis banyak peringatan ke log. Anda akan melihat ini, tetapi menemukan alasannya bisa sangat sulit. Tetapi jika dilakukan dengan hati-hati, misalnya, menghasilkan ekspresi reguler ini secara terprogram, maka ini akan berhasil. Selanjutnya Anda akan memiliki dasbor biasa di mana hanya node_cpu digunakan. Bergantung pada Prometheus mana yang digunakan, Anda akan menerima data mentah atau data agregat.

Seperti yang saya katakan, aturan perekaman dapat dibuat cukup sederhana. Kami hanya mendapatkan semua deret waktu melalui api yang sudah saya tunjukkan. Kami membuat aturan dan aturan ini harus menggunakan fungsi dan operator yang benar. Tidak perlu menggunakan rate dengan gauge di sana. Ini tidak akan berfungsi dengan baik. Ini harus digunakan hanya dengan hitungan. Di tingkat tempat Anda bekerja, Anda mungkin tidak memiliki informasi tentang tipe data. Misalnya, jika Anda menggunakan expfmt. Ada informasi tentang jenisnya. Jika API JSON tidak ada di sana. Akibatnya, ekspresi yang Anda buat secara otomatis mungkin tidak memiliki makna fisik apa pun. Oleh karena itu, Anda dapat menggunakan daftar putih atau daftar hitam di sana. Bergantung pada ini, baik menghasilkan aturan yang Anda butuhkan, atau membuang aturan-aturan yang tidak masuk akal. Ada alat promtool yang memungkinkan Anda untuk memeriksa bahwa aturan yang Anda buat, konfigurasi yang Anda buat, masuk akal. Ini memiliki sintaks yang benar.

Jika kita memiliki Grafana dan ada beberapa Prometheus, kita perlu tahu Prometheus mana yang akan dikirimi permintaan. Bagaimana kita melakukan ini?
Salah satu caranya adalah dengan meletakkan proxy khusus yang akan melihat waktu pada permintaan, dan tergantung pada ini, pilih Prometheus. Kueri memiliki waktu mulai dan waktu selesai. Tergantung pada ini, Anda dapat melakukan routing dengan tangan Anda. Orang bisa menulis semacam program yang melakukan ini. Dalam prakteknya, ini dilakukan oleh nginx dengan modul lua atau program kecil.

Apakah kita benar-benar membutuhkan API? Bisakah kita bekerja dengan TSDB secara langsung? Ada nuansa. Pertama, jika kita mencoba menggunakan TSDB, yang digunakan oleh Prometheus sekarang, kita tidak akan dapat melakukan ini. Ada file kunci khusus yang mencegah ini. Jika kami menulis kode yang akan mengabaikan ini dan mencoba membaca atau menulis data, kami dijamin akan merusaknya. Apalagi membaca. Apa yang bisa dilakukan? Kita dapat membaca data melalui API dan membuat TSDB berdampingan. Kemudian hentikan Prometheus dan gantikan dengan TSDB. Tetapi pada saat yang sama, kita dapat menguras kinerja jika kita membaca semua data melalui API. Saya akan membicarakan hal ini nanti.
Opsi kedua. Anda dapat menyalin (membuat cadangan panas) file-file ini, yaitu, salin apa adanya. Ya, mereka akan rusak. Ketika Anda membuka, Anda akan memiliki peringatan bahwa data rusak. Mereka perlu diperbaiki. Anda mungkin kehilangan data baru. Tetapi itu tidak masalah bagi kami. Kami ingin downsampling data lama. Downsampling dapat dilakukan menggunakan PromQL. Namun ada nuansa. Jauh lebih sulit untuk merobeknya dari Prometheus daripada TSDB. Jika Anda sedikit terbiasa dengan Go dan manajemen ketergantungan, vendor PromQL sangat merepotkan. Saya tidak akan menyarankan Anda. Hindari ini jika memungkinkan.

Kami beralih ke Penyimpanan Jarak Jauh. Adakah yang bekerja dengan Remote Storage di Prometheus? Beberapa tangan. Penyimpanan Jarak Jauh adalah API yang telah ada sejak lama. Sekarang dalam versi 2.2 Penyimpanan Jarak Jauh - ditandai sebagai percobaan. Selain itu, diketahui bahwa Remote Storage API pasti akan berubah.
Penyimpanan Jarak Jauh memungkinkan Anda bekerja hanya dengan data mentah. Tidak ada PromQL pada input atau output. Saat Anda membaca, Anda tidak dapat menggunakan kekuatan penuh PromQL. Ini pada dasarnya memompa semua data dari Remote Storage yang sesuai dengan kondisi. Lebih lanjut PromQL sudah bekerja dengan mereka. Ini memiliki overhead yang cukup besar. Anda perlu memompa banyak data melalui jaringan. Oleh karena itu, dalam Prometheus 2.3, yang belum dirilis, tetapi sudah ditunda, akan ada petunjuk baca. Kami akan membicarakannya nanti.
Belum ada API untuk metadata. Anda tidak dapat membuat API yang mengembalikan semua rangkaian waktu dari Remote Storage. Jika Anda membuat permintaan ke Prometheus API, itu tidak akan pergi ke Penyimpanan Jarak Jauh. Ini akan mengembalikan Anda seri waktu, yang ada di database lokalnya. Jika database lokal Anda dinonaktifkan, itu akan mengembalikan Anda 0. Yang mungkin agak tak terduga. Sekarang API ini menggunakan ProtoBuf dan pasti akan diubah menjadi gRPC di masa depan. Mereka belum melakukannya, karena gRPC membutuhkan HTTP2. Dan dalam praktiknya mereka punya masalah dengannya.

API penulisan terlihat seperti ini. Permintaan memiliki serangkaian label. Set label hanya mengidentifikasi secara unik deret waktu. __name__
sebenarnya hanya label dengan nama khusus. Dan sampel adalah seperangkat waktu dan nilai - int64 dan float64. Saat merekam, pesanan tidak penting. Diasumsikan bahwa database yang menulis ini untuk dirinya sendiri akan melakukan segalanya dengan benar. Prometheus dapat melakukan beberapa optimasi dan tidak mengurutkannya lagi. Karenanya, permintaan penulisan hanyalah beberapa seri waktu.

Konfigurasi tulis memiliki konfigurasi yang cukup fleksibel. Ada banyak opsi untuk mengkonfigurasi konkurensi write write. Apa yang disebut Prometheus pecahan pada dasarnya adalah permintaan kompetitif. Anda dapat membatasi jumlah sampel maksimum dalam satu permintaan, maksimum permintaan paralel, batas waktu, cara mengulangi, backoff mana. Untuk banyak basis data, 100 sampel sekaligus - ini bisa sangat kecil. Jika Anda menggunakan ClickHouse, seperti yang kami lakukan, maka tentu saja nilainya perlu sangat ditingkatkan. Kalau tidak, itu akan sangat tidak efisien.

API baca jarak jauh terlihat seperti ini. Ini hanya rentang waktu dari awal hingga selesai dan satu set pertandingan.

Match pada dasarnya adalah kumpulan pasangan nama dan nilai - label reguler dan jenis kondisi. Sebagai perbandingan, ada persamaan, ketidaksetaraan, atau ekspresi reguler. Ini adalah pemilih seri waktu yang biasa Anda lihat di PromQL. Tidak ada fitur di sini.

Jawabannya adalah beberapa seri waktu yang cocok dengan kueri ini. Di sini sampel harus diurutkan berdasarkan waktu. sekali lagi ini membantu Prometheus menghemat sedikit cpu - tidak perlu disortir. Tetapi diasumsikan bahwa database Anda harus melakukan ini. Dalam kebanyakan kasus, itu akan terjadi, karena, kemungkinan besar, akan ada indeks tepat waktu.

Prometheus 2.3 memperkenalkan petunjuk baca. Apa ini Ini adalah kesempatan untuk memberi tahu Prometheus fungsi internal mana yang bekerja dengan deret waktu yang diminta akan diterapkan. Ini bisa berupa fungsi atau operator agregasi. Mungkin nilai. Artinya, itu disebut func, tetapi sebenarnya bisa dijumlahkan, yang dari sudut pandang PromQL sebenarnya bukan fungsi sama sekali. Ini operatornya. Dan satu langkah. Dalam contoh sebelumnya, ada laju 1 menit. Di sini rate adalah fungsi dan satu menit dalam milidetik sebagai langkah. Petunjuk ini dapat diabaikan oleh basis data jauh. Pada saat yang sama, tidak ada indikasi dalam jawaban apakah itu diabaikan atau tidak.

Apa konfigurasi baca?
Pertama, ada konfigurasi yang diperlukan_matcher. Ini memungkinkan Anda untuk mengirim permintaan Penyimpanan Jarak Jauh yang cocok dengan ekspresi. Untuk membaca data teragregasi dari Penyimpanan Jarak Jauh, Anda harus menggunakan kueri yang berisi titik dua.
Ada opsi yang memungkinkan Anda membaca atau tidak membaca data terbaru dari Remote Storage, yang ada di TSDB. Biasanya dalam konfigurasi standar ada TSDB lokal kecil yang ditulis ke disk lokal. Dia menyimpan di sana selama beberapa jam atau beberapa hari. Data yang Anda gunakan sekarang, yang digunakan untuk peringatan, yang digunakan untuk membangun dasbor, hanya dibaca dari TSDB lokal. Ini cepat, tetapi tidak memungkinkan kita untuk menyimpan banyak data.
Data historis lama akan dibaca dari Remote Storage. Ini memperjelas bagaimana Penyimpanan Lokal dan Penyimpanan Jarak Jauh saling berkomunikasi. Tidak ada deduplikasi.
Intinya apa yang terjadi. Data diambil dari penyimpanan lokal, data diambil dari penyimpanan jarak jauh jika read_recent diaktifkan. Mereka hanya bergabung bersama. Tampaknya ini bukan masalah. Jika diasumsikan bahwa kami belum melakukan downsampel data terbaru, ini adalah data yang persis sama, mereka benar-benar bertepatan dengan data lokal, kami akan memiliki sampel dua kali lebih banyak, kami tidak boleh mempengaruhi fungsi apa pun. Tidak juga. Ada fungsi irate () dan sepasang untuk itu untuk mengukur, yang mengembalikan kita perbedaan antara dua nilai terakhir. Dia melihat kembali pada rentang waktu yang ditunjukkan, tetapi hanya menggunakan dua nilai terakhir. Jika kita memiliki dua nilai terakhir memiliki waktu yang sama, maka selisihnya akan nol. Ini adalah bug dan hampir tidak mungkin menemukannya. Itu diperbaiki hanya empat hari yang lalu. Ini tiket untuk siapa pun yang tertarik.

Menariknya, baca jarak jauh telah diterapkan oleh Prometheus sejak versi 1.8. Ini adalah cara yang memungkinkan Anda membaca data Prometheus lama ketika Anda bermigrasi ke versi 2.x. Cara resmi menyarankan menghubungkannya sebagai baca jarak jauh. Data akan dikurangi sesuai kebutuhan.
Remote read dapat digunakan untuk melakukan routing query tanpa proxy. Pada salah satu slide sebelumnya, saya menunjukkan bahwa, tergantung pada waktu, kita dapat melakukan routing pada satu Prometheus atau yang lain. Dengan cara yang sama, kita bisa menghindari ini. Cukup tancapkan Prometheus di bawah ini yang merupakan read remote - dan data akan dibaca dari sana. Tetapi ada amandemen pada fakta bahwa tentu saja banyak data akan dipompa. Terutama jika Anda tidak menggunakan petunjuk permintaan.

Mengapa clickhouse
Untuk solusi penelitian kami, kami memilih ClickHouse, karena kami telah lama melihatnya. Kami memiliki orang-orang yang secara konstan terlibat dalam kinerja database, terus-menerus memeriksa database baru. Perusahaan kami bergerak di bidang basis data opensource.
Kami sangat menyukai kinerjanya yang mentah. Kekuatannya dalam hal CPU, waktu dan sebagainya, sangat bagus. Sebagian besar sistem ini berbicara tentang skalabilitas tak terbatas, tetapi berbicara sedikit tentang efisiensi untuk satu server. Banyak klien kami menyimpan metrik di sepasang server.
Replikasi bawaan, sharding.
GraphiteMergeTree adalah mesin khusus untuk menyimpan data grafit. Awalnya dia sangat tertarik pada kita.

Mesin ini dimaksudkan untuk rollup (penipisan dan agregasi / rata-rata) data Graphite.
Graphite menyimpan data lengkap di ClickHouse, dan itu bisa menerimanya, dan ia mengatakan lebih lanjut bahwa dengan penipisan GraphiteMergeTree digunakan, MergeTree digunakan tanpa penipisan. Perasaannya adalah bahwa data selalu penuh, mereka tidak ditimpa, itu hanya optimasi membaca. Tapi secara keseluruhan itu tidak buruk. Ketika kita melakukan pembacaan, kita tidak memompa data, mereka dikumpulkan secara otomatis, kita mendapatkan sedikit data - ini bagus. Kelemahan bagi kami adalah bahwa semua data disimpan.
Saya sedang bersiap di awal bulan untuk laporan. Seseorang datang dalam obrolan telegram dan bertanya - "Contoh data GraphiteMergeTree"? Saya sudah menulis no. Dokumentasi mengatakan tidak. Tetapi orang lain dalam obrolan itu menjawab, "Ya, Anda perlu memanggil optimisasi." Jalankan, periksa - ya kebenarannya. Dokumentasi pada dasarnya adalah bug. Kemudian saya membaca kode sumber, mengecek, ternyata ada yang mengoptimalkan, optimalkan yang terakhir. Final Optimize awalnya dibuat khusus untuk GraphiteMergeTree. Sebenarnya downsampling yang dia lakukan. Tetapi itu harus disebut dengan tangannya.
GraphiteMergeTree memiliki model data yang berbeda. Dia tidak memiliki label. Menulis semuanya dengan efektif atas nama metrik tidak berhasil dengan baik.
Metrik nama disimpan dalam satu tabel. Nama metrik memiliki panjang yang berbeda. Ini mengarah pada fakta bahwa jika kita melakukan pencarian indeks dengan nama metrik, karena panjangnya berbeda, indeks ini tidak akan seefektif jika indeks ini memiliki nilai panjang tetap. Karena Anda perlu melakukan pencarian file. Tidak mungkin menentukan secara pasti tempat mendarat untuk melakukan pencarian biner.

Karena itu, mereka membuat skema sendiri. Slide menunjukkan bagaimana kami menyimpan deret waktu dalam database. Tanggal yang dibutuhkan ClickHouse adalah sidik jari. Jika Anda melihat sumber-sumber Prometheus atau TSDB, maka Anda tahu bahwa sidik jari pada dasarnya adalah checksum singkat singkat dari seri waktu nama lengkap. Sidik jari adalah kombinasi dari semua label, kunci, dan nilai. Nama adalah label reguler. Kami menggunakan algoritma yang sama untuk kompatibilitas. Mendebit sesuatu bisa membuat nyaman. Sidik jari adalah sama dan dapat diperiksa di TSDB dan di penyimpanan kami bahwa mereka sama. Label disimpan dalam JSON khusus, yang memungkinkan ClickHouse bekerja dengannya dengan fungsi standarnya. Ini adalah JSON yang ringkas tanpa spasi, dengan penamaan yang sedikit disederhanakan. Tabel ini tidak digunakan selama operasi. Itu selalu disimpan dalam memori solusi aktual kami, yang disebut PromHouse. Ini digunakan hanya ketika kita memulai server untuk mengetahui seri waktu apa. Dia dikurangi. Saat seri waktu baru tiba, kami merekamnya di sana. Semua banyak instance PromHouse dapat membaca tabel yang sama. ReplacingMergeTree memberi tahu kita bahwa deret waktu ini - ada beberapa contoh yang berbeda - tulis deret waktu yang sama. Mereka akan bertengkar - dan tidak akan ada masalah di sini.

Kami menyimpan sampel dalam tabel terpisah dengan sangat efisien. Dengan nilai panjang tetap, sidik jari ini sama, waktu dan nilainya. Kami mendapatkan 24 byte per sampel. Ini memiliki panjang yang benar-benar tetap. Setiap kolom disimpan secara terpisah. Pencarian sidik jari efektif karena kita tahu bahwa ukurannya tetap. Tidak ada masalah dengan GraphitmergeTree saat ini adalah sebuah string. Kami menggunakan partisi khusus. Indeks sidik jari primer dan oleh waktu.
24 byte adalah versi yang disederhanakan. Bahkan, kompresnya baik. Bahkan menggunakan lebih sedikit ruang. Dalam pengujian terbaru kami, rasio kompresi sekitar 1 hingga 42.

Bagaimana kita dapat melakukan downsampling manual jika kita memiliki GraphiteMergeTree, tetapi tidak sama seperti yang kita inginkan. Padahal, kita bisa melakukannya dengan tangan. Seperti yang sebelumnya dilakukan sharding, partisi, ketika tidak ada built-in. Kami membuat meja baru dengan tangan kami. Ketika sampel waktu datang kepada kami, kami menentukan tabel yang kami tulis.
Kami memilih waktu dari kueri dari tabel mana untuk dibaca. Jika pembacaan terjadi di perbatasan, kami membaca beberapa tabel. Selanjutnya kita pegang data ini. Orang bisa menggunakan tampilan untuk ini. Misalnya, buat tampilan untuk beberapa tabel, yang memungkinkannya dibaca dalam satu kueri. Tetapi ada bug di ClickHouse: predikat dari tampilan tidak diganti ke dalam kueri. Oleh karena itu, jika Anda membuat permintaan dalam tampilan, maka masuk ke semua tabel. Lihat tidak bisa kita gunakan.
Bagaimana kita melakukan downsampling? Kami membuat tabel sementara. Salin sisipan ke data pilih dari itu menggunakan fungsi yang benar.
Kami membuat penggantian nama yang merupakan atom di bawah kunci global. Kami mengganti nama tabel yang ada dengan yang lama. Baru ada. Kami menjatuhkan meja lama. Kami memiliki data selama 148 hari sudah downsampling. Apa masalahnya di sini? Masukkan ke terlihat cantik. Bahkan, kita perlu menerapkan fungsi yang benar, agregasi yang tepat untuk dilakukan. Dalam praktiknya, ini tidak dapat dilakukan dengan satu permintaan besar. Bahkan beberapa permintaan besar tidak dapat dibuat. Ini harus dilakukan dari kode. Kode mengirimkan sejumlah besar permintaan kecil. Kami mencoba melakukan yang terbaik dengan permintaan besar, tetapi ini tidak terlalu efektif. Downsampling data dari satu hari sejauh ini membutuhkan waktu kurang dari sehari. Tergantung pada jumlah data, itu bisa memakan waktu lama.

ClickHouse akan memperbarui / menghapus. Hapus sudah punya versi pertama. Jika pembaruan / penghapusan berfungsi, maka skema data downsampling kami dapat disederhanakan.
Kedua, ClickHouse memiliki tugas untuk membuat kompresi khusus (delta, delta ke delta). Inilah yang dilakukan TSDB. Ini sangat cocok untuk data deret waktu. Ini sangat berguna jika kita akan dapat memilih jenis kompresi tergantung pada tipe data. Misalnya, penghitung, yang hanya bertambah - untuk ini, kompresi delta-delta cocok. Ukuran yang berfluktuasi di sekitar besaran, sehingga delta berfungsi dengan baik.

Ada penyimpanan lain yang berfungsi. Ada InfluxDB yang berfungsi di luar kotak. Adalah kebiasaan untuk memarahinya karena kecepatan, tetapi apa yang berhasil di luar kotak dan Anda tidak perlu melakukan apa pun itu baik.
Ada OpenTSDB dan Graphite, yang hanya menulis. Adaptor standar dari Prometheus tidak benar-benar berfungsi.
Ada CrateDB. Ada TimescaleDB yang menggunakan PostgreSQL untuk database deret waktu. Mereka mengatakan itu bekerja dengan baik, tetapi kita sendiri belum mencobanya.
Ada Cortex, yang juga dikenal sebagai proyek Frankenstein. Ini menggambarkannya dengan sangat baik. Ini adalah orang-orang yang mencoba membuat keputusan berdasarkan federasi Prometheus. Mereka menyimpan data dalam S3.
Ada Thanos.
- Ia memiliki arsitektur yang sangat menarik. Ada Prometheus yang menggunakan TSDB lokal. Cluster dibuat di antara mereka. Di sebelah setiap Prometheus terdapat mobil samping khusus, yang menerima permintaan melalui API baca dan baca jarak jauh. Dia mengalihkan permintaan ini ke Prometheus. Prometheus dapat menggunakan API baca jauh dan tulis jarak jauh. Semua mobil samping saling berhubungan dan antara master API kustom melalui gRPC, replikasi tersedia, ada shading ulang.
- Arsitektur yang canggih.
- Cukup lembab. Beberapa bulan yang lalu, itu terlepas dari tendangan setengah ketika itu dimulai.

Menggunakan model tarikan tidak menulis banyak data. Anda perlu menunggu satu tahun penuh untuk mengisi data tahunan. Kami mencoba menulisnya di sana.
Tidak ada penulisan jarak jauh di Prometheus, oleh karena itu, menulis banyak data ke TSDB lokal tidak akan berfungsi.
Masalah kedua. Jika kita menghasilkan data untuk pengujian stres, maka mereka sering bergetar dengan baik. Sebagai contoh, jika kita mengambil data yang ada dan menghasilkan 100 instance, dan ini adalah data yang sama, maka koefisien kompresi akan sangat indah sehingga pada kenyataannya tidak terjadi.

Kami menulis eksportir palsu yang terlihat seperti eksportir biasa yang dapat disatukan oleh Prometheus:
- Ketika memo masuk, ia pergi ke beberapa eksportir hulu. Mengambil data darinya.
- Menghasilkan banyak contoh. Katakanlah 1 adalah scrapie, dan kami mendapatkan 100 pada output.
- Mengubah data sedikit: plus minus 10% untuk penghitung dan pengukur.
- Itu tidak mengubah nilai-nilai sederhana 0 atau 1. Karena jika ada metrik UP yang merespons itu menunjukkan apakah layanan sedang berjalan: ya - 1 atau tidak - 0. Dan tidak jelas apa artinya 098 UP artinya.
- Kami tidak mengubah bilangan bulat ke yang nyata dan sebaliknya.
- Itu hanya memberikan data dalam format expfmt yang biasa.

Alat promload yang memuat data. Membaca data:
- Dapat membaca dari file dalam formatnya sendiri
- Mungkin dari jauh membaca
- Dapat membaca dari beberapa eksportir
Menulis dalam berbagai format. Termasuk di / dev / null, jika kita ingin menguji dengan tepat cara membaca bekerja dengan cepat.
Sekarang ini adalah alat pengujian beban tidak hanya untuk PromHouse, tetapi juga untuk solusi apa pun yang menggunakan pembacaan jarak jauh atau Prometheus.

Kami ingin menambahkan caching baca, karena dalam pengujian kami kemacetan sering kali adalah eksportir palsu, yang menghasilkan data untuk waktu yang lama. Kita bisa menyimpannya. Biarkan mereka menjadi luar biasa baik. Tapi kami tidak akan melambat. Kami tidak perlu menunggu berhari-hari untuk pengujian stres.
Semacam penyaringan on the fly, semacam modifikasi on the fly.
Dukungan asli untuk TSDB. Agar dapat bekerja dengan database pada disk, dan tidak melalui API.
Fokus pada akurasi untuk migrasi. Saya pernah pmmdemo.percona.com menempatkan: terhubung, menerima semua metrik. Jika Anda melakukan ini dengan cara asli, maka Prometheus membuka TSDB, menaikkan semua deret waktu dari disk, menaikkan indeks, lalu merayapi ke dalam file chunk, menyadari bahwa mereka benar-benar ada. Pada titik ini, semuanya bisa berbaring.
Pendekatan naif adalah mengambil seluruh rangkaian waktu dan membaca dari data lama ke yang baru. Pada saat itu dia akan berbaring. Anda perlu melakukan yang sebaliknya. Pertama, Anda perlu mendapatkan daftar seri waktu dengan beberapa pertanyaan dengan ekspresi reguler. Misalnya, deret waktu yang dimulai pada A. Lalu beri saya deret waktu yang dimulai pada B. Lalu muat mereka persis dengan metrik, bukan berdasarkan waktu. Ini tidak masuk akal, tetapi ini cara kerjanya. Ini adalah nuansa jika Anda melakukan sesuatu seperti itu. Jika Anda melihat bahwa OOM Killer terjadi di sana, maka Anda akan tahu bahwa itu karena Anda.

Hasil pengujian beban, tidak akan ada grafik. Pengujian beban membutuhkan banyak waktu dan, sayangnya, karena kesalahan konfigurasi, semuanya salah. Karena itu, hasilnya tidak membuahkan hasil.
Kami akan menulis di blog Percona ketika kami melakukan pengujian.
Saya bisa mengatakan hasilnya tanpa grafik. Rekaman itu linear. Membaca melompat dan tidak terlalu cepat. Membaca data saat ini tidak terlalu penting bagi kami. Mereka dapat dipercepat melalui petunjuk baca. Anda dapat mengaktifkan read_recent untuk meningkatkan kemampuan membaca. Dan untuk data lama, ini berfungsi dengan baik.

Orang menginginkan penyimpanan jangka panjang. Ada permintaan seperti itu. Kami berbicara tentang PromHouse di PromCon. Itu adalah topik yang sangat panas. Thanos secara aktif berkembang.
Itu sudah mungkin sekarang. Ada solusi untuk ini. Ada sebuah API. Ada beberapa integrasi. Tetapi semua ini harus diselesaikan dengan file. Tidak ada solusi siap produksi.

Tautan ke mana harus mencari. Tautan pertama adalah gudang PromHouse. Tautan kedua adalah tempat dia kemungkinan akan pindah. Sekarang dalam satu repositori ada beberapa hal berbeda? tidak terkait sangat erat. Karena itu, Anda perlu mentransfernya.
Blog kami akan berisi informasi tentang kinerja dan beberapa berita.
Pertanyaan:
Pertanyaan: Sudahkah Anda memeriksa rumor tentang InfluxDB?
Jawab: Dia tidak terlalu baik. Dia menjadi jauh lebih baik. Semua cerita ini tentang fakta bahwa InfluxDB lambat, berantakan - itu tentang versi lama. Versi saat ini stabil. Saya tidak akan mengatakan? bahwa ia bekerja dengan cepat. Tapi itu bekerja dengan stabil. Kelebihan dari InfluxDB menurut saya:
- Pertama, tidak perlu melakukan sesuatu di dekatnya, karena InfluxDB bekerja di luar kotak.
- Kedua, di ClickHouse, seperti pada solusi berbasis basis data lainnya, tetapi bukan TSDB, Anda bisa menggunakan bahasa permintaan yang lebih akrab bagi Anda. Bahasa permintaan InfluxDB mirip dengan SQL. Anda dapat melakukan analisis di atasnya, yang sulit dilakukan di PromQL. Jika Anda menggunakan TimeScaleDB - ada SQL nyata.
Pertanyaan: Apakah mesin GraphiteMergeTree hanya untuk pekerjaan perekaman? Jika kita ingin menampilkan grafik, apakah Grafana perlu disiapkan di Graphite untuk menunjukkan penyimpanan jangka panjang?
Jawab: Ya. Integrasi yang ada di Prometheus sendiri hanya berfungsi untuk merekam. Dia hanya menulis data. Jadi dari Grafana Anda pergi ke Graphite.
Pertanyaan: Dan dia kehilangan label ketika dia menulis?
Jawaban: Ada konfigurasi yang mengatakan apa yang harus dilakukan dengan mereka, cara memasukkannya, di mana memasukkannya.
Informasi dari penonton: Avito mengatakan bahwa mereka sedang menulis solusi mereka untuk rekaman dari Prometheus ke Graphite.
Pertanyaan: ada kesimpulan bahwa dengan merekam semuanya baik-baik saja di server penyimpanan jangka panjang.
(5- 15-). raid 6 sata ?
: PMM — . downsampling c 14 1 . , . . . .
: IOPS ?
: .
:
: . , . , , .
: InfluxDB, InfluxDB?
: read_recent. , remote storage. InfluxDB . . read_recent , .
: , Prometheus. InfluxDB. Grafana Prometheus. Prometheus PromQL , InfluxDB?
: .
: Prometheus InfluxDB Grafana?
: . Prometheus 2.2 , .
PS : valyala gecube
, .