Bioyino - pengagregat metrik boleh skala yang diedarkan

Jadi anda mengumpul metrik. Seperti kita. Kami juga mengumpul metrik. Sudah tentu, perlu untuk perniagaan. Hari ini kita akan bercakap tentang pautan pertama sistem pemantauan kami - pelayan pengagregatan yang serasi dengan statsd bioyino, mengapa kami menulisnya dan mengapa kami meninggalkan brubeck.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Daripada artikel kami sebelum ini (1, 2) anda boleh mengetahui bahawa sehingga beberapa ketika kami mengumpul markah menggunakan Brubeck. Ia ditulis dalam C. Dari sudut pandangan kod, ia semudah palam (ini penting apabila anda ingin menyumbang) dan, yang paling penting, ia mengendalikan volum kami sebanyak 2 juta metrik sesaat (MPS) pada puncak tanpa sebarang masalah. Dokumentasi menyatakan sokongan untuk 4 juta MPS dengan asterisk. Ini bermakna anda akan mendapat angka yang dinyatakan jika anda mengkonfigurasi rangkaian dengan betul pada Linux. (Kami tidak tahu berapa banyak MPS yang anda boleh dapat jika anda meninggalkan rangkaian seperti sedia ada). Di sebalik kelebihan ini, kami mempunyai beberapa aduan serius tentang brubeck.

Tuntutan 1. Github, pembangun projek, berhenti menyokongnya: menerbitkan patch dan pembetulan, menerima kami dan (bukan sahaja kami) PR. Dalam beberapa bulan kebelakangan ini (dari Februari-Mac 2018), aktiviti telah disambung semula, tetapi sebelum itu terdapat hampir 2 tahun ketenangan sepenuhnya. Di samping itu, projek itu sedang dibangunkan untuk keperluan Gihub dalaman, yang boleh menjadi halangan serius kepada pengenalan ciri baharu.

Tuntutan 2. Ketepatan pengiraan. Brubeck mengumpul sejumlah 65536 nilai untuk pengagregatan. Dalam kes kami, untuk sesetengah metrik, semasa tempoh pengagregatan (30 saat), lebih banyak nilai mungkin tiba (1 pada puncak). Hasil daripada pensampelan ini, nilai maksimum dan minimum kelihatan tidak berguna. Sebagai contoh, seperti ini:

Bioyino - pengagregat metrik boleh skala yang diedarkan
Seperti yang berlaku

Bioyino - pengagregat metrik boleh skala yang diedarkan
Bagaimana ia sepatutnya

Atas sebab yang sama, jumlah biasanya dikira secara tidak betul. Tambahkan di sini pepijat dengan limpahan apungan 32-bit, yang biasanya menghantar pelayan ke segfault apabila menerima metrik yang kelihatan tidak bersalah, dan semuanya menjadi hebat. Pepijat, dengan cara ini, belum diperbaiki.

Dan, akhirnya, Tuntutan X. Pada masa penulisan, kami bersedia untuk membentangkannya kepada semua 14 lebih atau kurang pelaksanaan statistik berfungsi yang kami dapat temui. Bayangkan beberapa infrastruktur tunggal telah berkembang dengan pesat sehingga menerima 4 juta MPS tidak lagi mencukupi. Atau walaupun ia belum berkembang lagi, tetapi metriknya sudah sangat penting kepada anda sehinggakan penurunan dalam carta yang singkat, 2-3 minit pun boleh menjadi kritikal dan menyebabkan kemurungan yang tidak dapat diatasi dalam kalangan pengurus. Memandangkan merawat kemurungan adalah tugas yang tidak berterima kasih, penyelesaian teknikal diperlukan.

Pertama, toleransi kesalahan, supaya masalah tiba-tiba pada pelayan tidak menyebabkan apocalypse zombi psikiatri di pejabat. Kedua, skala untuk dapat menerima lebih daripada 4 juta MPS, tanpa menggali jauh ke dalam susunan rangkaian Linux dan dengan tenang berkembang "dalam keluasan" kepada saiz yang diperlukan.

Memandangkan kami mempunyai ruang untuk penskalaan, kami memutuskan untuk memulakan dengan toleransi kesalahan. "TENTANG! Toleransi kesalahan! Ia mudah, kami boleh melakukannya,” kami berfikir dan melancarkan 2 pelayan, menaikkan satu salinan brubeck pada setiap satu. Untuk melakukan ini, kami perlu menyalin trafik dengan metrik ke kedua-dua pelayan dan juga menulis untuk ini utiliti kecil. Kami menyelesaikan masalah toleransi kesalahan dengan ini, tetapi... tidak begitu baik. Pada mulanya semuanya kelihatan hebat: setiap brubeck mengumpul versi pengagregatannya sendiri, menulis data kepada Graphite sekali setiap 30 saat, menimpa selang lama (ini dilakukan di sebelah Grafit). Jika satu pelayan tiba-tiba gagal, kami sentiasa mempunyai pelayan kedua dengan salinan data agregatnya sendiri. Tetapi inilah masalahnya: jika pelayan gagal, "gergaji" muncul pada graf. Ini disebabkan oleh fakta bahawa selang 30 saat brubeck tidak disegerakkan, dan pada saat ranap salah satu daripadanya tidak ditimpa. Apabila pelayan kedua bermula, perkara yang sama berlaku. Cukup boleh diterima, tetapi saya mahu lebih baik! Masalah skalabiliti juga tidak hilang. Semua metrik masih "terbang" ke pelayan tunggal, dan oleh itu kami terhad kepada 2-4 juta MPS yang sama, bergantung pada tahap rangkaian.

Jika anda berfikir sedikit tentang masalah itu dan pada masa yang sama menggali salji dengan penyodok, idea jelas berikut mungkin terlintas di fikiran: anda memerlukan statistik yang boleh berfungsi dalam mod teragih. Iaitu, yang melaksanakan penyegerakan antara nod dalam masa dan metrik. "Sudah tentu, penyelesaian sedemikian mungkin sudah wujud," kami berkata dan pergi ke Google…. Dan mereka tidak menemui apa-apa. Selepas melalui dokumentasi untuk statistik berbeza (https://github.com/etsy/statsd/wiki#server-implementations setakat 11.12.2017 Disember XNUMX), kami tidak menemui apa-apa. Nampaknya, baik pembangun mahupun pengguna penyelesaian ini belum menemui begitu banyak metrik, jika tidak, mereka pasti akan menghasilkan sesuatu.

Dan kemudian kami teringat tentang statistik "mainan" - bioyino, yang ditulis di hackathon Just for Fun (nama projek dijana oleh skrip sebelum permulaan hackathon) dan menyedari bahawa kami memerlukan statistik kami sendiri dengan segera. Untuk apa?

  • kerana terdapat terlalu sedikit klon statistik di dunia,
  • kerana adalah mungkin untuk memberikan yang dikehendaki atau hampir dengan toleransi kesalahan dan skalabiliti yang diingini (termasuk menyegerakkan metrik agregat antara pelayan dan menyelesaikan masalah penghantaran konflik),
  • kerana adalah mungkin untuk mengira metrik dengan lebih tepat daripada yang dilakukan oleh brubeck,
  • kerana anda boleh mengumpul statistik yang lebih terperinci sendiri, yang secara praktikalnya tidak diberikan oleh brubeck kepada kami,
  • kerana saya mempunyai peluang untuk memprogramkan hiperperformance distributedscalelabplication saya sendiri, yang tidak akan mengulang sepenuhnya seni bina hiper yang serupa untuk... baik, itu sahaja.

Apa yang hendak ditulis? Sudah tentu, di Rust. kenapa?

  • kerana sudah ada penyelesaian prototaip,
  • kerana pengarang artikel itu sudah mengenali Rust pada masa itu dan tidak sabar-sabar untuk menulis sesuatu di dalamnya untuk pengeluaran dengan peluang untuk meletakkannya dalam sumber terbuka,
  • kerana bahasa dengan GC tidak sesuai untuk kami kerana sifat trafik yang diterima (hampir masa nyata) dan jeda GC secara praktikalnya tidak boleh diterima,
  • kerana anda memerlukan prestasi maksimum setanding dengan C
  • kerana Rust membekalkan kita dengan ketabahan tanpa rasa takut, dan jika kita mula menulisnya dalam C/C++, kita akan mendapat lebih banyak kelemahan, limpahan penampan, keadaan perlumbaan dan perkataan menakutkan lain daripada brubeck.

Terdapat juga hujah terhadap Rust. Syarikat itu tidak mempunyai pengalaman mencipta projek di Rust, dan kini kami juga tidak bercadang untuk menggunakannya dalam projek utama. Oleh itu, terdapat kebimbangan serius bahawa tiada apa-apa akan berjaya, tetapi kami memutuskan untuk mengambil peluang dan mencuba.

Masa berlalu...

Akhirnya, selepas beberapa percubaan yang gagal, versi pertama yang berfungsi telah sedia. Apa yang berlaku? Inilah yang berlaku.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Setiap nod menerima set metriknya sendiri dan mengumpulkannya serta tidak mengagregat metrik untuk jenis yang set lengkapnya diperlukan untuk pengagregatan akhir. Nod disambungkan antara satu sama lain oleh beberapa jenis protokol kunci yang diedarkan, yang membolehkan anda memilih antara mereka satu-satunya (di sini kami menangis) yang layak menghantar metrik kepada Yang Hebat. Masalah ini sedang diselesaikan oleh Konsul, tetapi pada masa hadapan cita-cita penulis meluaskan kepada sendiri pelaksanaan Rakit, di mana yang paling layak, sudah tentu, menjadi nod ketua konsensus. Selain konsensus, nod agak kerap (sekali sesaat secara lalai) menghantar kepada jiran mereka bahagian metrik pra-agregat yang mereka berjaya kumpulkan dalam detik itu. Ternyata penskalaan dan toleransi kesalahan dikekalkan - setiap nod masih memegang set penuh metrik, tetapi metrik dihantar sudah diagregatkan, melalui TCP dan dikodkan ke dalam protokol binari, jadi kos penduaan dikurangkan dengan ketara berbanding UDP. Walaupun bilangan metrik masuk yang agak besar, pengumpulan memerlukan memori yang sangat sedikit dan juga kurang CPU. Untuk mertik kami yang sangat boleh mampat, ini hanya beberapa puluh megabait data. Sebagai bonus tambahan, kami tidak mendapat penulisan semula data yang tidak perlu dalam Grafit, seperti yang berlaku dengan burbeck.

Paket UDP dengan metrik tidak seimbang antara nod pada peralatan rangkaian melalui Round Robin yang ringkas. Sudah tentu, perkakasan rangkaian tidak menghuraikan kandungan paket dan oleh itu boleh menarik lebih daripada 4M paket sesaat, apatah lagi metrik yang ia tidak tahu apa-apa sama sekali. Jika kami mengambil kira bahawa metrik tidak datang satu demi satu dalam setiap paket, maka kami tidak meramalkan sebarang masalah prestasi di tempat ini. Jika pelayan ranap, peranti rangkaian dengan cepat (dalam 1-2 saat) mengesan fakta ini dan mengalih keluar pelayan ranap daripada putaran. Akibat daripada ini, nod pasif (iaitu, bukan pemimpin) boleh dihidupkan dan dimatikan secara praktikal tanpa melihat penarikan pada carta. Maksimum yang kita hilang adalah sebahagian daripada metrik yang masuk pada saat terakhir. Kehilangan/penutupan/suis pemimpin secara tiba-tiba masih akan mewujudkan anomali kecil (selang 30 saat masih tidak segerak), tetapi jika terdapat komunikasi antara nod, masalah ini boleh diminimumkan, contohnya, dengan menghantar paket penyegerakan .

Sedikit mengenai struktur dalaman. Aplikasi ini, sudah tentu, berbilang benang, tetapi seni bina benang berbeza daripada yang digunakan dalam brubeck. Benang dalam brubeck adalah sama - setiap daripada mereka bertanggungjawab untuk kedua-dua pengumpulan maklumat dan pengagregatan. Dalam bioyino, pekerja dibahagikan kepada dua kumpulan: mereka yang bertanggungjawab untuk rangkaian dan mereka yang bertanggungjawab untuk pengagregatan. Bahagian ini membolehkan anda mengurus aplikasi dengan lebih fleksibel bergantung pada jenis metrik: di mana pengagregatan intensif diperlukan, anda boleh menambah pengagregat, di mana terdapat banyak trafik rangkaian, anda boleh menambah bilangan aliran rangkaian. Pada masa ini, pada pelayan kami, kami bekerja dalam 8 rangkaian dan 4 aliran pengagregatan.

Bahagian pengiraan (bertanggungjawab untuk pengagregatan) agak membosankan. Penampan yang diisi oleh aliran rangkaian diedarkan antara aliran mengira, di mana ia kemudiannya dihuraikan dan diagregatkan. Atas permintaan, metrik diberikan untuk dihantar ke nod lain. Semua ini, termasuk menghantar data antara nod dan bekerja dengan Konsul, dilakukan secara tidak segerak, berjalan pada rangka kerja Tokyo.

Lebih banyak masalah semasa pembangunan disebabkan oleh bahagian rangkaian yang bertanggungjawab untuk menerima metrik. Matlamat utama untuk memisahkan aliran rangkaian kepada entiti yang berasingan ialah keinginan untuk mengurangkan masa yang dibelanjakan oleh aliran tiada untuk membaca data daripada soket. Pilihan menggunakan UDP tak segerak dan recvmsg biasa cepat hilang: yang pertama menggunakan terlalu banyak CPU ruang pengguna untuk pemprosesan acara, yang kedua memerlukan terlalu banyak suis konteks. Oleh itu ia kini digunakan recvmmsg dengan penimbal besar (dan penimbal, tuan-tuan pegawai, tiada apa-apa bagi anda!). Sokongan untuk UDP biasa dikhaskan untuk kes ringan di mana recvmmsg tidak diperlukan. Dalam mod berbilang mesej, adalah mungkin untuk mencapai perkara utama: sebahagian besar masa, benang rangkaian meraut baris gilir OS - membaca data dari soket dan memindahkannya ke penimbal ruang pengguna, hanya sekali-sekala bertukar kepada memberikan penimbal yang diisi kepada agregator. Barisan gilir dalam soket secara praktikal tidak terkumpul, bilangan paket yang dijatuhkan secara praktikal tidak berkembang.

Nota

Dalam tetapan lalai, saiz penimbal ditetapkan menjadi agak besar. Jika anda tiba-tiba memutuskan untuk mencuba pelayan sendiri, anda mungkin menghadapi hakikat bahawa selepas menghantar sebilangan kecil metrik, ia tidak akan tiba di Graphite, kekal dalam penimbal strim rangkaian. Untuk bekerja dengan sebilangan kecil metrik, anda perlu menetapkan bufsize dan task-queue-size kepada nilai yang lebih kecil dalam konfigurasi.

Akhir sekali, beberapa carta untuk pencinta carta.

Statistik tentang bilangan metrik masuk untuk setiap pelayan: lebih daripada 2 juta MPS.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Melumpuhkan salah satu nod dan mengagihkan semula metrik masuk.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Statistik tentang metrik keluar: hanya satu nod yang sentiasa dihantar - bos serbuan.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Statistik operasi setiap nod, dengan mengambil kira ralat dalam pelbagai modul sistem.

Bioyino - pengagregat metrik boleh skala yang diedarkan

Perincian metrik masuk (nama metrik disembunyikan).

Bioyino - pengagregat metrik boleh skala yang diedarkan

Apa yang kita rancang untuk lakukan dengan semua ini seterusnya? Sudah tentu, tulis kod, sial...! Projek ini pada asalnya dirancang untuk menjadi sumber terbuka dan akan kekal begitu sepanjang hayatnya. Pelan segera kami termasuk menukar kepada versi Raft kami sendiri, menukar protokol rakan sebaya kepada yang lebih mudah alih, memperkenalkan statistik dalaman tambahan, jenis metrik baharu, pembetulan pepijat dan penambahbaikan lain.

Sudah tentu, semua orang dialu-alukan untuk membantu dalam pembangunan projek: mewujudkan PR, Isu, jika boleh kami akan bertindak balas, menambah baik, dll.

Dengan itu dikatakan, itu semua orang, beli gajah kami!



Sumber: www.habr.com

Tambah komen