Redis的內部結構如下圖所示:
各功能模組說明如下:
File Event: 處理檔案事件(在多個用戶端中實現多工,接受它們發來的命令請求(讀事件),並將命令的執行結果返回給用戶端(寫事件))
Time Event: 時間事件(更新統計資料,清理到期資料,附屬節點同步,定期持久化等)
AOF: 命令日誌的資料持久化
RDB:實際的資料持久化
Lua Environment : Lua 指令碼的運行環境. 為了讓 Lua 環境符合 Redis 指令碼功能的需求, Redis 對 Lua 環境進行了一系列的修改, 包括添加函數庫、更換隨機函數、保護全域變數, 等等
Command table(命令表):在執行命令時,根據字元來尋找相應命令的實現函數。
Share Objects(對象共用):
主要儲存常見的值:a.各種命令常見的傳回值,例如傳回值OK、ERROR、WRONGTYPE等字元;b. 小於 redis.h/REDIS_SHARED_INTEGERS (預設1000)的所有整數。通過預分配的一些常見的值對象,並在多個資料結構之間共用對象,程式避免了重複分配的麻煩。也就是說,這些常見的值在記憶體中只有一份。
Databases:
Redis資料庫是真正儲存資料的地方。當然,資料庫本身也是儲存在記憶體中的。
Databased的資料結構虛擬碼如下:
<span style="font-family:Microsoft YaHei;font-size:18px;">typedef struct redisDb { // 儲存著資料庫以整數表示的號碼 int id; // 儲存著資料庫中的所有索引值對資料 // 這個屬性也被稱為鍵空間(key space) dict *dict; // 儲存著鍵的到期資訊 dict *expires; // 實現列表阻塞原語,如 BLPOP // 在清單類型一章有詳細的討論 dict *blocking_keys; dict *ready_keys; // 用於實現 WATCH 命令 // 在事務章節有詳細的討論 dict *watched_keys;} redisDb;</span>
一個資料庫,在記憶體中的資料結構如下圖所示:
Database的內容要點包括:
ü 資料庫主要由 dict 和 expires 兩個字典構成,其中 dict 儲存索引值對,而 expires 則儲存鍵的到期時間。
ü 資料庫的鍵總是一個字串對象,而值可以是任意一種 Redis 資料類型,包括字串、雜湊、集合、列表和有序集。
ü expires 的某個鍵和 dict 的某個鍵共同指向同一個字串對象,而 expires鍵的值則是該鍵以毫秒計算的 UNIX 到期時間戳記。
ü Redis 使用惰性刪除和定期刪除兩種策略來刪除到期的鍵。
ü 更新後的 RDB 檔案和重寫後的 AOF 檔案都不會保留已經到期的鍵。
ü 當一個到期鍵被刪除之後,程式會追加一條新的 DEL 命令到現有 AOF 檔案末尾。
ü 當主節點刪除一個到期鍵之後,它會顯式地發送一條 DEL 命令到所有附屬節點。
ü 附屬節點即使發現到期鍵,也不會自作主張地刪除它,而是等待主節點發來 DEL 命令,這樣可以保證主節點和附屬節點的資料總是一致的。 資料庫的dict 字典和expires 字典的擴充策略和普通字典一樣。它們的收縮策略是:當節點的填充百分比不足 10% 時,將可用節點數量減少至大於等於當前已用節點數量。