Jeśli Redis jest jednowątkowy, po co w ogóle potrzebny mechanizm blokujący.
Redis jest rzeczywiście (w większości) jednowątkowy, ale blokowanie jest wymagane, gdy wielu klientów próbuje zrobić coś innego w sąsiednim sąsiedztwie czasowym. Blokowanie omawiane w RiA dotyczy właśnie tego – zapewnienia, że tylko jeden klient/wątek wykonuje określone zadanie lub upewnienia się, że aktualizacje nie pójdą nie tak.
Oto przykład, dlaczego potrzebujesz blokowania pomimo jednowątkowości Redis:załóżmy, że masz wartość w Redis, na przykład liczbę zapisaną pod kluczem o nazwie foo
. Kod Twojej aplikacji odczytuje ten numer (GET foo
), robi coś (np. dodaje 1) i odpisuje (SET
). Kiedy uruchamiasz swój kod w jednym wątku, wygląda to tak:
App Redis
|---- GET foo ---->|
|<------ 1 --------|
| |
| thinking... |
| |
|--- SET foo 2 --->|
|<----- OK --------|
Zobaczmy teraz, co się stanie, gdy spróbują to zrobić dwaj klienci aplikacji:
App 1 Redis App 2
|---- GET foo ---->| |
|<------ 1 --------|<--- GET foo -----|
| |------- 1 ------->|
| thinking... | |
| | thinking...|
|--- SET foo 2 --->| |
|<----- OK --------|<--- SET foo 2 ---|
| |------ OK ------->|
Tutaj możesz od razu zobaczyć, co się stało bez blokowania, mimo że serwer jest (w większości) jednowątkowy - zamiast 3, foo
wartość to 2. Gdy dodasz więcej wątków/klientów/aplikacji, sprawy mogą pójść wesoło i strasznie źle, gdy wielu autorów będzie próbowało modyfikować dane bez koordynacji (np. blokowania).
Optymistyczne blokowanie to tylko jeden ze sposobów na zrobienie tego, który Redis oferuje wbudowaną za pomocą WATCH
mechanizm. Czasami jednak optymizm - pomimo łatwego i radosnego charakteru - nie jest właściwym rozwiązaniem, więc będziesz musiał wdrożyć lepsze/zaawansowane/inne mechanizmy, aby zapobiec sytuacji wyścigowej. Takie blokady mogłyby prawdopodobnie zostać zaimplementowane nawet poza Redis, ale jeśli już z nich korzystasz, sensowne jest również zarządzanie w nim swoimi blokadami.