redis服務器將所有數據庫都保存在redis/redisServer中,數組db存放所有數據庫,每一項是一個redisdb結構。dbnum代表數據庫數量。
客戶端有一個指針指向當前數據庫,可以切換,也就是移動指針。
鍵空間
現在稍微介紹一下redisdb結構,它的字典保存了所有鍵值對
鍵空間的鍵也就是數據庫的鍵, 每個鍵都是一個字符串對象。
鍵空間的值也就是數據庫的值, 每個值可以是字符串對象、列表對象、哈希表對象、集合對象、有序集合對象
所有數據庫的操作,添加一個鍵值對, 刪除一個鍵值對, 獲取某個鍵值對, 等等,都是通過對鍵空間字典進行操作來實現的。
維護
讀寫鍵空間的時候,服務器會執行一些額外操作,比如:
- 讀一個鍵后(讀操作寫操作都要對鍵讀取),?會根據鍵是否存在, 更新鍵空間命中(hit)次數或不命中(miss)次數。
- 讀取一個鍵后, 服務器會更新鍵的 LRU (最后一次使用)時間, 這個值可以用于計算鍵的閑置時間。
- 如果服務器在讀一個鍵時, 該鍵已經過期, 服務器會刪除這個鍵, 然后執行其他操作。
- 如果客戶使用?WATCH?監視某個鍵,在對這個鍵進行修改之后, 會將這個鍵記為臟(dirty),讓事務程序知到這個鍵被修改
- 服務器每次修改一個鍵之后, 都會對臟(dirty)鍵計數器的值增一, 這個計數器會觸發服務器的持久化以及復制操作執行
- 如果服務器開啟了數據庫通知功能, 那么在對鍵進行修改之后, 服務器將按配置發送相應的數據庫通知。
時間
用戶可以給某個鍵設置生存時間,過期時間是一個UNIX時間戳,到時間自動刪除這個鍵。
redisdb結構的expires字典保存了所有的鍵的過期時間,我們稱這個字典為過期字典。
三種過期鍵刪除策略
1)定時刪除:創建一個定時器,到時間立即執行刪除操作(對內存友好,因為能保證過期了立馬刪除,但是對cpu不友好)
2)惰性刪除:鍵過期不管,每次獲取鍵時檢查是否過期,過期就刪除(對cpu友好,但是只有在使用的時候才可能刪除,對內存不友好)
3)定期刪除:隔一段時間檢查一次(具體算法決定檢查多少刪多少,需要合理設置)
淘汰策略
當Redis占用內存超出最大限制 (maxmemory) 時,可采用如下策略 (maxmemory-policy) ,讓Redis淘汰一些數據,以騰出空間繼續提供讀寫服務 :
noeviction: 對可能導致增大內存的命令返回錯誤 (大多數寫命令,DEL除外) ;
volatile-ttl: 在設置了過期時間的key中,選擇剩余壽命 (TTL) 最短的key,將其淘汰;
volatile-lru: 在設置了過期時間的key中,選擇最少使用的key (RU) ,將其淘汰;
volatile-random: 在設置了過期時間的key中,隨機選擇一些key,將其淘汰;
allkeys-1Lru: 在所有的key中,選擇最少使用的key (LRU) ,將其淘汰;
allkeys-random: 在所有的key中,隨機選擇一些key,將其淘汰;
?