Projektowanie skalowalnej architektury kolejki komunikatów

22

Niedawno zacząłem uczyć się niuansów skalowalnej i korporacyjnej architektury komputerowej, a jednym z głównych elementów jest kolejka przesyłania wiadomości. Aby jak najlepiej nauczyć się z dowolnego paradygmatu programowania, próbuję wdrożyć własną wersję usługi kolejki przesyłania wiadomości.

Do tej pory mój początkowy projekt działał na nasłuchiwaniu z wątkami, ale aby zapobiec dwukrotnemu pobieraniu tej samej wiadomości przez dwa osobne węzły przetwarzania, rejestr indeksu kolejek komunikatów jest blokowany po zainicjowaniu odczytu i odblokowywany po zarejestrowaniu rejestru zaktualizowane. W związku z tym eliminuje to potrzebę wątkowania i oznacza, że ​​istnieje pułap wielkości skalowalnego systemu w oparciu o szybkość przetwarzania serwera, na którym działa usługa kolejki przesyłania komunikatów.

Aby obejść ten problem, należy uruchomić usługę kolejki wiadomości na wielu serwerach, ale zwiększy to prawdopodobieństwo dwukrotnego pobrania tej samej wiadomości. Jedynym sposobem zapobiegania takim problemom byłoby włączenie wywołania zwrotnego odwołania, które (po tym, jak serwery, a nawet wątki na jednym serwerze zsynchronizują swoje informacje i wykryją taką ponowną emisję) nakazałby węzłowi przetwarzania, aby zatrzymał jego bieżące zadanie i ponownie przeprowadź zapytanie do kolejki komunikatów dla następnej wiadomości, ale znowu będzie pułap, w którym większość wysyłanego ruchu to synchronizacje i odwołania zwrotne, powodując wąskie gardło i spowalniające przetwarzanie informacji, tak że wiele węzłów przetwarzających wykonywałoby operacje zerowe i marnowało czas.

Ostatnim sposobem, w jaki mogę wymyślić obejście tego problemu, jest posiadanie każdego serwera kolejki komunikatów (i każdego wątku na każdym serwerze) z określonym przesunięciem co do miejsca, w którym szuka kolejki, ale może to mieć problemy na podstawie rodzaj aplikacji, szczególnie jeśli przetwarzanie musi być wykonane w określonej kolejności.

Tak więc czy to wszystko, czy są jakieś projekty architektury kolejek komunikatów, które mogłyby pokazać mi, w jaki sposób istniejące usługi kolejek wiadomości klasy korporacyjnej unikają tych problemów?

topherg
źródło
2
To ogromne pytanie. Gdybym był tobą, udałbym się na ibm.com i poszukał czerwonych książek, które opisują, co robi mq i (jeśli masz szczęście), jak to działa. Jasne, te książki nie dostarczą ci wszystkich odpowiedzi, ale dadzą wyobrażenie co do wielkości pytania. MQ jest niezwykle skomplikowane - pracowałem nad nim 15 lat temu.
PeteH
Inne architektury warte obejrzenia to Tibco Rendezvous ( tibco.com/products/automation/messaging/low-latency/rendezvous/… ), Apache ActiveMQ i Spread ( spread.org ).
Axel Kemper
1
Nie wymyślaj koła na nowo. ZeroMQ, RabbitMQ, Redis itp.
djechlin
1
@djechlin koło jest najbardziej wymyślonym przedmiotem wszechczasów. ZAWSZE może być okrągły, ale w tym przypadku nie próbuje go
wynaleźć
@cgoddard spróbuj zanurzyć się w kodzie bazującym na jednej z tych technologii.
djechlin

Odpowiedzi:

14

W skrócie:

To trudny problem. Nie wymyślaj koła na nowo.

Istnieje wiele technologii, które rozwiązują warstwę kolejki komunikatów. Zawierają

  • ZeroMQ
  • RabbitMQ
  • Apacz Kafka
  • Redis, z BLPOP lub PUBSUB (zapytałem, jak to zrobić tutaj ).
  • Inne implementacje AMQP oprócz RabbitMQ

Myślę, że omawianie wad każdego z nich jest poza zasięgiem, zwłaszcza dlatego, że tak naprawdę nie twierdzę, że potrafię dobrze kaszleć , nie używaj kaszlu Królika .

Nawet jeśli nie chcesz korzystać z żadnej z tych technologii, przeczytaj ich dokumentację.

To nauczy Cię wzorców projektowych, które są możliwe w jednym systemie. Czytanie dokumentacji ZeroMQ nauczy Cię wielu klasycznych architektur kolejkowania wiadomości, które z wdziękiem zaimplementowali. Nawet jeśli nie używasz ZeroMQ, znajomość tych wzorców pomoże ci ocenić inne technologie kolejkowania, pytając, czy możesz tam zaimplementować ten wzorzec.

Dowiedz się o modelu kolejki wymiany RabbitMQ / AMQP. Może pojawić się routing - jest obsługiwany przez Redis PUBSUB, ale nie pamiętam, aby był obsługiwany przez ZeroMQ - i fanouty są czymś, z czego korzystał mój sklep, chociaż słabo zaimplementowany w ankiecie Memcached (fuj!), Od dłuższego czasu .

Jak wybrać jeden?

Pracuję w startupie, którego umowa SLA jest typowa dla aplikacji internetowej - niektóre awarie są w porządku, o ile możemy szybko przywrócić usługę przy niewielkiej utracie danych. Nie musieliśmy myśleć o problemach ze skalowaniem, takich jak Twitter czy Tumblr, więc tak naprawdę nie musieliśmy myśleć o wolumenie przepustowości. Biorąc to pod uwagę, jeśli wdrażasz umowę SLA podobną do mojej, będą ci przychodzić na myśl następujące kwestie:

  • czy biblioteki klienckie faktycznie działają ? Czy łatwo jest utrzymać w nich połączenie? (ZeroMQ, Redis: tak. RabbitMQ: nie).
  • czy monitorowanie i zarządzanie są łatwe z poziomu konsoli serwera? (Redis: tak, RabbitMQ: tak, ZeroMQ: nie, że pamiętam, ale nie używaliśmy go tak długo)
  • czy klienci obsługują wewnętrzne kolejki, aby w krótkich przerwach nastąpiła niewielka utrata danych? (ZeroMQ, Redis: tak. RabbitMQ: nie.)

Oczywiście, jeśli pracujesz dla, powiedzmy, sklepu handlowego o wysokiej częstotliwości, będą to twoje mniejsze obawy. Bardziej chętnie poświęcisz czas programowania na bibliotekę po stronie klienta w zamian za większą przepustowość. Ale piszę to bardziej, aby ostrzec, że technologie te mają tendencję do wprowadzania na rynek ze względu na ich wydajność, a nie ich gotową funkcjonalność. Jeśli jesteś startup internetowy, jesteś daleko bardziej zainteresowani w tym ostatnim niż poprzednio, a zatem coś Redis, która jest bardziej zoptymalizowany pod kątem łatwości obsługi przy dobrej wydajności niż trudności użytku w doskonałej wydajności, to prawdopodobnie lepszy wybór niż RabbitMQ. (Naprawdę nie lubię RabbitMQ).

djechlin
źródło
8
Nie wymyślaj ponownie koła !!! ??? Gdyby Linus tak myślał, używałbyś teraz Windowsa. Wymyślił MINIX dla zabawy „ponieważ mu się nie podobało” i spójrz na to, co mamy teraz.
chrisapotek
9
@chrisapotek Linus zrozumiał wewnętrzne elementy systemu operacyjnego, zanim spróbował rozwiązać problem. OP na tym etapie rozwija swoje słownictwo. Różnica.
erbdex
2
@chrisapotek też chciał. Jeśli chcesz zbudować lepszą magistralę wiadomości, śmiało, ale prawdopodobnie nie chcesz tego robić, gdy próbujesz zbudować aplikację internetową lub cokolwiek innego. Polecam także posiadanie kwalifikacji. Osobiście nie mam uprawnień, aby wymyślać system operacyjny za każdym razem, gdy chcę pisać kod.
djechlin