Diversity w polskim IT
Timothy Downs
Timothy Downs

Nowość: strumienie w Redisie

Strumienie w Redisie mogą się stać doskonałą alternatywą dla Kafki.
5.01.20184 min
Nowość: strumienie w Redisie

Wyobraź sobie coś takiego: mamy bardzo długą książkę i chcemy, żeby wielu ludzi ją przeczytało. Jedni mogą czytać w przerwie na lunch, inni w poniedziałek wieczorem, jeszcze inni wolą wziąć książkę do domu na weekend. Książka jest tak długa, że w dowolnym momencie czytają ją setki osób.


Każda z tych osób chce wiedzieć, jak daleko doszła, więc zaznacza to miejsce zakładką. Niektórzy czytają bardzo powoli, ich zakładki są blisko początku. Inni rezygnują w połowie, zostawiają zakładki gdzieś w środku i nigdy nie wracają do lektury.

Co więcej, codziennie dodajemy do tej książki nowe strony. Nasza książka wypełnia się zakładkami, robi się coraz grubsza, cięższa, aż w końcu nie da się jej czytać.

Ale pewnego dnia jakiś cwaniak stwierdził, że czytelnicy nie powinni wkładać zakładek do książki. Zamiast tego mają zapisać sobie numer strony, na której skończyli.

Tak powstał Apache Kafka, i jest to bardzo wytrzymała konstrukcja. Czytelnicy to nie zawsze odpowiedzialni obywatele i zdarza się, że po sobie nie posprzątają. A ta książka to na przykład dziennik wszystkich ważnych wydarzeń, które dzieją się w naszej firmie.

Jest jedna popularna alternatywa: system kolejki zapisuje, dokąd dotarli czytelnicy - to oznacza, że trzeba przypisać pamięć każdemu czytelnikowi. Źle wychowani czytelnicy mogą za każdym razem żądać nowej sesji kolejki, a to może spowodować przeciążenie usługi kolejki. To zwykle nienajlepsze rozwiązanie, bo chcemy, żeby wszyscy czytali sobie swobodnie bez ryzyka przeciążenia kolejki.

Apache Kafka


Kafka jest zaprojektowana wokół strumienia zdarzeń takich jak:

1001. ‘tim’ has purchased travel deal ‘fiji’ 
1002. ‘tim’ has updated his subscription preference to ‘daily’
1003. ‘sam’ has logged in using ‘iphone’
1004. ‘sam’ has opened travel deal ‘bali’
1005. ‘sam’ has logged in using ‘desktop web’
1006. ‘sam’ has purchased deal ‘bali’

Czytelnicy zdarzeń w strumieniu śledzą ID do którego doszli, co oznacza, że serwer zdarzeń nie musi ich śledzić. To umożliwia serwerowi zdarzeń Kafki utrzymać przewidywalne wykorzystanie pamięci nawet, jeśli mamy wielu niewychowanych czytelników.

Kafka jest super, po co nam strumienie Redis?


Kafka to dobry wybór do przechowywania strumienia zdarzeń, i jest zaprojektowana z myślą o wysokiej skali. Ale żeby taką skalę osiągnąć, wprowadza dodatkową złożoność. Żeby dobrze ustawić i zarządzać Kafką, trzeba rozumieć pewne złożone pojęcia. W przypadku mniejszych projektów lepszy będzie mniejszy i prostszy system. Wszyscy lubimy rozwiązywać problemy skali Google'a, ale niezbyt często mamy z takimi do czynienia ;)

Do prostej, zwykle niepersystentnej bazy danych najczęściej wybieram Redis. Ma bardzo dobre wsparcie, biblioteki we wszystkich popularnych językach programowania i większość developerów dobrze go rozumie. To doskonały przykład, w którym wytrzymały, rozproszony system zamieniamy na coś prostego. Redis obsługuje teraz prostszą wersję koncepcji strumieni Kafki, dzięki czemu architektura jest tania i łatwo dostępna dla każdego.

Aby rozpocząć pracę ze strumieniami w Redisie, przedstawię dwie nowe komendy, które są teraz w “niestabilnej” gałęzi Redisa. By przećwiczyć to, co napisałem w poniższym przykładzie, możesz stworzyć instancję Redisa online tutaj w jakieś 2 minuty. Możesz też wyciągnąć “niestabilną” gałąź Redisa stąd.

Pisanie do strumienia w Redisie

XADD stream_name * key1 value1 key2 value2 (etc)

XADD pozwala nam napisać strumień zdarzeń. Stwórzmy strumień zdarzeń odpowiadający powyższemu przykładowi. Możemy nazwać nasz strumień “events”'.


XADD events * user tim action purchase item travel:fiji

XADD events * user tim action preferences subscription daily

XADD events * user sam action login platform iPhone

XADD events * user sam action visit item travel:bali

XADD events * user sam action login platform “desktop web”

XADD events * user sam action purchase item travel:bali


Znak "*" jest używany do oddzielania parametrów opcjonalnych od zestawu wartości klucza.

To zapisze wszystkie te działania w strumieniu "events".

Czytanie ze strumienia w Redisie

XREAD COUNT 2 STREAMS events item-id

XREAD pozwala nam czytać elementy z tej kolejki. Odczytajmy dwa elementy na raz:


demo.wiftycloud.com:6379> XREAD COUNT 2 STREAMS events 0
1) 1) “events”
   2) 1) 1) 1512991598699–0
         2) 1) “user”
            2) “tim”
            3) “action”
            4) “purchase”
            5) “item”
            6) “travel:fiji”
      2) 1) 1512991602438–0
         2) 1) “user”
            2) “tim”
            3) “action”
            4) “preferences”
            5) “subscription”
            6) “daily”


Pobieramy elementy w strumieniu “events”, zaczynając od początku listy (pomijając “0”). Pobraliśmy tylko 2 elementy. Aby uzyskać kolejne dwa, zamiast zaczynać od “0”, teraz zaczynamy od ostatniego ID zwróconego przez Redis — w powyższym przykładzie to “1512991602438 – 0”.


> XREAD COUNT 2 streams events 1512991602438–0
1) 1) “events”
   2) 1) 1) 1512991605766-0
         2) 1) “user”
            2) “sam”
            3) “action”
            4) “logon”
            5) “platform”
            6) “iPhone”
      2) 1) 1512991617871-0
         2) 1) “user”
            2) “sam”
            3) “action”
            4) “visit”
            5) “item”
            6) “travel:bali”


Są dostępne inne opcje — BLOCK pozwala na to, żeby serwer Redis czekał na łączu aż będą dostępne kolejne zdarzenia.

Dzięki tym dwu komendom, XADD i XREAD możemy bardzo łatwo skonstruować kolejkę zdarzeń biznesowych.

Przykład Node.js


Jeśli chodzi o biblioteki, wsparcie dla strumieni nadal nie jest całkiem gotowe, ale można używać poleceń niestandardowych. Przykład, w którym zrobiono to za pomocą ioredis znajdziesz tutaj.

TL; DR

Kafka jest super, a strumienie w Redisie mogą się stać doskonałą alternatywą LoFi dla Kafki do zarządzania strumieniami zdarzeń.


--------------
Artykuł na blogu Timothy'ego znajdziecie tutaj.

<p>Loading...</p>