Redis üzerinden bir mesaj kuyruğu nasıl uygulanır?


29

Neden kuyrukta Redis?

Redis'in kuyruk sistemini uygulamak için iyi bir aday olabileceği izlenimini edindim. Bu noktaya kadar MySQL veritabanımızı sorgulama ya da RabbitMQ ile kullanıyorduk. RabbitMQ ile birçok sorun yaşadık - istemci kitaplıkları çok zayıf ve sorunlu ve bunları düzeltmek için çok fazla geliştirici saat harcamak istemiyoruz, sunucu yönetim konsolu ile birkaç sorun, vb. en azından, milisaniyeyi kavramıyoruz veya performansı ciddi şekilde zorluyoruz, bu nedenle bir sistem zekayı akıllıca destekleyen bir mimariye sahip olduğu sürece muhtemelen iyi durumdayız.

Tamam, öyleyse arka plan bu. Temel olarak çok klasik, basit bir kuyruk modelim var - iş üreten birkaç üretici ve iş yapan birkaç tüketici ve hem üreticilerin hem de tüketicilerin akıllıca ölçeklendirilmeleri gerekir. Bir saflığın PUBSUBişe yaramadığı ortaya çıktı , çünkü tüm abonelerin iş tüketmesini istemiyorum, sadece bir abonenin işi almasını istiyorum . İlk geçişte bana BRPOPLPUSHakıllı bir tasarım gibi geldi.

BRPOPLPUSH kullanabilir miyiz?

Temel tasarım BRPOPLPUSH, bir iş sıranız ve bir ilerleme sıranız olması. Bir tüketici iş aldığında, ürünü atomik olarak ilerleme kuyruğuna doğru iter ve işi tamamladığında o LREMolur. Bu, eğer müşteriler ölürse ve izlemeyi oldukça zahmetsiz hale getirirse, çalışmanın karartılmasını önler - örneğin, çok sayıda işin olup olmadığını söylemenin yanı sıra, tüketicilerin işleri yapmak için uzun zaman almalarına neden olan bir sorun olup olmadığını söyleyebiliriz.

Sağlar

  • iş tam bir tüketiciye ulaştırılıyor
  • iş, ilerleme kuyruğundaki rüzgârlara bürünür, bu nedenle tüketici olursa kara delik açamaz

Sakıncaları

  • PUBSUBRedis'i sıraya sokmakla ilgili çoğu blog yazısının odaklandığı konu bu gibi görünüyor çünkü buldum en iyi tasarımın aslında kullanmıyor olması bana çok garip geliyor. Bu yüzden bariz bir şeyi kaçırdığımı hissediyorum. PUBSUBGörevleri iki kere tüketmeden kullanmamın tek yolu , işin geldiğine dair bir bildirimde bulunmaktır; bu da tüketicilerin daha sonra engellemeyebilecekleri bir bildirimdir RPOPLPUSH.
  • Bir seferde birden fazla iş öğesi istemek imkansız, bu bir performans sorunu gibi görünüyor. Durumumuz için çok büyük bir şey değil, ancak açıkça görülüyor ki bu operasyon yüksek verimlilik veya bu durum için tasarlanmadı
  • Kısacası: Aptalca bir şey eksik mi?

Ayrıca node.js etiketini de ekliyorum çünkü en çok uğraştığım dil bu. Düğüm, tek iş parçacıklı ve bloksuz doğası göz önüne alındığında, uygulamada bazı basitleştirmeler sunabilir, ancak dahası, düğüm redis kitaplığını kullanıyorum ve çözümler de güçlü ve zayıf yönlerine karşı hassas olmalı veya hassas olmalıdır.

Yanıtlar:


5

Redis'i Node.js'deki bir mesaj kuyruğu için kullanmak istiyorsanız ve bunun için bir modül kullanmayı düşünmüyorsanız , RSMQ - Düğüm için Redis Basit İleti Kuyruğu'nu deneyebilirsiniz . Bu soru sorulduğu sırada mevcut değildi, ancak bugün uygulanabilir bir seçenek.

Eğer sorgunuzda belirtildiği gibi kuyruğu gerçekten kendiniz uygulamak istiyorsanız, tam olarak istediğinizi yapan sadece 20 ekran kodu olduğu için RSMQ kaynağını okumak isteyebilirsiniz.

Görmek:


Bunu daha sonra gerçekten kusurlu veya kırılmış bir şey olduğunu öğrenmezsem kabul edeceğim.
djechlin

22

Şimdiye dek bazı zorluklarla karşılaştım burada belgelemek istiyorum.

Yeniden bağlanma mantığını nasıl ele alıyorsunuz?

Bu bir mesaj kuyruğu tasarlama ve uygulamada zor bir problem ve özellikle de zor bir sorundur. Mesajlar, tüketiciler çevrimdışıyken bir yerde sıraya girebilmelidir, bu nedenle basit bir pub-sub yeterince güçlü değildir ve tüketicilerin bir dinleme durumunda yeniden bağlanması gerekir. Pop'ları engellemek, sürdürülmesi zor olan bir durumdur; çünkü onlar, iddiasız bir dinleme durumu değildir . Dinleme iddiasız bir işlem olmalıdır, ancak engelleyici bir pop ile ilgili bir bağlantı kesilmesiyle uğraşırken, işlemin başarılı olmasından hemen sonra mı yoksa işlemin başarısızlığından hemen önce mi olduğunu kesmek konusunda çok zor düşünme zevkine sahip olursunuz. Bu aşılmaz bir şey değil ama istenmiyor.

Ayrıca, dinleme işlemi mümkün olduğu kadar basit olmalıdır . İdeal olarak, bu özelliklere sahip olması gerekir:

  • Dinlemek boşuna.
  • Tüketici daima dinliyor ve azaltma mantığı, dinleme mantığı kodunun dışında işleniyor. RabbitMQ, tüketicinin sahip olabileceği paketlenmemiş mesajların sayısını sınırlandırmasını sağlayarak bunu kapsar.
    Özellikle, engelleyici bir pop'a tekrar girmenin önceki operasyonların başarısına bağlı olduğu ve zorlu ve kırılgan olması gereken zayıf bir tasarıma sahip oldum.

Şimdi Redis PUBSUB + RPOPLPUSH çözümünü tercih ediyorum. Bu, işin iş tüketiminden haberdar edilmesini sağlar ve bu da temiz bir dinleme çözümünü ortaya çıkarmamızı sağlar. PUBSUB sadece iş bildirimlerinden sorumludur. RPOPLPUSH’in atomik doğası tüketimden ve işi tam olarak bir tüketiciye devretmekten sorumludur. İlk başta bu çözüm engelleyici bir pop ile karşılaştırıldığında gereksiz yere karmaşık görünüyordu, ama şimdi komplikasyonun hiç gereksiz olmadığını görüyorum; zor bir problem çözüyordu.

Ancak bu çözüm oldukça önemsiz değil:

  • Tüketiciler ayrıca yeniden bağlantı konusundaki çalışmaları kontrol etmelidir.
  • Tüketiciler zaten yeni işler için, artıklık için bir anket yapmak isteyebilirler. Eğer anket gerçekten başarılı olursa bir uyarı verilmelidir, çünkü bu sadece PUBSUB'taki tüketim ile bir RPOPLPUSH'deki anket arasında yapılmalıdır. Bu nedenle birçok anket başarısı, abonelik sisteminin kırıldığını gösteriyor.

PUBSUB / RPOPLPUSH tasarımının da ölçeklendirme sorunları olduğunu unutmayın. Her tüketici, her mesaj için hafif bir bildirim alır , bu da gereksiz bir tıkanıklık olduğu anlamına gelir. İşi engellemek için kanalları kullanmanın mümkün olduğundan şüpheliyim, ancak bu iyi bir şekilde çalışılması zor bir tasarım.


Müşterileri engellemeyle ilgili sorunu takip ettiğimden emin değilim. Bana öyle geliyor ki, tüketicilerin işlenmesi için herhangi bir iş yoksa, bir miktar oluncaya kadar engellemek gerekir, bununla birlikte, tüketicinin farklı bir hikaye olabilecek başka şeyler yapıp yapmadığını da varsayalım, ancak uygulamada bu bir sorun değil. ve sıra için çok değil? IE daha büyük bir uygulama içinde engelleyen bir iş parçacığı daha şık bir çözüm olmazdı, burada iş parçacığı daha sonra sıradan bir iş aldığında uygulamayı haberdar edebilirdi. Belki de komplikasyon yaratan sadece düğüm kullanımıdır.
AaronM 23

9
Geçen Ağustos ayından bu yana ne kadar geldiğini merak ediyorum. Sorunlarınızı memnuniyetinize göre çözebildiniz mi? Onları nasıl çözdün?
AaronM 23

3
AAA: Tıpkı @AaronM gibi, nasıl ilerlediğinizi duymak isterim.
bjornl

Kabul. Bu nasıl ilerledi? RabbitMQ'yu yığından çıkarma ve yine de orada bulunan Redis'i kullanma fikrini seviyorum. Benim sorunum, RSMQ (düğüm lib) kullanarak bir tüketiciyi nasıl kaydedeceğim.
ra9r

@raiglstorfer iki yıldır orada çalışmadı: P araştırma yapmaktan ve yayınlamaktan çekinmeyin ...
djechlin

0

Bu yüzden RedMis üzerinden RabbitMQ kullanmayı seçmenin en büyük nedeni başarısızlık senaryoları ve kümelenmedir.

Bu makale gerçekten en iyisini açıklıyor, bu yüzden sadece bağlantıyı vereceğim:

https://aphyr.com/posts/283-jepsen-redis

Redis sentinel ve daha yakın zamanda redis kümelemesi, sıra için kötü bir seçim haline getiren çok sayıda temel başarısızlık senaryosuyla başa çıkamamaktadır.

RabbitMQ'nun kendine özgü sorunları var, ancak üretimde inanılmaz derecede sağlam olduğu ve iyi bir mesaj sırası olduğu söyleniyor.

İşte tavşan için yazı:

https://aphyr.com/posts/315-jepsen-rabbitmq

CAP teorisine baktığınızda (tutarlılık, kullanılabilirlik ve bölüm işleme) yalnızca 3/2 seçebilirsiniz. Mesaj yükümüzle CP için RMQ'dan yararlanıyoruz (tutarlılık ve bölüm işleme). t dünyanın sonu. Mesaj kaybetmemek için, mesaj kaybetmemek için bölüm işleme için yoksay kullanıyoruz. Kaynak UUID'yi yönettiğinden beri kopyalar kullanılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.