文章目錄
- 服務器保存數據庫的方法
- 服務端切換數據庫的方法
- 數據庫保存鍵值對的方法
- 保存鍵的
過期時間
的方法- 服務器自動刪除
過期鍵
的方法
服務器中的數據庫
Redis服務器將所有數據庫都保存在服務器狀態
redisServer
結構的db數組中,每個數據庫都是一個redisDb
結構,dbnum
屬性來決定創建多少個數據庫(默認16
)。
切換數據庫
默認數據庫是0號數據庫,但是客戶段可以通過
select
命令來切換目標數據庫。
- 在redisClient.db指針指向
redisServer.db
數組的其中一個元素,而被指向的元素就是客戶端的目標數據庫。- 通過修改
redisClient.db
指針,讓它指向服務器中不同的數據庫,從而實現切換目標 數據庫的功能----這就是select
命令的實現原理。
數據庫如何存儲數據
底層存儲結構–字典
- Redis是一個鍵值對數據庫服務器,服務器中的每個數據庫都是由一個
redisDb
構成,其中redisDb
結構的dict
字典中保存了數據庫中的所有鍵值對,我們將這個字典稱爲鍵空間
- 鍵空間的鍵也就是數據庫的鍵,每個鍵都是一個字符串對象;鍵空間的值也就是數據庫的值,每個值可以是字符串對象,列表對象,哈希表對象。
添加鍵
添加一個新鍵值對到數據庫,實際上就是一個新鍵值對添加到鍵空間字典裏面,其中鍵爲字符串對象,而值則爲任意一種類型的Redis對象。
刪除鍵
刪除數據庫中的鍵,實際上就是在鍵空間裏面刪除鍵鎖對應的鍵值對對象。
更新鍵
對一個數據庫鍵進行更新,,實際上就是對鍵空間裏面鍵所對應的值對象進行更新,根據值對象的類型的不同,更新的具體方法也會有所不同。
對鍵取值
對一個數據庫鍵進行取值,實際上就是在鍵空間中取出鍵所對應的值對象。
對鍵的其他操作
- 如果服務器在讀取一個鍵時發現該鍵已經過期,那麼服務器會先刪除這個過期鍵,然後才執行餘下的其他操作。
- 如果有客戶端使用WATCH命令監事了某個鍵,那麼服務器在被監式的鍵進行修改之後,會將這個鍵標記爲
髒
,從而讓事務程序注意到這個鍵已經被修改過。
數據庫鍵的生存時間
指令
- 通過expire或者pexpire命令,客戶單可以以秒或者毫秒精度數據庫爲數據庫的某個鍵設置生存時間,在經過指定的秒數或者毫秒數之後,服務器就會自動刪除生存時間爲0的鍵
- 通過
ExpireAT
命令或者PEXPIREAT
命令,以秒或毫秒精度給數據庫中某個鍵設置過期時間ttl
和pttl
命令接受一個帶有生存時間或者過期時間的鍵,返回這個鍵的剩餘生存時間
如何存儲鍵的過期時間
- redisDb結構的
expire
字典保存了數據庫中所有鍵的過期時間,我們稱這個字典爲過期字典- 過期字典的鍵是一個指針,這個指針指向鍵空間的某個鍵對象(也就是數據庫鍵)
- 過期字典的值是一個
long long
類型的整數,這個整數保存了鍵所指向的數據庫的過期時間—一個毫秒精度的UNIX
時間戳
如何刪除過期的鍵
可選刪除策略
定時刪除
:在設置鍵的過期時間的同時,創建一個定時器
,讓定時器在鍵過期時間來臨時,立即執行對鍵的刪除操作(對內存友好,效率低
)惰性刪除
:放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵;如果沒有過期,就返回該鍵(對內存不友好,效率高
)定期刪除
:每隔一段時間,程序就對數據庫進行一次檢查,刪除裏面的過期鍵,置於要刪除多少過期鍵,以及要檢查多少個數據庫,由算法決定
Redis的刪除策略
Redis服務器實際使用的是惰性刪除
和定期刪除
兩種策略,通過配合使用這兩種刪除策略
,服務器可以很友好的在合理使用cpu時間
和避免浪費內存
之間取得平衡。
惰性刪除策略的實現
- 如果輸入鍵已經過期,那麼將輸入鍵從數據庫中刪除
- 如果輸入鍵未過期,那麼將不做任何動作
定時刪除策略的實現
在規定的時間內,分多次遍歷服務器中的各個數據庫,從數據庫的expires
字典中隨機檢查一部分鍵的過期時間,並刪除其中的過期鍵
過期鍵對RDB的影響
- 在生成RDB文件的時候,已過期的鍵不會被保存到新創建的
RDB
文件中 - 在載入RDB文件的時候,如果是主服務器則將過期鍵刪除;如果是從服務器,無論是否過期,都會載入到內存中
過期鍵對AOF的影響
- 當服務器以AOF持久化模式運行時,如果數據庫中的某個鍵已經過期,但它還沒有被惰性刪除或者定期刪除,那麼AOF文件不會因爲這個過期鍵而產生任何影響
- 當過期鍵被
惰性刪除
或者定期刪除
之後,程序會向AOF
文件追加一條DEL
命令,來顯示的記錄被該鍵已經發被刪除 - 在執行
AOF重寫
的過程中,程序會對數據庫中的鍵進行檢查,已過期的鍵不會被保存到重寫後的AOF
文件中