1. 程式人生 > >Redis資料庫的實現原理

Redis資料庫的實現原理

知道了Redis的各種資料結構,物件結構,那麼Redis是如何儲存資料的,又是如何操作資料的呢,Redis裡面的命令是怎麼實現的呢?這一系列問題值得我們思考 一.Redis維護多個數據庫 Redis內部維護一個db陣列,每個db都是一個數據庫,預設情況下Redis會建立16個數據庫。我們可以通過select命令來切換資料庫,如select 1切換到資料庫號為1的資料庫。select實現是通過修改客戶端的db指標,通過指標指向不同的資料庫來實現資料庫的切換操作的。 需要注意的是,為了不造成操作資料庫號錯誤,最好執行命令之前,手動select一下資料庫。 二.資料庫鍵空間 Redis是一個鍵值對資料庫伺服器,Redis通過字典儲存了資料庫中的所有鍵值對,我們將這個字典稱為鍵空間。鍵空間的每個鍵都是一個字串物件,鍵空間的值也就是資料庫的值,可以是字串物件,列表物件,雜湊表物件,集合物件,有序集合物件中的任何一種。 1.新增新鍵 每次新增一個新鍵就是將一個新鍵值對新增到鍵空間裡面,其中鍵為字串物件,值為任意一種型別的Redis物件。 2.刪除鍵 刪除鍵就是在鍵空間裡刪除鍵所對應的鍵值對物件。 3.更新鍵 更新鍵就是對鍵空間裡面鍵所對應的值物件進行更新。 4.查詢鍵 查詢鍵就是在鍵空間中取出鍵所對應的值物件。 每次在鍵空間讀取一個鍵之後,伺服器會更新鍵的LRU時間,用於計算鍵的閒置時間。如果伺服器在讀取一個鍵時發現該鍵已經過期,那麼伺服器會先刪除這個過期鍵,然後才執行後續操作。如果有客戶端使用watch命令監視了某個鍵,那麼伺服器在對被監視的鍵進行修改之後,會將這個鍵標記為dirty,從而讓事務注意到這個鍵被修改過。伺服器每次修改一個鍵之後,都會對鍵計數器的值+1,這個計數器用來觸發伺服器的持久化操作。如果伺服器開啟了資料庫通知功能,那麼在對鍵進行修改之後,伺服器將按配置傳送相應的資料庫通知。 三.設定鍵的生存時間和過期時間 我們知道expire命令或者pexpire命令可以對一個鍵設定生存時間,經過指定的時間之後,伺服器會自動刪除生存時間為0的鍵。那麼Redis是如何實現刪除過期鍵的操作的呢? Redis有四個命令可以設定鍵的過期時間,包括expire,pexpire,expireat,pexpireat,不過這四個命令最後都會轉化成pexpireat命令來實現。 Redis使用一個過期字典記錄所有帶過期時間的鍵,字典的鍵指向鍵空間中的某個鍵物件,字典的值是一個long long型別的整數,這個證書儲存了鍵空間所指向的資料庫鍵的過期時間。通過過期字典,程式可以檢查一個給定鍵是否過期,檢查給定鍵是否存在於過期字典,如果存在,取得鍵的過期時間,檢查當前時間戳是否大於鍵的過期時間,如果是的話,鍵已經過期,否則鍵未過期。 四.過期鍵的刪除策略 如果一個鍵過期了,那麼它什麼時候被刪除呢?通常我們可以用三種刪除策略刪除過期鍵 1.定時刪除:在設定鍵過期時間的同時,建立一個定時器,讓定時器在鍵的過期時間來臨時,刪除鍵 2.惰性刪除:放任鍵過期不管,但是每次動鍵空間獲取鍵時,都會檢查鍵是否過期,如果過期,則刪除。 3.定期刪除:每隔一段時間,程式就對資料庫進行一次檢查,刪除裡面的過期鍵。 這幾種方式各有利有弊,首先定時刪除對記憶體最友好,當一個鍵過期時,一定會刪除這個鍵,釋放記憶體。不過定時刪除對CPU最不友好,在過期鍵比較多的情況下,刪除過期鍵這一行為可能會佔用相當一部分CPU時間。此外,建立定時器需要用到Redis伺服器中的時間時間,而當前時間時間的實現方式-無序連結串列查詢一個事件的時間複雜度為O(N),不能高效地處理大量時間事件。 惰性刪除策略對CPU是最友好的,但是對記憶體最不友好。如果一個鍵已經過期,這個鍵又保留在資料庫中,那麼記憶體就會一直佔用不釋放。 定期刪除算是前兩種策略的一種整合和折中,定期策略每隔一段時間執行一次刪除過期鍵操作,並通過限制刪除操作執行的時長和頻率減少刪除操作對CPU時間的影響。定期刪除過期鍵可以有效地減少因為過期鍵帶來的記憶體浪費。 Redis過期鍵的刪除使用惰性刪除和定期刪除兩種策略配合使用。惰性策略比較好理解,所有讀寫資料庫的命令執行之前都會對輸入鍵進行檢查,如果鍵過期,那麼從資料庫中刪除鍵。定期刪除策略的實現由Redis的serverCron函式來執行,這個函式每100ms執行一次,它在規定的時間內,分多次遍歷伺服器中的各個資料庫,從資料庫的expires字典中隨機檢查一部分鍵的過期時間,刪除其中的過期鍵。 五.複製功能對過期鍵的處理 Redis複製主要包括RDB複製和AOF複製,在RDB複製中,每次執行SAVE或BGSAVE命令建立一個新的RDB檔案時,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被儲存到新建立的RDB檔案中。載入RDB檔案時,伺服器也會對儲存的鍵進行檢查,如果鍵已過期,則不會載入。當使用AOF持久化模式執行時,當過期鍵被惰性刪除或者定期刪除之後,程式會向AOF檔案追加一條刪除命令,記錄鍵已被刪除。 參考內容:Redis設計與實現-黃健巨集