Pokud je Redis jednovláknový, tak proč vůbec potřebovat zamykací mechanismus.
Redis je skutečně (většinou) jednovláknový, ale zamykání je vyžadováno, když se více klientů pokouší dělat různé věci v sousední časové blízkosti. Zamykání, o kterém se mluví v RiA, je přesně o tom – zajistit, aby konkrétní úkol provedl pouze jeden klient/vlákno, nebo zajistit, aby se aktualizace nezkazily.
Zde je příklad, proč byste potřebovali zamykání i přes jednovláknovost Redis:předpokládejme, že máte hodnotu v Redis, číslo uložené například pod klíčem s názvem foo
. Kód vaší aplikace toto číslo přečte (GET foo
), něco udělá (např. přidá 1) a zapíše to zpět (SET
). Když spustíte svůj kód v jediném vláknu, bude to vypadat takto:
App Redis
|---- GET foo ---->|
|<------ 1 --------|
| |
| thinking... |
| |
|--- SET foo 2 --->|
|<----- OK --------|
Nyní se podívejme, co se stane, když se o to pokusí dva klienti aplikace:
App 1 Redis App 2
|---- GET foo ---->| |
|<------ 1 --------|<--- GET foo -----|
| |------- 1 ------->|
| thinking... | |
| | thinking...|
|--- SET foo 2 --->| |
|<----- OK --------|<--- SET foo 2 ---|
| |------ OK ------->|
Zde můžete okamžitě vidět, co se stalo bez zamykání, přestože je server (většinou) s jedním vláknem - namísto 3 foo
Hodnota 's je 2. Jak přidáváte další vlákna/klienty/aplikace, věci se mohou vesele a strašně pokazit, když se více autorů pokusí upravit data bez koordinace (např. uzamčení).
Optimistické zamykání je jen jedním ze způsobů, jak toho dosáhnout, které Redis nabízí vestavěné prostřednictvím WATCH
mechanismus. Někdy však optimismus – navzdory jeho snadné a šťastné povaze – není tím správným řešením, takže budete muset implementovat lepší/pokročilejší/jiné mechanismy, abyste předešli rasovým podmínkám. Takové zámky by pravděpodobně mohly být implementovány i mimo Redis, ale pokud jej již používáte, má smysl spravovat své zámky také v něm.