Cześć.
Za nami ogrom wiedzy podzielonej na osiem wpisów. Dzisiejszy, dziewiąty, dotyczyć będzie pewnej bardzo przydatnej funkcjonalności Redisa. Pokaże jak skonfigurować i używać notyfikacja. Standardowo, jak w każdym poprzednim artykule, tak i w tym będę opierał się na wiedzy która już została przeze opublikowana. Zachęcam więc do zapoznania się z poprzednimi wpisami:
Notyfikacje to powiadomienia które wysyła Redis (via publish na konkretnym kanale) generowane w momencie pracy na innych kluczach. Brzmi zawile, więc może przykład: możemy tak skonfigurować Redisa by ten robił publish na pewny kanał z informacją o np. usunięciu jakiegoś klucza. Albo z dodaniem elementu do listy. Albo z dodaniem elementu do strumienia. Możliwości jest dużo, zbyt dużo by pokazać każdą z nich w tym wpisie, więc jest on bardziej przysłowiową wędką niż rybą.
Subskrybować możemy się na kanały których nazwy wyglądają tak:
1 2 | __keyspace@0__:mykey __keyevent@0__:del |
pierwszy, zwany „key-space notification” po subskrypcji pozwoli na odbieranie wiadomości na temat konkretnego klucza (w przykładzie mykey). Drugi, zwany „key-event notification” będzie dostarczał informacje dla podanego typu operacji (w przykładzie dla del). Nie trudno się domyśleć że jeśli usuniemy klucz o nazwie „mykey” to na pierwszym kanale dostaniemy wiadomość o treści „del” a na drugim „mykey”.
Notyfikacje można włączyć na dwa sposoby. Jeden z nich jest trwały, tj ustawienie jest respektowane nawet po restarcie Redisa a drugi pozwala na konfigurację ulotną. Oczywiście tę drugą można zapisać i tym samym sprawić, że zostanie zapamiętana. Skonfigurowanie powiadomień sprowadza się do wyboru konkretnych literek z tych które odpowiadają za efekt jaki chcemy uzyskać:
1 2 3 4 5 6 7 8 9 10 11 12 13 | K Keyspace events, published with __keyspace@<db>__ prefix. E Keyevent events, published with __keyevent@<db>__ prefix. g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... $ String commands l List commands s Set commands h Hash commands z Sorted set commands t Stream commands x Expired events (events generated every time a key expires) e Evicted events (events generated when a key is evicted for maxmemory) m Key miss events (events generated when a key that doesn't exist is accessed) A Alias for "g$lshztxe", so that the "AKE" string means all the events except "m". |
a wiec dla przykładu, jeśli chcemy aby Redis publikował na kanałach typu key-space informacje o komendach dotyczących list to konfiguracją będzie „Kl”. Jeśli chcemy by nie tylko o listach informował a o stringach też, to konfiguracją będzie „Kl$”. Przyznać muszę, że jest to słabo czytelne, ale idzie się przyzwyczaić.
Włączyć notyfikację można poprzez:
1 | redis-cli config set notify-keyspace-events K$ |
co sprawi, że Redis zacznie wysyłać notyfikację zgodnie ze wskazanym ustawieniem. Utrwalenie można osiągnąć wykonując polecenie:
1 | redis-cli config rewrite |
które po prostu zapisuje aktualną konfigurację do pliku redis.conf w którym również manualnie można zmienić ilość pożądanych notyfikacji.
Stwórzmy program który będzie nasłuchiwał na każdą zmianę klucza wynikającą z komend dedykowanych stringowi:
1 2 3 4 5 6 7 8 9 10 11 | from redis import Redis redis_connection = Redis(decode_responses=True, db=0) redis_connection.config_set('notify-keyspace-events', 'K$') pub_sub = redis_connection.pubsub() pub_sub.subscribe('__keyspace@0__:test_key') for message in pub_sub.listen(): print(message) |
uruchom program i wykonaj z poziomu redis-cli komendę:
1 2 | 127.0.0.1:6379> set test_key 15 OK |
która momentalnie sprawi, że program wypisze:
1 | {'type': 'message', 'pattern': None, 'channel': '__keyspace@0__:test_key', 'data': 'set'} |
wykonaj teraz w redis-cli:
1 2 | 127.0.0.1:6379> append test_key 11 (integer) 4 |
a program zareaaguje nowym powiadomieniem:
1 | {'type': 'message', 'pattern': None, 'channel': '__keyspace@0__:test_key', 'data': 'append'} |
teraz usuń klucz i wykonaj:
1 2 | 127.0.0.1:6379> LPUSH test_key 1 (integer) 1 |
program na to nie zareagował. Wynika to wprost z konfiguracji, która pozwala na publikowanie tylko zdarzeń wygenerowanych w wyniku użycia komend dedykowanych stringom.
Jeśli uruchomisz taki program:
1 2 3 4 5 6 7 8 9 10 11 | from redis import Redis redis_connection = Redis(decode_responses=True, db=0) redis_connection.config_set('notify-keyspace-events', 'E$') pub_sub = redis_connection.pubsub() pub_sub.subscribe('__keyevent@0__:set') for message in pub_sub.listen(): print(message) |
to dostaniesz powiadomienia o każdym użyciu komendy SET a jako wiadomość przyjdzie nazwa klucza, na której komenda się wykonała, np.:
1 | {'type': 'message', 'pattern': None, 'channel': '__keyevent@0__:set', 'data': 'test_key'} |
To o czym należy pamiętać, to o tym że Redis pcha powiadomienia przez mechanizm kanałów pub-sub, co ma swoje zalety i wady. Ale nie ma sensu by je powtarzać – jeden z poprzednich artykułów jest poświęcony właśnie temu mechanizmowi. Ciekawostką jest, że te powiadomienia kiedyś bardzo pomogły mi, w takim trybie „turbo-hot-fix”, uszczelnić pewien proces. Ustawienie klucza jednoznacznie określało że powinna się po nim zadziać pewna akcja. Akcja z wyniku błędu nie zawsze się wykonywała a notyfikacje pomogły mi ekspresowo złapać ten moment i obsłużyć niefortunne przypadki. Tak czy siak, warto wiedzieć że takie sztuczki istnieją.
Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More
Cześć! Zapraszam na krótkie podsumowanie kwietnia. Wyjazd do Niemiec A dokładniej pod granicę z Francją. Chrześnica miała pierwszą komunię. Po… Read More
Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More
Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More