RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik

В son makale Hata toleransı ve yüksek kullanılabilirlik açısından RabbitMQ kümelemesine baktık. Şimdi Apache Kafka'nın derinliklerine inelim.

Burada çoğaltma birimi bölümdür. Her konunun bir veya daha fazla bölümü vardır. Her bölümün takipçisi olan veya olmayan bir lideri vardır. Konu oluştururken bölüm sayısını ve çoğaltma katsayısını belirtirsiniz. Genel değer 3'tür, bu da üç kopya anlamına gelir: bir lider ve iki takipçi.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 1. Dört bölüm üç broker arasında dağıtılmıştır.

Tüm okuma ve yazma istekleri lidere gider. Takipçiler periyodik olarak lidere en son mesajları almak için istek gönderir. Tüketiciler asla takipçilere başvurmaz; takipçiler yalnızca fazlalık ve hata toleransı için vardır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik

Bölüm hatası

Bir komisyoncu başarısız olduğunda, çeşitli bölümlerin liderleri sıklıkla başarısız olur. Her birinde başka bir düğümden gelen bir takipçi lider olur. Aslında, senkronizasyon faktörü aynı zamanda şunları da etkilediğinden, durum her zaman böyle değildir: senkronize takipçilerin olup olmadığı ve değilse, senkronize edilmemiş bir kopyaya geçişe izin verilip verilmediği. Ama şimdilik işleri karmaşıklaştırmayalım.

Broker 3 ağdan ayrılır ve broker 2'de bölüm 2 için yeni bir lider seçilir.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 2. Komisyoncu 3 ölür ve komisyoncu 2'deki takipçisi bölüm 2'nin yeni lideri olarak seçilir

Daha sonra komisyoncu 1 ayrılır ve bölüm 1 de rolü komisyoncu 2'ye geçen liderini kaybeder.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 3. Bir komisyoncu kaldı. Tüm liderler sıfır yedeklilik ile tek bir komisyoncudadır

Broker 1 tekrar çevrimiçi olduğunda, dört takipçi ekleyerek her bölüme bir miktar yedeklilik sağlar. Ancak tüm liderler hala komisyoncu 2'de kaldı.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 4. Liderler komisyoncu 2'de kalır

Aracı 3 ortaya çıktığında bölüm başına üç kopyaya geri döneriz. Ancak tüm liderler hala komisyoncu 2'de.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 5. Broker 1 ve 3'ün restorasyonundan sonra liderlerin dengesiz yerleştirilmesi

Kafka'nın RabbitMQ'dan daha iyi bir lider yeniden dengeleme aracı var. Burada, geçiş sırasındaki fazlalığı azaltarak ana düğümün geçişine ilişkin politikaları değiştiren bir üçüncü taraf eklentisi veya komut dosyası kullanmanız gerekiyordu. Ayrıca büyük kuyruklar için senkronizasyon sırasında kullanılamamayı kabul etmek zorunda kaldık.

Kafka'nın lider rolü için "tercih edilen kopyalar" kavramı vardır. Konu bölümleri oluşturulduğunda Kafka, liderleri düğümler arasında eşit olarak dağıtmaya çalışır ve bu ilk liderleri tercih edilen olarak işaretler. Zamanla, sunucunun yeniden başlatılması, arızalar ve bağlantı kesintileri nedeniyle liderler, yukarıda açıklanan en uç durumda olduğu gibi, kendilerini diğer düğümlerde bulabilirler.

Bunu düzeltmek için Kafka iki seçenek sunuyor:

  • Seçenek auto.leader.rebalance.enable=true denetleyici düğümünün liderleri tercih edilen kopyalara otomatik olarak yeniden atamasına ve böylece tekdüze dağıtımı geri yüklemesine olanak tanır.
  • Yönetici betiği çalıştırabilir kafka-tercih edilen-kopya-election.sh manuel yeniden atama için.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 6. Yeniden dengeleme sonrasında kopyalar

Bu, başarısızlığın basitleştirilmiş bir versiyonuydu, ancak burada çok karmaşık bir şey olmamasına rağmen gerçek daha karmaşıktır. Her şey senkronize kopyalara (Senkronize Edilmiş Kopyalar, ISR) bağlıdır.

Senkronize Kopyalar (ISR)

ISR, "senkronize" (senkronize) olarak kabul edilen bir bölümün kopyaları kümesidir. Bir lider var ama takipçileri olmayabilir. Bir takipçi, aralık sona ermeden önce liderin tüm mesajlarının tam kopyalarını almışsa senkronize edilmiş sayılır. replika.lag.time.max.ms.

Bir takipçi şu durumlarda ISR setinden çıkarılır:

  • aralık için seçim yapma talebinde bulunmadı replika.lag.time.max.ms (ölü olduğu varsayılıyor)
  • aralık boyunca güncellemeyi başaramadım replika.lag.time.max.ms (yavaş sayılır)

Takipçiler aralıkta örnekleme talebinde bulunur replika.fetch.wait.max.ms, varsayılan olarak 500ms'dir.

ISR'nin amacını net bir şekilde anlatabilmek için üreticiden gelen onaylara ve bazı başarısızlık senaryolarına bakmamız gerekiyor. Yapımcılar komisyoncunun ne zaman onay göndereceğini seçebilir:

  • acks=0, onay gönderilmiyor
  • acks=1, lider yerel günlüğüne bir mesaj yazdıktan sonra onay gönderilir
  • acks=all, ISR'deki tüm kopyalar mesajı yerel günlüklere yazdıktan sonra onay gönderilir

Kafka terminolojisinde ISR bir mesajı kaydettiyse bu “taahhüt edilir”. Acks=all en güvenli seçenektir ancak aynı zamanda ek gecikme ekler. İki başarısızlık örneğine ve farklı 'acks' seçeneklerinin ISR konseptiyle nasıl etkileşime girdiğine bakalım.

Acks=1 ve ISR

Bu örnekte, eğer lider tüm takipçilerden gelen her mesajın kaydedilmesini beklemiyorsa, liderin başarısız olması durumunda veri kaybının mümkün olduğunu göreceğiz. Senkronize edilmemiş bir takipçiye gitmek, ayarlanarak etkinleştirilebilir veya devre dışı bırakılabilir kirli.lider.seçim.etkin.

Bu örnekte üreticinin değeri acks=1'dir. Bu bölüm her üç komisyoncuya dağıtılmıştır. Broker 3 geride, sekiz saniye önce liderle senkronize oldu ve şu anda 7456 mesaj geride. Broker 1 yalnızca bir saniye gerideydi. Üreticimiz bir mesaj gönderir ve liderin beklemediği yavaş veya ölü takipçilerin yükü olmadan hızlı bir şekilde yanıt alır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 7. Üç kopyalı ISR

Broker 2 başarısız olur ve yapımcı bir bağlantı hatası alır. Liderlik komisyoncu 1'e geçtikten sonra 123 mesajı kaybederiz. Broker 1'deki takipçi ISR'nin bir parçasıydı ancak düştüğünde liderle tam olarak senkronize değildi.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 8. Kilitlendiğinde mesajlar kayboluyor

Yapılandırmada bootstrap.sunucuları Üreticinin listede yer alan birden fazla komisyoncusu vardır ve yeni bölüm liderinin kim olduğunu başka bir komisyoncuya sorabilir. Daha sonra aracı 1 ile bağlantı kurar ve mesaj göndermeye devam eder.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 9. Mesaj göndermeye kısa bir aradan sonra devam edilir

Broker 3 daha da geride. Getirme isteklerinde bulunuyor ancak senkronize edemiyor. Bunun nedeni aracılar arasındaki ağ bağlantısının yavaş olması, depolama sorunu vb. olabilir. ISR'den kaldırılır. Artık ISR tek bir kopyadan oluşuyor - lider! Üretici mesaj göndermeye ve onay almaya devam ediyor.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 10. Broker 3'ün takipçisi ISR'den kaldırılır

Broker 1 düşer ve 3 mesajın kaybıyla liderlik rolü broker 15286'e geçer! Üretici bir bağlantı hatası mesajı alır. ISR dışında bir lidere geçiş ancak ortam nedeniyle mümkün oldu kirli.leader.election.enable=true. Eğer yüklüyse yanlış, bu durumda geçiş gerçekleşmeyecek ve tüm okuma ve yazma istekleri reddedilecektir. Bu durumda, komisyoncu 1'in kopyadaki sağlam verileriyle geri dönmesini bekleriz, bu da liderliği tekrar devralır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 11. Broker 1 düşüyor. Bir arıza meydana geldiğinde çok sayıda mesaj kaybolur

Yapımcı son komisyoncuyla bağlantı kurar ve artık bölümün lideri olduğunu görür. Broker 3'e mesaj göndermeye başlar.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 12. Kısa bir aradan sonra tekrar 0. bölüme mesajlar gönderilir.

Üreticinin yeni bağlantılar kurmak ve yeni lider arayışına yönelik kısa kesintiler dışında sürekli mesaj gönderdiğini gördük. Bu yapılandırma, tutarlılık (veri güvenliği) pahasına kullanılabilirliği sağlar. Kafka binlerce iletiyi kaybetti ancak yeni yazmaları kabul etmeye devam etti.

Acks=hepsi ve ISR

Bu senaryoyu bir kez daha tekrarlayalım, ancak acks=tümü. Broker 3'ün ortalama gecikme süresi dört saniyedir. Üretici şunu içeren bir mesaj gönderir: acks=tümüve şu anda hızlı bir yanıt alamıyor. Lider, mesajın ISR'deki tüm kopyalar tarafından kaydedilmesini bekler.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 13. Üç kopyalı ISR. Biri yavaş, bu da kayıtta gecikmelere neden oluyor

Dört saniyelik ek gecikmeden sonra komisyoncu 2 bir onay gönderir. Tüm kopyalar artık tamamen güncellendi.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 14. Tüm kopyalar mesajları kaydeder ve onay gönderir

Broker 3 artık daha da geride kalıyor ve ISR'den çıkarılıyor. ISR'de yavaş kopya kalmadığından gecikme önemli ölçüde azalır. Aracı 2 artık yalnızca aracı 1'i bekliyor ve ortalama 500 ms'lik bir gecikmeye sahip.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 15. Aracı 3'teki kopya ISR'den kaldırılır

Daha sonra komisyoncu 2 düşer ve liderlik mesaj kaybı olmadan komisyoncu 1'e geçer.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 16. Komisyoncu 2 düşüyor

Üretici yeni bir lider bulur ve ona mesajlar göndermeye başlar. ISR artık tek bir kopyadan oluştuğu için gecikme daha da azaldı! Bu nedenle seçenek acks=tümü fazlalık eklemez.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 17. Aracı 1'deki kopya, mesajları kaybetmeden liderliği ele geçirir

Daha sonra komisyoncu 1 çöküyor ve 3 mesaj kaybıyla lider komisyoncu 14238'e gidiyor!

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 18. Broker 1 ölür ve kirli ayarlarla liderlik geçişi, kapsamlı veri kaybına neden olur

Seçeneği yükleyemedik kirli.lider.seçim.etkin anlam içine gerçek. Varsayılan olarak eşittir yanlış. Ayarlar acks=tümü с kirli.leader.election.enable=true bazı ek veri güvenliğiyle erişilebilirlik sağlar. Ancak gördüğünüz gibi yine de mesajları kaybedebiliriz.

Peki ya veri güvenliğini artırmak istiyorsak? Koyabilirsin kirli.leader.election.enable = yanlış, ancak bu bizi veri kaybından mutlaka korumayacaktır. Lider sert bir şekilde düştüyse ve verileri de yanına aldıysa, mesajlar yine de kaybolur ve ayrıca yönetici durumu geri yükleyene kadar kullanılabilirlik kaybolur.

Tüm mesajların gereksiz olduğundan emin olmak, aksi halde kaydı iptal etmek daha iyidir. Bu durumda, en azından komisyoncunun bakış açısından, veri kaybı yalnızca iki veya daha fazla eşzamanlı arıza durumunda mümkündür.

Acks=tümü, min.insync.replicas ve ISR

Konu yapılandırması ile min.insync.replikalar Veri güvenliği düzeyini artırıyoruz. Önceki senaryonun son kısmını tekrar gözden geçirelim, ancak bu sefer min.insync.replicas=2.

Yani aracı 2'nin bir kopya lideri vardır ve aracı 3'teki takipçi ISR'den kaldırılır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 19. İki kopyadan ISR

Broker 2 düşer ve liderlik mesaj kaybı olmadan broker 1'e geçer. Ancak artık ISR yalnızca tek bir kopyadan oluşuyor. Bu, kayıtları almak için gereken minimum sayıyı karşılamıyor ve bu nedenle aracı, yazma girişimine bir hatayla yanıt veriyor Yeterli DeğilKopyalar.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 20. ISR sayısı min.insync.replicas'ta belirtilenden bir düşük

Bu yapılandırma tutarlılık adına kullanılabilirlikten ödün verir. Bir mesajı kabul etmeden önce en az iki kopyaya yazıldığından emin oluyoruz. Bu, üreticiye çok daha fazla güven verir. Burada mesaj kaybı yalnızca, mesaj ek bir takipçiye kopyalanana kadar kısa bir aralıkta iki kopyanın aynı anda başarısız olması durumunda mümkündür ki bu pek olası değildir. Ama aşırı paranoyaksanız kopyalama faktörünü 5'e ayarlayabilirsiniz. min.insync.replikalar 3'e kadar. Burada rekoru kaybetmek için üç komisyoncunun aynı anda düşmesi gerekiyor! Elbette bu güvenilirliğin bedelini ek gecikmeyle ödersiniz.

Veri güvenliği için erişilebilirliğin gerekli olduğu durumlarda

Gibi RabbitMQ'lu durumBazen veri güvenliği için erişilebilirlik gereklidir. İşte düşünmeniz gerekenler:

  • Yayıncı bir hata döndürüp yukarı akış hizmetinin veya kullanıcının daha sonra tekrar denemesini sağlayabilir mi?
  • Yayıncı daha sonra tekrar denemek üzere mesajı yerel olarak veya bir veritabanına kaydedebilir mi?

Cevap hayırsa kullanılabilirliğin optimize edilmesi veri güvenliğini artırır. Kayıt yapmamak yerine kullanılabilirliği seçerseniz daha az veri kaybedersiniz. Dolayısıyla her şey bir denge bulmaya bağlıdır ve karar belirli duruma bağlıdır.

ISR'nin anlamı

ISR paketi, veri güvenliği ile gecikme arasındaki en uygun dengeyi seçmenize olanak tanır. Örneğin, replikaların çoğunluğunun arızalanması durumunda kullanılabilirliği sağlayarak ölü veya yavaş replikaların gecikme açısından etkisini en aza indirin.

Anlamını kendimiz seçiyoruz replika.lag.time.max.ms ihtiyaçlarınıza göre. Temel olarak bu parametre, ne kadar gecikmeyi kabul etmeye hazır olduğumuz anlamına gelir. acks=tümü. Varsayılan değer on saniyedir. Bu süre size çok uzun geliyorsa azaltabilirsiniz. Daha sonra takipçiler daha sık kaldırılıp ekleneceği için ISR'deki değişikliklerin sıklığı artacaktır.

RabbitMQ, kopyalanması gereken bir dizi aynadan ibarettir. Yavaş aynalar ek gecikmeye neden olur ve ölü aynalar, her düğümün kullanılabilirliğini (net onay işareti) kontrol eden paketlerin yanıt vermesini bekleyebilir. ISR, bu gecikme sorunlarından kaçınmanın ilginç bir yoludur. Ancak ISR yalnızca lidere küçülebileceğinden fazlalığı kaybetme riskiyle karşı karşıyayız. Bu riski önlemek için ayarı kullanın min.insync.replikalar.

İstemci bağlantı garantisi

Ayarlarında bootstrap.sunucuları Üretici ve tüketici, istemcileri birbirine bağlamak için birden fazla aracı belirleyebilir. Buradaki fikir, bir düğüm çöktüğünde, müşterinin bağlantı açabileceği birkaç yedek düğümün kalmasıdır. Bunlar mutlaka bölüm liderleri değildir, yalnızca ilk yükleme için bir sıçrama tahtasıdır. İstemci onlara okuma/yazma bölümü liderini hangi düğümün barındırdığını sorabilir.

RabbitMQ'da istemciler herhangi bir düğüme bağlanabilir ve dahili yönlendirme, isteği gitmesi gereken yere gönderir. Bu, RabbitMQ'nun önüne bir yük dengeleyici kurabileceğiniz anlamına gelir. Kafka, istemcilerin ilgili bölüm liderini barındıran düğüme bağlanmasını gerektirir. Böyle bir durumda yük dengeleyici kuramazsınız. Liste bootstrap.sunucuları Bir arızanın ardından istemcilerin doğru düğümlere erişebilmesi ve bu düğümleri bulabilmesi kritik öneme sahiptir.

Kafka Uzlaşı Mimarisi

Şu ana kadar kümenin brokerin düşüşünü nasıl öğrendiğini ve yeni liderin nasıl seçildiğini düşünmedik. Kafka'nın ağ bölümleriyle nasıl çalıştığını anlamak için öncelikle konsensüs mimarisini anlamanız gerekir.

Her Kafka kümesi, sistemin kullanılabilirlik yerine tutarlılığa öncelik vererek belirli bir durum üzerinde fikir birliğine varmasını sağlayan dağıtılmış bir fikir birliği hizmeti olan Zookeeper kümesiyle birlikte dağıtılır. Okuma ve yazma işlemlerini onaylamak için Zookeeper düğümlerinin çoğunluğunun onayı gerekir.

Zookeeper kümenin durumunu saklar:

  • Konuların, bölümlerin, yapılandırmanın, mevcut lider kopyaların, tercih edilen kopyaların listesi.
  • Küme üyeleri. Her komisyoncu Zookeeper kümesine ping gönderir. Belirli bir süre içinde ping almazsa Zookeeper aracıyı kullanılamaz olarak kaydeder.
  • Denetleyici için ana ve yedek düğümlerin seçilmesi.

Denetleyici düğümü, kopya liderlerini seçmekten sorumlu olan Kafka aracılarından biridir. Zookeeper, denetleyiciye küme üyeliği ve konu değişiklikleri hakkında bildirimler gönderir ve denetleyicinin bu değişikliklere göre hareket etmesi gerekir.

Örneğin, on bölümlü ve çoğaltma faktörü 3 olan yeni bir konuyu ele alalım. Denetleyicinin, liderleri aracılar arasında en iyi şekilde dağıtmaya çalışarak her bölüm için bir lider seçmesi gerekir.

Her bölüm denetleyicisi için:

  • Zookeeper'daki ISR ​​ve lider hakkındaki bilgileri günceller;
  • Bu bölümün bir kopyasını barındıran her aracıya bir LeaderAndISRCommand göndererek aracıları ISR ve lider hakkında bilgilendirir.

Lideri olan bir komisyoncu düştüğünde Zookeeper kontrolöre bir bildirim gönderir ve yeni bir lider seçer. Yine kontrolör önce Zookeeper'ı günceller ve ardından her komisyoncuya liderlik değişikliğini bildiren bir komut gönderir.

Her lider ISR'leri işe almaktan sorumludur. Ayarlar replika.lag.time.max.ms oraya kimin gireceğini belirler. ISR değiştiğinde lider yeni bilgileri Zookeeper'a iletir.

Zookeeper her zaman herhangi bir değişiklikten haberdar edilir, böylece bir başarısızlık durumunda yönetim sorunsuz bir şekilde yeni bir lidere geçebilir.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 21. Kafka Uzlaşısı

Çoğaltma protokolü

Çoğaltma ayrıntılarını anlamak, olası veri kaybı senaryolarını daha iyi anlamanıza yardımcı olur.

Örnekleme sorguları, Günlük Sonu Uzaklığı (LEO) ve Yüksek Su İşareti (HW)

Takipçilerin periyodik olarak lidere getirme isteği gönderdiğini düşündük. Varsayılan aralık 500 ms'dir. Bu, RabbitMQ'dan farklıdır, çünkü RabbitMQ'da çoğaltma kuyruk aynası tarafından değil ana bilgisayar tarafından başlatılır. Usta değişiklikleri aynalara aktarır.

Lider ve tüm takipçiler Log End Offset (LEO) ve Highwater (HW) etiketini kaydeder. LEO işareti, son mesajın ofsetini yerel kopyada saklar ve HW, son işlemin ofsetini tutar. Taahhüt durumu için mesajın tüm ISR kopyalarında kalıcı olması gerektiğini unutmayın. Bu, LEO'nun genellikle HW'nin biraz ilerisinde olduğu anlamına gelir.

Lider bir mesaj aldığında onu yerel olarak saklar. Takipçi LEO'sunu ileterek bir getirme isteğinde bulunur. Lider daha sonra bu LEO'dan başlayarak bir dizi mesaj gönderir ve aynı zamanda mevcut HW'yi de iletir. Lider, tüm kopyaların mesajı verilen ofset seviyesinde sakladığına dair bilgi aldığında HW işaretini hareket ettirir. Yalnızca lider HW'yi hareket ettirebilir ve böylece tüm takipçiler, isteklerine verilen yanıtlardaki mevcut değeri bilecek. Bu, takipçilerin hem mesaj hem de donanım bilgisinde liderin gerisinde kalabileceği anlamına gelir. Tüketiciler yalnızca mevcut donanıma kadar mesaj alırlar.

"Devamlı" ifadesinin diske değil belleğe yazıldığı anlamına geldiğini unutmayın. Performans için Kafka, belirli bir aralıkta diske senkronizasyon yapar. RabbitMQ'nun da böyle bir aralığı var ama yayıncıya ancak master ve tüm aynalar mesajı diske yazdıktan sonra bir onay gönderecek. Kafka geliştiricileri, performans nedeniyle, mesaj belleğe yazılır yazılmaz bir onay göndermeye karar verdiler. Kafka, artıklığın, onaylanmış mesajların yalnızca hafızada kısa süreliğine saklanması riskini ortadan kaldırdığına bahse girer.

Lider başarısızlığı

Bir lider düştüğünde Zookeeper denetleyiciyi bilgilendirir ve yeni bir lider kopyası seçer. Yeni lider, LEO'suna göre yeni bir HW işareti belirler. Takipçiler daha sonra yeni lider hakkında bilgi alırlar. Kafka'nın versiyonuna bağlı olarak takipçi iki senaryodan birini seçecektir:

  1. Yerel günlüğü bilinen bir HW'ye kesecek ve bu işaretten sonra yeni lidere mesajlar için bir istek gönderecektir.
  2. Lidere, lider seçildiği andaki HW'yi bulması için bir istek gönderecek ve ardından günlüğü bu ofsete kısaltacaktır. Daha sonra bu ofsetten başlayarak periyodik getirme istekleri yapmaya başlayacaktır.

Bir takipçinin aşağıdaki nedenlerden dolayı günlüğü kısaltması gerekebilir:

  • Bir lider başarısız olduğunda, Zookeeper'a kayıtlı ISR setindeki ilk takipçi seçimi kazanır ve lider olur. ISR'deki tüm takipçiler, "senkronize" olarak değerlendirilse de, eski liderden gelen tüm mesajların kopyalarını almamış olabilir. Öne çıkan takipçinin en güncel kopyaya sahip olmaması tamamen mümkündür. Kafka kopyalar arasında hiçbir farklılık olmamasını sağlar. Bu nedenle, tutarsızlıkları önlemek için her takipçinin günlüğünü yeni liderin seçildiği andaki HW değerine göre kesmesi gerekir. Bu, ayarın başka bir nedenidir acks=tümü tutarlılık açısından çok önemlidir.
  • Mesajlar periyodik olarak diske yazılır. Tüm küme düğümleri aynı anda arızalanırsa farklı konumlara sahip kopyalar disklerde depolanır. Brokerlar tekrar çevrimiçi olduklarında, seçilen yeni liderin diğerlerinden önce diske kaydedildiği için takipçilerinin arkasında olması mümkündür.

Kümeyle yeniden birleşme

Kümeye yeniden katılırken kopyalar, bir liderin başarısız olması durumunda yaptığının aynısını yapar: liderin kopyasını kontrol ederler ve günlüklerini donanımlarına (seçim sırasında) göre kısaltırlar. Karşılaştırıldığında, RabbitMQ yeniden birleştirilmiş düğümlere eşit şekilde tamamen yeniymiş gibi davranır. Her iki durumda da aracı, mevcut herhangi bir durumu atar. Otomatik senkronizasyon kullanılırsa, ana yöneticinin mevcut içeriğin tamamını "tüm dünya beklesin" yöntemiyle yeni aynaya kesinlikle kopyalaması gerekir. Master bu işlem sırasında herhangi bir okuma veya yazma işlemini kabul etmez. Bu yaklaşım büyük kuyruklarda sorun yaratmaktadır.

Kafka dağıtılmış bir günlüktür ve genel olarak verilerin okunduktan sonra kuyruktan kaldırıldığı RabbitMQ kuyruğundan daha fazla mesaj depolar. Aktif kuyruklar nispeten küçük kalmalıdır. Ancak Kafka, günlerce veya haftalarca süre belirleyebilen, kendi saklama politikasına sahip bir günlüktür. Dağıtılmış bir günlük için kuyruk engelleme ve tam senkronizasyon yaklaşımı kesinlikle kabul edilemez. Bunun yerine, Kafka takipçileri, eğer kopyaları liderin önündeyse, günlüklerini liderin HW'sine (seçim sırasında) kısaltırlar. Daha muhtemel durumda, takipçi geride kaldığında mevcut LEO'sundan başlayarak getirme istekleri yapmaya başlar.

Yeni veya yeniden katılan takipçiler ISR'nin dışında başlar ve taahhütlere katılmazlar. Sadece grupla birlikte çalışırlar, lidere yetişip ISR'ye girene kadar mesajları olabildiğince hızlı alırlar. Kilitlenmenize gerek yok ve tüm verilerinizi atmanıza gerek yok.

Bağlantı kaybı

Kafka, RabbitMQ'dan daha fazla bileşene sahiptir, dolayısıyla küme bağlantısı kesildiğinde daha karmaşık davranışlara sahip olur. Ancak Kafka başlangıçta kümeler için tasarlandığından çözümler çok iyi düşünülmüş.

Aşağıda çeşitli bağlantı hatası senaryoları verilmiştir:

  • Senaryo 1: Takipçi lideri görmüyor ama yine de Hayvanat Bahçesi Bekçisini görüyor.
  • Senaryo 2: Lider herhangi bir takipçi görmüyor ancak yine de Zookeeper'ı görüyor.
  • Senaryo 3: Takipçi lideri görüyor ancak Hayvanat Bahçesi Bekçisini görmüyor.
  • Senaryo 4: Lider takipçileri görüyor ancak Hayvanat Bahçesi Bekçisini görmüyor.
  • Senaryo 5: Follower, diğer Kafka düğümlerinden ve Zookeeper'dan tamamen ayrıdır.
  • Senaryo 6: Lider, diğer Kafka düğümlerinden ve Zookeeper'dan tamamen ayrıdır.
  • Senaryo 7: Kafka denetleyici düğümü başka bir Kafka düğümünü göremiyor.
  • Senaryo 8: Kafka denetleyicisi Zookeeper'ı görmüyor.

Her senaryonun kendi davranışı vardır.

Senaryo 1: Takipçi lideri görmüyor ancak yine de Zookeeper'ı görüyor

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 22. Senaryo 1: Üç kopyanın ISR'si

Bağlantı hatası, aracı 3'ü aracı 1 ve 2'den ayırır, ancak Zookeeper'dan ayırmaz. Broker 3 artık getirme isteği gönderemez. Zaman geçtikten sonra replika.lag.time.max.ms ISR'den kaldırılır ve mesaj taahhütlerine katılmaz. Bağlantı yeniden kurulduğunda, getirme isteklerini sürdürecek ve lidere yetiştiğinde ISR'ye katılacaktır. Zookeeper ping almaya devam edecek ve komisyoncunun hayatta ve iyi durumda olduğunu varsayacaktır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 23. Senaryo 1: ISR'den replika.lag.time.max.ms aralığı içerisinde herhangi bir getirme isteği alınmazsa aracı ISR'den kaldırılır.

RabbitMQ'daki gibi bölünmüş beyin veya düğüm süspansiyonu yoktur. Bunun yerine artıklık azalır.

Senaryo 2: Lider herhangi bir takipçi görmüyor ancak yine de Zookeeper'ı görüyor

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 24. Senaryo 2. Lider ve iki takipçi

Ağ bağlantısındaki bir kesinti, lideri takipçilerden ayırıyor ancak komisyoncu hala Zookeeper'ı görebiliyor. İlk senaryoda olduğu gibi ISR ​​küçülür, ancak bu sefer tüm takipçiler getirme isteği göndermeyi bıraktığından yalnızca lidere gider. Yine mantıksal bir ayrım yoktur. Bunun yerine, bağlantı yeniden sağlanana kadar yeni mesajlar için artıklık kaybı yaşanır. Zookeeper ping almaya devam ediyor ve komisyoncunun hayatta ve iyi durumda olduğuna inanıyor.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 25. Senaryo 2. ISR yalnızca lidere küçüldü

Senaryo 3. Takipçi lideri görüyor ancak Hayvanat Bahçesi Bekçisini görmüyor

Takipçi Zookeeper'dan ayrılır ancak liderle komisyoncudan ayrılmaz. Sonuç olarak takipçi, getirme talebinde bulunmaya ve ISR'ye üye olmaya devam ediyor. Zookeeper artık ping almıyor ve bir komisyoncunun çökmesini kaydetmiyor, ancak yalnızca bir takipçi olduğu için iyileşme sonrasında herhangi bir sonuç yok.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 26. Senaryo 3: Takipçi, lidere getirme istekleri göndermeye devam ediyor

Senaryo 4. Lider takipçileri görüyor ancak Zookeeper'ı görmüyor

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 27. Senaryo 4. Lider ve iki takipçi

Lider, Zookeeper'dan ayrıdır ancak takipçileri olan komisyonculardan ayrı değildir.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 28. Senaryo 4: Lider Zookeeper'dan izole edildi

Bir süre sonra Zookeeper bir aracı hatası kaydedecek ve denetleyiciyi bu konuda bilgilendirecektir. Takipçileri arasından yeni bir lider seçecek. Ancak asıl lider, kendisinin lider olduğunu düşünmeye devam edecek ve gelen girdileri kabul etmeye devam edecektir. acks=1. Takipçiler artık ona getirme istekleri göndermiyor, bu yüzden onların ölü olduğunu düşünecek ve ISR'yi kendine küçültmeye çalışacak. Ancak Zookeeper ile bağlantısı olmadığı için bunu yapamayacak ve bu noktada başka girişleri kabul etmeyi reddedecektir.

Сообщения acks=tümü ISR ilk önce tüm kopyaları açtığından ve iletiler onlara ulaşmadığından bir onay almayacaktır. Orijinal lider onları ISR'den çıkarmaya çalıştığında bunu başaramayacak ve hiçbir mesajı kabul etmeyi bırakacaktır.

İstemciler kısa sürede liderdeki değişikliği fark eder ve kayıtları yeni sunucuya göndermeye başlar. Ağ geri yüklendiğinde, orijinal lider artık bir lider olmadığını görür ve günlük farklılığını önlemek için günlüğünü yeni liderin başarısızlık anında sahip olduğu HW değerine kısaltır. Daha sonra yeni lidere getirme istekleri göndermeye başlayacaktır. Orijinal liderin yeni lidere kopyalanmayan tüm kayıtları kaybolur. Yani, iki liderin çalıştığı birkaç saniye içinde orijinal lider tarafından kabul edilmeyen mesajlar kaybolacaktır.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 29. Senaryo 4. Broker 1'in lideri, ağ geri yüklendikten sonra takipçi olur

Senaryo 5: Takipçi hem diğer Kafka düğümlerinden hem de Zookeeper'dan tamamen ayrıdır

Takipçi hem diğer Kafka düğümlerinden hem de Zookeeper'dan tamamen izole edilmiştir. Ağ yeniden sağlanana kadar kendisini ISR'den uzaklaştırır ve ardından diğerlerine yetişir.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 30. Senaryo 5: Yalıtılmış takipçi ISR'den kaldırılır

Senaryo 6: Lider, diğer Kafka düğümlerinden ve Zookeeper'dan tamamen ayrıdır

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 31. Senaryo 6. Lider ve iki takipçi

Lider, takipçilerinden, kontrolörden ve hayvanat bahçesi bekçisinden tamamen izole edilmiştir. Kısa bir süre için girişleri kabul etmeye devam edecektir. acks=1.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 32. Senaryo 6: Lideri diğer Kafka ve Zookeeper düğümlerinden ayırma

Süre dolduktan sonra istek almamış olmak replika.lag.time.max.msISR'yi kendine küçültmeye çalışacak, ancak Zookeeper ile iletişim olmadığı için bunu yapamayacak, ardından yazma kabul etmeyi bırakacaktır.

Bu arada Zookeeper, izole edilmiş komisyoncuyu ölü olarak işaretleyecek ve kontrolör yeni bir lider seçecek.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 33. Senaryo 6. İki lider

Orijinal lider, girişleri birkaç saniyeliğine kabul edebilir, ancak daha sonra herhangi bir mesajı kabul etmeyi bırakır. İstemciler her 60 saniyede bir en son meta verilerle güncellenir. Lider değişikliği konusunda bilgilendirilecekler ve yeni lidere girişler göndermeye başlayacaklar.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 34. Senaryo 6: Üreticiler yeni bir lidere geçiş yapıyor

Bağlantı kaybından bu yana orijinal lider tarafından yapılan onaylanmış tüm girişler kaybolacak. Ağ yeniden kurulduğunda orijinal lider, Zookeeper aracılığıyla artık lider olmadığını keşfedecektir. Daha sonra seçim anında logunu yeni liderin HW'sine kesecek ve takipçi olarak istek göndermeye başlayacak.

RabbitMQ vs Kafka: Hata Toleransı ve Yüksek Erişilebilirlik
Pirinç. 35. Senaryo 6: Orijinal lider, ağ bağlantısı yeniden sağlandıktan sonra takipçi haline gelir

Bu durumda mantıksal ayrılma kısa bir süre için meydana gelebilir, ancak yalnızca acks=1 и min.insync.replikalar ayrıca 1. Mantıksal ayırma, ağ geri yüklendikten sonra, orijinal lider artık lider olmadığını fark ettiğinde veya tüm müşteriler liderin değiştiğini fark edip yeni lidere yazmaya başladığında (hangisi önce gerçekleşirse) otomatik olarak sona erer. Her durumda, bazı mesajlar kaybolacaktır, ancak yalnızca acks=1.

Bu senaryonun, ağ bölünmeden hemen önce takipçilerin geride kaldığı ve liderin ISR'yi yalnızca kendisine sıkıştırdığı başka bir çeşidi daha vardır. Daha sonra bağlantı kaybı nedeniyle izole hale gelir. Yeni bir lider seçilir, ancak asıl lider, girişleri kabul etmeye devam eder. acks=tümüçünkü ISR'de ondan başka kimse yok. Ağ geri yüklendiğinde bu kayıtlar kaybolacaktır. Bu seçenekten kaçınmanın tek yolu min.insync.replicas = 2.

Senaryo 7: Kafka Denetleyici Düğümü Başka Bir Kafka Düğümünü Göremiyor

Genel olarak Kafka düğümüyle bağlantı kesildiğinde denetleyici ona herhangi bir lider değişikliği bilgisi iletemeyecektir. En kötü durumda, bu, senaryo 6'da olduğu gibi kısa vadeli mantıksal bir ayrılığa yol açacaktır. Çoğunlukla, ikincisi başarısız olursa, komisyoncu liderlik adayı olmayacaktır.

Senaryo 8: Kafka denetleyicisi Zookeeper'ı görmüyor

Zookeeper, düşen denetleyiciden ping almayacak ve denetleyici olarak yeni bir Kafka düğümü seçecektir. Orijinal denetleyici kendisini bu şekilde göstermeye devam edebilir ancak Zookeeper'dan bildirim almaz, dolayısıyla gerçekleştirmesi gereken herhangi bir görevi olmayacaktır. Ağ yeniden kurulduğunda artık bir denetleyici olmadığını, sıradan bir Kafka düğümü haline geldiğini anlayacaktır.

Senaryolardan çıkan sonuçlar

Takipçi bağlantısının kaybının mesaj kaybıyla sonuçlanmadığını, yalnızca ağ yeniden kurulana kadar yedekliliği geçici olarak azalttığını görüyoruz. Bu elbette bir veya daha fazla düğümün kaybolması durumunda veri kaybına yol açabilir.

Lider, bağlantı kaybı nedeniyle Zookeeper'dan ayrılırsa, bu durum mesajların kaybolmasına neden olabilir. acks=1. Zookeeper ile iletişim eksikliği, iki lider arasında kısa bir mantıksal ayrılığa neden olur. Bu sorun parametre ile çözülür. acks=tümü.

Parametre min.insync.replikalar iki veya daha fazla kopyaya bölünmesi, bu tür kısa vadeli senaryoların Senaryo 6'daki gibi mesajların kaybolmasıyla sonuçlanmayacağına dair ek güvence sağlar.

Kayıp Mesajların Özeti

Kafka'da veri kaybetmenin tüm yollarını listeleyelim:

  • İletiler kullanılarak onaylanırsa herhangi bir lider hatası acks=1
  • Liderliğin, yani ISR ​​dışındaki bir takipçiye kirli olmayan herhangi bir geçişi, acks=tümü
  • İletiler kullanılarak onaylanırsa lideri Zookeeper'dan ayırmak acks=1
  • ISR grubunu zaten kendi içine sıkıştırmış olan liderin tamamen izolasyonu. Hatta tüm mesajlar kaybolacak acks=tümü. Bu yalnızca eğer doğrudur min.insync.replicas=1.
  • Tüm bölüm düğümlerinde eşzamanlı arızalar. Mesajlar bellekten onaylandığı için bazıları henüz diske yazılmamış olabilir. Sunucuları yeniden başlattıktan sonra bazı mesajlar eksik olabilir.

Saf olmayan liderlik geçişleri ya yasaklanarak ya da en az iki işten çıkarma sağlanarak önlenebilir. En dayanıklı konfigürasyon bir kombinasyondur acks=tümü и min.insync.replikalar daha 1.

RabbitMQ ve Kafka'nın güvenilirliğinin doğrudan karşılaştırılması

Güvenilirliği ve yüksek kullanılabilirliği sağlamak için her iki platform da birincil ve ikincil çoğaltma sistemi uygular. Ancak RabbitMQ'nun Aşil topuğu var. Bir arızadan sonra yeniden bağlanırken düğümler verilerini atar ve senkronizasyon engellenir. Bu çifte sorun, RabbitMQ'daki büyük kuyrukların uzun ömürlülüğünü sorguluyor. Ya azaltılmış yedekliliği ya da uzun engelleme sürelerini kabul etmeniz gerekecektir. Artıklığın azaltılması büyük miktarda veri kaybı riskini artırır. Ancak kuyruklar küçükse, yedeklilik adına, tekrarlanan bağlantı denemeleri kullanılarak kısa süreli (birkaç saniye) kullanılamama sorununun üstesinden gelinebilir.

Kafka'nın bu sorunu yok. Yalnızca lider ile takipçi arasındaki farklılık noktasındaki verileri atar. Paylaşılan tüm veriler kaydedilir. Ayrıca replikasyon sistemi engellemez. Yeni takipçi yetişirken lider gönderileri kabul etmeye devam eder, bu nedenle devop'lar için kümeye katılmak veya yeniden katılmak önemsiz bir görev haline gelir. Elbette çoğaltma sırasında hala ağ bant genişliği gibi sorunlar var. Aynı anda birden fazla takipçi eklerseniz bant genişliği sınırıyla karşılaşabilirsiniz.

RabbitMQ, bir kümedeki birden fazla sunucunun aynı anda arızalanması durumunda güvenilirlik açısından Kafka'dan üstündür. Daha önce de söylediğimiz gibi RabbitMQ, ancak mesajın master ve tüm aynalar tarafından diske yazılmasından sonra yayıncıya bir onay gönderir. Ancak bu, iki nedenden dolayı ek gecikme süresi ekler:

  • her birkaç yüz milisaniyede bir fsync
  • Aynanın arızası ancak her düğümün kullanılabilirliğini (net onay) kontrol eden paketlerin ömrü sona erdikten sonra fark edilebilir. Ayna yavaşlarsa veya düşerse bu bir gecikmeye neden olur.

Kafka'nın iddiası şu: Eğer bir mesaj birden fazla düğümde saklanıyorsa, mesajları belleğe ulaşır ulaşmaz kabul edebilir. Bu nedenle, her türden mesajın (hatta acks=tümü, min.insync.replicas=2) eşzamanlı arıza durumunda.

Genel olarak Kafka daha iyi bir yazılım performansı sergiliyor ve sıfırdan kümeler için tasarlandı. Güvenilirlik açısından gerekirse takipçi sayısı 11'e kadar çıkarılabilir. Çoğaltma faktörü 5 ve senkronizasyondaki minimum kopya sayısı min.insync.replicas=3 mesaj kaybını çok nadir görülen bir olay haline getirecek. Altyapınız bu çoğaltma oranını ve artıklık düzeyini destekleyebiliyorsa bu seçeneği tercih edebilirsiniz.

RabbitMQ kümelemesi küçük kuyruklar için iyidir. Ancak yoğun trafik olduğunda küçük kuyruklar bile hızla büyüyebilir. Kuyruklar büyüdüğünde, kullanılabilirlik ve güvenilirlik arasında zor seçimler yapmak zorunda kalacaksınız. RabbitMQ kümelemesi, RabbitMQ'nun esnekliğinin faydalarının kümelemenin dezavantajlarından daha ağır bastığı tipik olmayan durumlar için en uygunudur.

RabbitMQ'nun büyük kuyruklara karşı savunmasızlığının panzehiri, onları daha küçük kuyruklara bölmektir. Tüm kuyruğun tam olarak sıralanmasını istemiyorsanız, yalnızca ilgili mesajların (örneğin, belirli bir müşteriden gelen mesajlar) veya hiçbir şeyin sipariş edilmesini istemiyorsanız, bu seçenek kabul edilebilir: projeme bak Yeniden dengeleyici kuyruğu bölmek için (proje hala erken aşamada).

Son olarak hem RabbitMQ hem de Kafka'nın kümeleme ve çoğaltma mekanizmalarındaki bazı hataları unutmayın. Zamanla sistemler daha olgun ve istikrarlı hale geldi, ancak hiçbir mesaj kaybolmaya karşı %100 güvenli olamayacak! Ayrıca veri merkezlerinde büyük çaplı kazalar yaşanıyor!

Bir şeyi kaçırırsam, bir hata yaptıysam veya herhangi bir noktaya katılmıyorsanız, yorum yazmaktan veya benimle iletişime geçmekten çekinmeyin.

Bana sık sık şu soru soruluyor: “Neyi seçmeliyim, Kafka mı yoksa RabbitMQ mu?”, “Hangi platform daha iyi?”. Gerçek şu ki, bu gerçekten sizin durumunuza, mevcut deneyiminize vb. bağlıdır. Fikrimi vermekten çekiniyorum çünkü tüm kullanım durumları ve olası sınırlamalar için tek bir platform önermek aşırı basitleştirme olacaktır. Bu yazı dizisini kendi fikrinizi oluşturabilmeniz için yazdım.

Her iki sistemin de bu alanda lider olduğunu söylemek istiyorum. Biraz önyargılı olabilirim çünkü projelerdeki deneyimlerime dayanarak, garantili mesaj sıralaması ve güvenilirlik gibi şeylere değer verme eğilimindeyim.

Bu güvenirlikten ve garantili siparişten yoksun başka teknolojiler görüyorum, sonra RabbitMQ ve Kafka'ya bakıyorum ve bu iki sistemin inanılmaz değerinin farkına varıyorum.

Kaynak: habr.com

Yorum ekle