本篇主要討論 Redis 對於 ACID 之關係
以下是簡介
- 先簡介一下ACID
- Redis 探討符合 ACID ?
- 總結
簡介一下ACID
Atomicity 原子性
基本上可以理解成,如果你在一個 transection 中,你所做的事情一定是全部成功,或是全部失敗,不會成功一部分。可以想像做到一半失敗的話,必須支持 rollback 機制。
Consistency 一致性
你的資料只會從一個有效的狀態 (valid data) 轉換到另外一個有效的狀態,這邊用 mysql 舉例一下,例如你有一個欄位定義的型別是 int,那在你資料修改完提交之後,這個欄位儲存的值也會是 int,不會變成 char。其他還有類似一些 foreign constrain 也會遵守。
Isolation 隔離性
簡單來說就是一個 transection 不會被其他的 transection干擾。但是以mysql 來說就是根據你設定的 isolation level 是甚麼來達到不同程度的隔離。
Durability 永久性
總之就是 transection 提交之後,他就會永久存在 ((即便 電源被拔掉或系統 crashed))。
好以上簡介完 ACID 了。大家應該有個觀念,如果想要更詳細的可以在 google 一下
Redis 探討符合 ACID ?
Redis: Atomicity 原子性
部分實現透過以下兩個
- LUA script
- MULTI
首先Redis 可以支持原子操作,意思是說你在操作的時候也絕對不會被其他的client 打斷你執行中的 LUAscript/ MULTI,但是不支援 rollback,所以單就這點來說,不符合上面定義的原子性。
細節探討的話可以分為 →EXEC 執行前出錯 / EXEC執行後出錯
EXEC 執行前出錯 ( before exec )
在指令出錯的時候(例如語法上的錯誤 typo),基本上這個就不會排進執行的 queue 裡面。還有一個錯誤就是當 redis server 的 memory 達到上限。此時都會在 EXEC 執行前就出錯。所以可以符合原子性
EXEC 執行後出錯 ( after exec )
總結就是,他只會讓錯誤那一行不執行,但是正確的通通會幫你執行。
It’s important to note that even when a command fails, all the other commands in the queue are processed — Redis will not stop the processing of commands.
所以呢因為以上這一點,他違反了 原子性。
Redis: Consistency一致性
基本上不符合,因為你可以用 SET 一個指令就改變某個 Key 的資料型態。
If key already holds a value, it is overwritten, regardless of its type.
only
SET
has that power, other commands will error when presented with the wrong type of value.
Redis: Isolation 隔離性
可以用 WATCH 指令達到說,監控你關心的 Key 有沒有被其他的 client 修改。
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
如果再 WATCH 跟 EXEC 之間修改 mykey,那你的 EXEC 會失敗,可以視為你的 transection 被 abort。 這是一種樂觀鎖
Redis: Durability 永久性
Redis 沒特別設定的時候不會把數據儲存到硬碟,如果要的話有兩種模式 RDB 跟 AOF。
— RDB
Redis 使用了 RDB 模式,在一個 transection 之後,而下一次的 RDB snapshot 還沒開始執行前,如果有當機或是電源拔掉,資料是會不見的,所以沒有保證 Durability
— AOF
no/everysec/always 都會存在數據資料不見的情形。
不管 Redis 使用哪一個方案,transection 的永久性是得不到保證的。
總結
- Redis 具備一部分的原子性,但是不支援 rollback
- Redis 不支援一致性
- Redis 可以具備 isolaction 的特性 (透過 Watch 達成)
- Redis 無法保證 Durability
以上是最近查資料相關的部分,如果有錯誤的話可以提出來討論
Reference