Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Böylece metrikleri topluyorsunuz. Biz olduğumuz gibi. Ayrıca ölçümleri de topluyoruz. Elbette iş için gerekli. Bugün izleme sistemimizin ilk bağlantısı olan istatistik uyumlu bir toplama sunucusundan bahsedeceğiz. biyoyino, bunu neden yazdık ve neden Brubeck'ten vazgeçtik.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Önceki yazılarımızdan (1, 2) bir süreye kadar notları topladığımızı öğrenebilirsiniz. Brübeck. C dilinde yazılmıştır. Kod açısından bakıldığında bir fiş kadar basittir (katkıda bulunmak istediğinizde bu önemlidir) ve en önemlisi, zirvede saniyede 2 milyon metrik (MPS) hacmimizi yönetir. herhangi bir sorun olmadan. Belgelerde yıldız işaretiyle 4 milyon MPS desteği belirtilmektedir. Bu, ağı Linux'ta doğru şekilde yapılandırırsanız belirtilen rakamı alacağınız anlamına gelir. (Ağı olduğu gibi bırakırsanız kaç MPS alabileceğinizi bilmiyoruz). Bu avantajlara rağmen brubeck ile ilgili çok sayıda ciddi şikayetimiz vardı.

İddia 1. Projenin geliştiricisi Github, onu desteklemeyi bıraktı: yamalar ve düzeltmeler yayınlamak, bizimkini ve (sadece bizim değil) PR'yi kabul etmek. Son birkaç ayda (Şubat-Mart 2018 arası) faaliyetler yeniden başladı, ancak bundan önce neredeyse 2 yıllık tam bir sakinlik vardı. Ayrıca proje geliştiriliyor dahili Gihub ihtiyaçları içinBu, yeni özelliklerin tanıtılmasının önünde ciddi bir engel olabilir.

İddia 2. Hesaplamaların doğruluğu. Brubeck, toplama için toplam 65536 değer toplar. Bizim durumumuzda bazı metrikler için toplama süresi boyunca (30 saniye) çok daha fazla değer gelebilir (zirvede 1). Bu örnekleme sonucunda maksimum ve minimum değerler işe yaramaz görünmektedir. Örneğin şöyle:

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı
Olduğu gibi

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı
Nasıl olmalıydı

Aynı sebepten dolayı tutarlar genellikle yanlış hesaplanmaktadır. Buraya, görünüşte masum bir ölçüm alırken genellikle sunucuyu segfault'a gönderen 32 bitlik kayan taşma ile ilgili bir hata ekleyin ve her şey mükemmel hale gelir. Bu arada hata düzeltilmedi.

Ve nihayet, X'i talep et. Bu yazının yazıldığı sırada, bulabildiğimiz az çok çalışan 14 istatistik uygulamasının tümüne bunu sunmaya hazırız. Tek bir altyapının o kadar büyüdüğünü ve 4 milyon MPS kabul etmenin artık yeterli olmadığını düşünelim. Ya da henüz büyümemiş olsa bile, metrikler sizin için o kadar önemli ki, grafiklerdeki 2-3 dakikalık kısa düşüşler bile zaten kritik hale gelebilir ve yöneticiler arasında aşılmaz depresyon nöbetlerine neden olabilir. Depresyonu tedavi etmek nankör bir iş olduğundan teknik çözümlere ihtiyaç vardır.

Birincisi, hata toleransı, böylece sunucuda ani bir sorun ofiste psikiyatrik bir zombi kıyametine neden olmaz. İkincisi, Linux ağ yığınının derinliklerine inmeden ve gerekli boyuta "genişlikte" sakin bir şekilde büyümeden, 4 milyondan fazla MPS'yi kabul edebilecek şekilde ölçeklendirme.

Ölçeklendirme için yerimiz olduğundan hata toleransıyla başlamaya karar verdik. "HAKKINDA! Hata toleransı! Çok basit, yapabiliriz” diye düşündük ve her birinde brubeck kopyasını yükselterek 2 sunucu başlattık. Bunu yapmak için metriklerin bulunduğu trafiği her iki sunucuya da kopyalamamız ve hatta bunun için yazmamız gerekiyordu. küçük yardımcı program. Bununla hata toleransı problemini çözdük ama... pek iyi değil. İlk başta her şey harika görünüyordu: her brubeck kendi toplama versiyonunu topluyor, verileri her 30 saniyede bir Grafit'e yazıyor, eski aralığın üzerine yazıyor (bu Grafit tarafında yapılıyor). Bir sunucu aniden arızalanırsa, her zaman toplanmış verilerin kendi kopyasını içeren ikinci bir sunucumuz olur. Ancak sorun şu: Sunucu arızalanırsa grafiklerde bir "testere" belirir. Bunun nedeni, Brubeck'in 30 saniyelik aralıklarının senkronize olmaması ve çarpışma anında bunlardan birinin üzerine yazılmamasıdır. İkinci sunucu başladığında da aynı şey oluyor. Oldukça tolere edilebilir, ama daha iyisini istiyorum! Ölçeklenebilirlik sorunu da ortadan kalkmadı. Tüm ölçümler hala tek bir sunucuya "uçuyor" ve bu nedenle ağ düzeyine bağlı olarak aynı 2-4 milyon MPS ile sınırlıyız.

Sorun hakkında biraz düşünürseniz ve aynı zamanda kürekle kar kazarsanız, aklınıza şu bariz fikir gelebilir: dağıtılmış modda çalışabilecek bir istatistiklere ihtiyacınız var. Yani, zaman ve ölçümlerdeki düğümler arasında senkronizasyonu uygulayan bir sistemdir. “Elbette böyle bir çözüm muhtemelen zaten vardır” dedik ve Google’a gittik…. Ve hiçbir şey bulamadılar. Farklı istatistikler için belgeleri inceledikten sonra (https://github.com/etsy/statsd/wiki#server-implementations 11.12.2017 Aralık XNUMX itibarıyla kesinlikle hiçbir şey bulamadık. Görünüşe göre, bu çözümlerin ne geliştiricileri ne de kullanıcıları henüz ÇOK fazla ölçümle karşılaşmadı, aksi takdirde kesinlikle bir şeyler bulurlardı.

Sonra Just for Fun hackathon'unda yazılan "oyuncak" istatistiklerini - bioyino'yu hatırladık (projenin adı hackathon başlamadan önce senaryo tarafından oluşturuldu) ve kendi istatistiklerimize acilen ihtiyacımız olduğunu fark ettik. Ne için?

  • çünkü dünyada çok az statsd klonu var,
  • istenilen veya istenilene yakın hata toleransı ve ölçeklenebilirliğin sağlanması mümkün olduğundan (sunucular arasında toplu metriklerin senkronize edilmesi ve çakışma gönderme sorununun çözülmesi dahil),
  • çünkü metrikleri Brubeck'ten daha doğru hesaplamak mümkündür,
  • çünkü Brubeck'in bize pratik olarak sunmadığı daha ayrıntılı istatistikleri kendiniz toplayabilirsiniz,
  • çünkü başka bir benzer hiperforun mimarisini tamamen tekrarlamayacak kendi hiperperformanslı dağıtılmış ölçek laboratuvar uygulamamı programlama şansım oldu... işte bu kadar.

Ne yazmalı? Tabii ki Rust'ta. Neden?

  • çünkü zaten bir prototip çözüm vardı,
  • çünkü makalenin yazarı o zamanlar Rust'u zaten tanıyordu ve onu açık kaynağa koyma fırsatıyla birlikte üretim için bir şeyler yazmaya hevesliydi,
  • Alınan trafiğin doğası gereği (neredeyse gerçek zamanlı) GC'li diller bizim için uygun olmadığından ve GC duraklamaları pratik olarak kabul edilemez olduğundan,
  • çünkü C ile karşılaştırılabilecek maksimum performansa ihtiyacınız var
  • çünkü Rust bize korkusuz eşzamanlılık sağlıyor ve eğer bunu C/C++ ile yazmaya başlasaydık, brubeck'ten çok daha fazla güvenlik açığını, arabellek taşmasını, yarış koşullarını ve diğer korkutucu kelimeleri araştırırdık.

Rust'a karşı da bir tartışma vardı. Şirketin Rust'ta proje oluşturma deneyimi yoktu ve şimdi de onu ana projede kullanmayı planlamıyoruz. Bu nedenle hiçbir şeyin yolunda gitmeyeceğine dair ciddi korkular vardı ama biz şansımızı denemeye karar verdik ve denedik.

Zaman Geçti...

Sonunda, birkaç başarısız denemeden sonra ilk çalışan sürüm hazırdı. Ne oldu? Olan şey bu.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Her düğüm kendi metrik kümesini alır ve bunları biriktirir ve son toplama için tam kümenin gerekli olduğu türler için metrikleri toplamaz. Düğümler birbirine bir çeşit dağıtılmış kilit protokolü ile bağlanır, bu da aralarından Büyük Olan'a metrik göndermeye layık olan tek olanı (burada ağladık) seçmenize olanak tanır. Bu sorun şu anda tarafından çözülmektedir konsolos, ancak gelecekte yazarın tutkuları genişliyor kendi uygulama En değerli olanın elbette fikir birliği lideri düğümü olacağı Raft. Konsensüse ek olarak, düğümler sıklıkla (varsayılan olarak saniyede bir kez) komşularına, o saniyede toplamayı başardıkları önceden toplanmış ölçüm parçalarını gönderir. Ölçeklendirmenin ve hata toleransının korunduğu ortaya çıktı; her düğüm hâlâ tam bir metrik kümesi barındırıyor, ancak metrikler zaten toplu olarak TCP aracılığıyla gönderiliyor ve ikili bir protokole kodlanmış durumda, böylece çoğaltma maliyetleri UDP'ye kıyasla önemli ölçüde azalıyor. Oldukça fazla sayıda gelen ölçüme rağmen, birikim çok az bellek ve hatta daha az CPU gerektirir. Oldukça sıkıştırılabilir ölçümlerimiz için bu yalnızca birkaç on megabaytlık veridir. Ek bir avantaj olarak, burbeck'te olduğu gibi Grafit'te gereksiz veri yeniden yazma işlemleriyle karşılaşmıyoruz.

Metrikli UDP paketleri, basit bir Round Robin yoluyla ağ ekipmanındaki düğümler arasında dengesizdir. Elbette ağ donanımı paketlerin içeriğini ayrıştırmaz ve bu nedenle hakkında hiçbir şey bilmediği ölçümlerden bahsetmeye bile gerek yok, saniyede 4 milyon paketten çok daha fazlasını çekebilir. Her pakette metriklerin teker teker gelmediğini hesaba katarsak burada herhangi bir performans sorunu öngörmüyoruz. Bir sunucu çökerse, ağ cihazı bu durumu hızlı bir şekilde (1-2 saniye içinde) algılar ve çöken sunucuyu rotasyondan kaldırır. Bunun bir sonucu olarak, pasif (yani lider olmayan) düğümler, grafiklerdeki dezavantajlar fark edilmeden pratik olarak açılıp kapatılabilir. Kaybedeceğimiz maksimum miktar, son saniyede gelen ölçümlerin bir kısmıdır. Bir liderin ani kaybı/kapanması/değişi yine de küçük bir anormallik yaratacaktır (30 saniyelik aralık hala senkronize değildir), ancak düğümler arasında iletişim varsa, bu sorunlar örneğin senkronizasyon paketleri gönderilerek en aza indirilebilir. .

İç yapı hakkında biraz. Uygulama elbette çok iş parçacıklıdır, ancak iş parçacığı mimarisi brubeck'te kullanılandan farklıdır. Brubeck'teki iş parçacıkları aynıdır; her biri hem bilgi toplamadan hem de toplamadan sorumludur. Bioyino'da çalışanlar iki gruba ayrılıyor: ağdan sorumlu olanlar ve toplamadan sorumlu olanlar. Bu bölüm, metrik türüne bağlı olarak uygulamayı daha esnek bir şekilde yönetmenize olanak tanır: yoğun toplamanın gerekli olduğu yerlerde toplayıcılar ekleyebilirsiniz; çok fazla ağ trafiğinin olduğu yerlerde, ağ akışlarının sayısını ekleyebilirsiniz. Şu anda sunucularımızda 8 ağ ve 4 toplama akışında çalışıyoruz.

Sayma (toplamadan sorumlu) kısmı oldukça sıkıcıdır. Ağ akışları tarafından doldurulan arabellekler, daha sonra ayrıştırılıp toplanacakları sayım akışları arasında dağıtılır. Talep edilmesi halinde diğer düğümlere gönderilmek üzere metrikler verilmektedir. Düğümler arasında veri göndermek ve Consul ile çalışmak da dahil olmak üzere tüm bunlar, çerçeve üzerinde çalışarak eşzamansız olarak gerçekleştirilir. tokio.

Geliştirme sırasındaki sorunların çoğu, metriklerin alınmasından sorumlu olan ağ kısmından kaynaklanıyordu. Ağ akışlarını ayrı varlıklara ayırmanın temel amacı, akışın harcadığı zamanı azaltma arzusuydu hayır Soketten veri okumak için. Eşzamansız UDP ve normal recvmsg kullanan seçenekler hızla ortadan kalktı: ilki, olay işleme için çok fazla kullanıcı alanı CPU tüketiyor, ikincisi ise çok fazla bağlam anahtarı gerektiriyor. Bu nedenle artık kullanılıyor recvmmsg büyük tamponlarla (ve tamponlar, beyler memurlar, sizin için hiçbir şey değil!). Normal UDP desteği, recvmmsg'nin gerekli olmadığı hafif durumlar için ayrılmıştır. Çoklu mesaj modunda ana şeyi başarmak mümkündür: çoğu zaman ağ iş parçacığı işletim sistemi kuyruğunu tarar - verileri soketten okur ve kullanıcı alanı arabelleğine aktarır, yalnızca ara sıra doldurulmuş arabelleği kullanıcıya vermeye geçer. toplayıcılar. Soketteki kuyruk pratikte birikmiyor, bırakılan paketlerin sayısı pratikte artmıyor.

Dikkat

Varsayılan ayarlarda arabellek boyutu oldukça büyük olacak şekilde ayarlanmıştır. Aniden sunucuyu kendiniz denemeye karar verirseniz, az sayıda ölçüm gönderdikten sonra Grafit'e ulaşmayacakları ve ağ akış arabelleğinde kalacakları gerçeğiyle karşılaşabilirsiniz. Az sayıda metrikle çalışmak için yapılandırmada bufsize ve görev kuyruğu boyutunu daha küçük değerlere ayarlamanız gerekir.

Son olarak grafik severler için bazı grafikler.

Her sunucu için gelen metriklerin sayısına ilişkin istatistikler: 2 milyondan fazla MPS.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Düğümlerden birinin devre dışı bırakılması ve gelen ölçümlerin yeniden dağıtılması.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Giden ölçümlere ilişkin istatistikler: her zaman yalnızca bir düğüm gönderir - baskın patronu.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Çeşitli sistem modüllerindeki hataları dikkate alarak her düğümün çalışma istatistikleri.

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Gelen metriklerin ayrıntılandırılması (metrik adları gizlidir).

Bioyino - dağıtılmış, ölçeklenebilir ölçüm toplayıcı

Bütün bunlarla bundan sonra ne yapmayı planlıyoruz? Tabii ki kod yaz, kahretsin...! Projenin başlangıçta açık kaynak olması planlanmıştı ve ömrü boyunca da öyle kalacak. Acil planlarımız arasında kendi Raft sürümümüze geçmek, eş protokolü daha taşınabilir bir protokolle değiştirmek, ek dahili istatistikler, yeni ölçüm türleri, hata düzeltmeleri ve diğer iyileştirmeler sunmak yer alıyor.

Elbette herkes projenin geliştirilmesine yardımcı olabilir: Halkla İlişkiler, Sorunlar oluşturun, mümkünse yanıt vereceğiz, iyileştireceğiz, vb.

Bununla birlikte, hepsi bu kadar millet, fillerimizi satın alın!



Kaynak: habr.com

Yorum ekle