理解 Redis 內部結構是掌握其高效能、支援多資料型別、實現事務與持久化的基石。本文深入解析伺服器啟動時的資料庫陣列、鍵值存儲字典、以及讀寫流程中的維護工作。
Redis 伺服器啟動時建立 redisDb[] 陣列,大小由 databases 16(預設 16)配置決定。每個元素為一個 redisDb 結構,代表一個邏輯資料庫(DB 0 ~ DB 15)。
redisDb[0]。SELECT 1 切換至 DB 1,但生產環境強烈建議僅使用 DB 0:databases 設為 1 可節省記憶體並簡化維護。每個 redisDb 內部包含一個 dict *dict 指針,指向一個哈希表(字典),鍵為 robj *key(Redis 物件),值為 robj *value。所有鍵值操作(SET/GET/HSET/RPUSH 等)最終均在此字典上進行。
SET msg "hello nana"
RPUSH mylist "a" "b" "c"
HSET book name "lover"
HSET book author "nana"
DB 0 的字典包含三個鍵:
msg → 字串物體("hello nana")mylist → 列表物體(["a","b","c"])book → 哈希物體({name:"lover", author:"nana"})
每次讀取鍵(讀或寫操作均需先查鍵)時,Redis 執行:
INFO stats 顯示 keyspace_hits/keyspace_misses。lru 欄位,供 maxmemory-policy allkeys-lru 等淘汰策略使用。server.dirty++,用於 RDB save 條件判斷與 AOF 重寫觸發。struct redisDb {
dict *dict; // 鍵值字典
dict *expires; // 過期字典:key -> 過期毫秒時間戳
dict *blocking_keys; // 阻塞鍵(BLPOP 等)
dict *ready_keys; // 就緒鍵
dict *watched_keys; // WATCH 鍵
int id; // DB 編號
long long avg_ttl; // 平均 TTL
};
struct redisServer {
redisDb *db; // redisDb[] 陣列
int dbnum; // databases 配置值
// ... 其他欄位
};
robj 封裝,字典值統一為 robj*,實現型別多態。dirty 計數器有助於調整 RDB/AOF 觸發頻率。Redis 以陣列管理多個邏輯資料庫,每個資料庫以字典存儲鍵值。讀寫路徑極短:哈希查找 → 維護統計/過期/LRU → 返回/更新物件。這種極簡結構配合單執行緒事件循環,成就了 Redis 的極致效能。