目錄
前言
1. Redis中的資料庫
2. 資料庫的鍵空間
3. 鍵的生成時間與過期時間
4. Redis中的過期鍵删除政策
5. AOF、RDB和複制功能對過期鍵的處理
5.1 生成 RDB 檔案
5.2 載入 RDB 檔案
5.3 AOF 檔案寫入
5.4 AOF 重寫
5.5 複制
6. 資料庫通知
最後
參考資料:《Redis設計與實作 第二版》;
第二部分為單機資料庫的實作,主要由以下子產品組成:資料庫、持久化、事件、用戶端與伺服器;
本篇将介紹 Redis 中的資料庫;
與本章相關的 Redis 指令總結在下篇文章,歡迎點選收藏,本篇将不再重複:
《Redis常用指令及示例總結(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html
Redis伺服器的所有資料庫儲存在<code>redis.h/redisService</code>結構的db數組中:
<code>dbnum</code>屬性由伺服器配置的 database 選項決定,預設為 16;
Redis用戶端資料庫儲存在在<code>redisClient</code>結構的<code>db</code>屬性:
用戶端通過修改目标資料庫指針,讓它指向 redisService.db 數組中的不同元素;
可以通過 SELECT index 指令來切換資料庫;

資料庫的定義在<code>redis.h/redisDb</code>結構中:
鍵空間的鍵是資料庫的鍵,每個鍵是一個字元串對象;
鍵空間的值是資料庫的值,每個值可以是字元串對象、清單對象、哈希表對象、集合對象和有序集合對象中的一種;
資料庫鍵空間是一個字典,所有針對資料庫的操作都是通過鍵空間字典來操作的;
在對鍵空間進行讀寫操作時,Redis 還會進行一些維護操作:
讀取鍵後,會根據鍵是否存在更新伺服器的鍵空間命中 keyspace_hits 次數或鍵空間不命中 keyspace_misses 次數。通過 INFO stats 指令檢視屬性;
讀取鍵後,伺服器會更新鍵的 LRU(最後一次使用時間)。通過 ONBJECT idlettime [key] 指令檢視key的閑置時間;
伺服器在讀取鍵時發現鍵已經過期,會先删除這個過期鍵;
如果有用戶端使用 WATCH 指令監視某個鍵,伺服器對該鍵修改後會标記上髒 <code>dirty</code>,讓事務處理程式注意;
伺服器每修改一個鍵後,會對髒 <code>dirty</code> 鍵計數器值增 1,計數器會觸發伺服器的持久化以及複制操作;
鍵的時間相關設定指令參看《Redis常用指令及示例總結》1.3 生存時間的功能;
生存時間:
用戶端可以通過 EXPIRE 或 PEXPIRE 指令以秒或毫秒精度為資料庫中某個鍵設定生存時間(Time To Live,TTL)。經過指定時間後,伺服器自動删除生存時間為0的鍵;
可以通過 SETEX 指令在設定字元串鍵同時設定過期時間;
使用 TTL 或 PTTL 指令擷取鍵的剩餘生存時間;
過期時間:
用戶端設定過期時間的指令是 EXPIREAT 或 PEXPIREAT;
過期時間是一個 UNIX 時間戳;
EXPIRE、PEXPIRE 和 EXPIREAT 三個指令都會轉換成 PEXPIREAT 指令實作;
有三種删除過期鍵的政策:
定時删除:主動政策。對記憶體最友好,到期就釋放記憶體。缺點是對CPU事件不友好,當過期鍵比較多時,會占用一部分CPU時間;
惰性删除:被動政策。對CPU時間最友好。每次從鍵空間擷取鍵時,檢查取得的鍵是否過期,過期則删除。缺點是對記憶體不友好;
定期删除:主動政策。前兩種政策的整合與折中。每隔一段時間執行一次删除過期鍵操作,并通過限制删除操作執行的時長與頻率減少删除操作對CPU時間的影響。缺點是難以确定删除操作執行的時長和頻率;
惰性删除政策由 <code>db.c/expireIfNeeded</code> 函數實作,流程如下:
定期删除政策由 <code>redis.c/activeExpireCycle</code> 函數實作,每當Redis的伺服器周期性操作 <code>redis.c/serverCron</code> 函數執行時,activeExpireCycle 函數會被調用。在規定的時間内,分多次周遊伺服器各個資料庫,從資料庫的 <code>expires</code> 字典中随機檢查一部分過期時間,删除其中過期鍵;
在執行 SAVE 或 BGSAVE 指令建立一個新的 RBG 檔案時,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被儲存到新建立的 RDB 檔案中;
載入 RDB 檔案時:
若伺服器以主伺服器模式運作,過期鍵不載入;
若伺服器以從伺服器模式運作,所有鍵都會載入;
當伺服器以 AOF 持久化模式運作時,未被惰性删除和定期删除的過期鍵不會對 AOF 檔案産生影響;
當過期鍵被惰性删除或定期删除後,程式會向 AOF 檔案追加(append)一條 DEL 指令,顯示記錄該鍵已被删除;
與 RDB 檔案類似,在執行 AOF 重寫過程中,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被儲存到重寫後的 AOF 檔案中;
當伺服器運作在複制模式下時,從伺服器的過期鍵删除動作由主伺服器控制;
資料庫通知是 Redis 2.8 版本新增的功能;
資料庫通知可以讓用戶端通過訂閱給定的頻道或模式,來獲知資料庫中鍵的變化,以及資料庫中指令的執行情況;
Redis 指令對資料庫進行修改後,伺服器會根據配置向用戶端發送資料庫通知;
通知的相關指令可以參考 《Redis常用指令及示例總結》7. Pub/Sub(釋出/訂閱);
兩類通知類型:
鍵空間通知 key-space notification:關注 “某個鍵執行了什麼指令”;SUBSCRIBE channel:message;
鍵事件通知 key-event notification:關注 “某個指令被什麼鍵執行了”;SUBSCRIBE channel:del;
伺服器配置的 <code>notify-keyspace-events</code> 選項決定伺服器所發送通知的類型:
AKE:發送所有類型的鍵空間和鍵事件通知;
AK:發送所有類型的鍵空間通知;
AE:發送所有類型的鍵事件通知;
K$:隻發送字元串有關的鍵空間通知;
EL:隻發送清單鍵有關的鍵事件通知;
發送資料庫通知的功能是由 <code>notify.c/notifyKeyspaceEvent</code> 函數實作;
新人制作,如有錯誤,歡迎指出,感激不盡!
歡迎關注公衆号,會分享一些更日常的東西!
如需轉載,請标注出處!