Redis i Python – dobrze dobrana para #9

Cześć! Cieszę się, że mnie odwiedziłeś/aś. Zanim przejdziesz do artykułu chciałbym zwrocić Ci uwagę na to, że ten artykuł był pisany kilka lat temu (2020-12-14) miej więc proszę na uwadzę że rozwiązania i przemyślenia które tu znajdziesz nie muszą być aktualne. Niemniej jednak zachęcam do przeczytania.

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:

Czy są notyfikacje redisowe?

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ą.

Kanały

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”.

Konfiguracja

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.


Czekaj, stop!

Podoba Ci się to co tworzę? Jeśli tak to zapraszam Cię do zapisania się na newsletter:

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)
a w ramach prezentu otrzymasz całkowicie za darmo, dwa dokumenty PDF „6 (nie zawsze oczywistych) błędów popełnianych podczas nauki programowania” który jest jednym z efektów ponad siedmioletniej pracy i obserwacji rozwoju niejednego programisty oraz „Wstęp do testowania w Pythonie”, będący wprowadzeniem do biblioteki PyTest.
Jeśli to Cię interesuje to zapraszam również na swoje social media.

Jak i do ewentualnego postawienia mi kawy :)

Przykład

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'}

Kończąc

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ą.

Dzięki za wizytę,
Mateusz Mazurek
Mateusz M.

Ostatnie wpisy

Python 1.0 vs. 3.13: Co się zmieniło?

Cześć. Dziś luźny artykuł, bo dziś pobawimy się jedną z pierwszy wersji Pythona. Skompilujemy go i zobaczymy co tam w… Read More

10 miesięcy ago

Podsumowanie: styczeń i luty 2025

Nowy rok czas zacząć! Więc lećmy z podsumowaniem. Nowy artykuł Nie uwierzycie, ale pojawił się na blogu nowy artykuł! Piszę… Read More

10 miesięcy ago

Just-in-time compiler (JIT) w Pythonie

Cześć! W Pythonie 3.13 dodano JITa! JIT, czyli just-in-time compiler to optymalizacja na która Python naprawdę długo czekał. Na nasze… Read More

11 miesięcy ago

Podsumowanie roku 2024

Cześć! Zapraszam na podsumowanie roku 2024. Książki W sumie rok 2024 był pod względem ilości książek nieco podobny do roku… Read More

11 miesięcy ago

Podsumowanie: wrzesień, październik, listopad i grudzień 2024

Podtrzymując tradycję, prawie regularnych podsumowań, zapraszam na wpis! Nie mogło obyć się bez Karkonoszy We wrześniu odwiedziłem z kolegą Karkonosze,… Read More

11 miesięcy ago

Podsumowanie: maj, czerwiec, lipiec i sierpień 2024

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

1 rok ago