Mateusz Mazurek – programista z pasją

Python, architektura, ciekawostki ze świata IT

Programowanie Programowanie webowe

Redis i Python – dobrze dobrana para #9

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:
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 :)
Postaw mi kawę na buycoffee.to

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

A może wolisz nowości na mail?

Subskrybuj
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

2 komentarzy
Inline Feedbacks
View all comments