redis原始碼分析(五):資料持久化
redis 是基於記憶體讀寫的資料庫,所有資料都儲存在記憶體中,所以儲存的資料大小受到了限制。但redis依然提供了固化功能,與mysql,leveldb等資料庫不同的是,redis的儲存功能只是用做備份,恢復的功能,全量資料還是儲存在記憶體中。
redis內部提供了兩種固化資料的方式,aof 和rdb。
1.aof
資料寫入
aof全稱appendOnlyFile,要讓redis支援aof方式,需要將配置檔案的appendonly配置為"yes",並配置appendfsync 為everysec/always/no。everysec是redis推薦的配置,我們預設以這種方式來具體分析。
每次對資料有修改的操作,均會以append的方式寫入server.aof_buf中,每秒鐘將在時間事件中檢查這個緩衝區是否為空,不空則說明有新的更新,將其寫入aof檔案中(注意write函式並非實時寫入硬碟,可以用flush函式來強制重新整理未寫入的快取),並觸發重新整理任務,通知bio模組建立的執行緒中執行。aof的檔案是相對"白話"的,如圖是我本地擷取的aof檔案:
1.png
'*'後跟的是當前的引數個數,'$'後跟的是下一個引數的長度,再後來就是引數了。一個redis中有多個資料庫,我們需要確定資料增改到那個資料庫了,因此第一句為select db的操作。
除了手動配置的重新整理aof規則外,客戶端可以手動觸發bgrewriteaof來覆蓋已有的aof檔案(未開啟aof配置也是支援這個命令),客戶端發起此命令後,redis會fork一個子程式來將記憶體中的資料儲存到檔案中。那麼問題來了,子程式執行過程中,redis主程式依然在提供服務,如果期間寫入新的資料,那麼主子程式間的資料將會不同步,如何解決?期間的資料會儲存在連結串列資料塊server.aof_rewrite_buf_blocks中,當主程式用wait方法檢測到子程式退出以後,會呼叫backgroundRewriteDoneHandler函式,將快取的資料附加到新的aof檔案中。重寫aof可以減小aof檔案的大小,因為部分資料失效,或者來回更改,在everysec的配置中均會儲存下來,但是重寫aof之後,無效資料,或者中間狀態的修改均會被忽略。
資料載入
redis剛啟動的時候會優先檢查是否開啟aof配置(否則rdb),如果是則載入aof配置檔案,每個引數均以'n'結尾,因此讀取/判斷合法十分方便。建立一個fakeClient來模擬客戶端將資料插入記憶體中。這裡有一個疑問,資料載入的同時,服務依然處理客戶端的io任務,這樣不怕aof的舊檔案寫髒使用者新插入的資料麼。
2.rdb
資料寫入
使用者可以配置redis中save的引數,格式為save sec commit 代表每sec秒,如果有commit次修改,則由服務自身執行一次bgsave操作。save配置可以有多個,相互之間是或的關係。server.dirty用來記錄資料修改次數,bgsave完成以後,會將其置0。
redis的每次寫入都是全量操作,步驟如下
1.建立臨時檔案,寫入redis字串+版本號。
2.寫入select db語句,如果當次db沒有資料,跳到下一個,沒有更多資料庫了,跳到步驟5。
3.建立字典的迭代器,迴圈字典內的元素。
4.redis都是鍵值對資料,分別寫入超時時間(如果有的話),value的型別,key,value,其中key和value儘可能的壓縮編碼。如果迭代器到達結尾,跳到步驟2。
5.大於4的版本加入了校驗碼,校驗和使用crc計算,用臨時檔案覆蓋正式rdb檔案,流程結束。
資料載入
這個也沒有懸念了,怎麼寫入,就怎麼載入;讀取到資料之後直接呼叫dbAdd函式把資料插入到字典server.db[dbnum]->dict中。
對比下aof和rdb。
1.aof檔案相對於直接儲存了語句和中間過程。所以更易於開發者修改檢視資料。追加修改的命令,對io,cpu,記憶體壓力均較小,相對來說更吃儲存空間。
2.aof的缺點就是rdb的優點了。特別是如果rdb的save引數儲存不當,redis會頻繁執行bgsave命令,每次都是全量修改,在資料量大,修改頻繁的時候會是個災難。
作者:msrpp
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2001/viewspace-2816403/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [Redis原始碼閱讀]redis持久化Redis原始碼持久化
- Redis 資料持久化Redis持久化
- Redis資料持久化—RDB持久化與AOF持久化Redis持久化
- Redis的資料持久化Redis持久化
- Redis(五)--- Redis的持久化RDB與AOFRedis持久化
- redis個人原始碼分析筆記5---RDB持久化機制Redis原始碼筆記持久化
- Redis——Redis用作資料庫(持久化/RDB/AOF)Redis資料庫持久化
- Redis資料結構概覽(原始碼分析)Redis資料結構原始碼
- [Redis]持久化Redis持久化
- redis持久化Redis持久化
- Redis - 持久化Redis持久化
- Redis 持久化Redis持久化
- Redis系列2:資料持久化提高可用性Redis持久化
- Redis原始碼分析-底層資料結構盤點Redis原始碼資料結構
- Giraph 原始碼分析(五)—— 載入資料+同步總結原始碼
- redis 持久化策略Redis持久化
- Redis的持久化Redis持久化
- Redis 的持久化Redis持久化
- redis 之 持久化Redis持久化
- Redis 七 持久化Redis持久化
- Redis 持久化方案Redis持久化
- redis ——AOF持久化Redis持久化
- Redis 持久化(Persistence)Redis持久化
- Redis:持久化篇Redis持久化
- redis-持久化Redis持久化
- redis之 Redis持久化配置Redis持久化
- redis系列:RDB持久化與AOF持久化Redis持久化
- Redis基礎—瞭解Redis是如何做資料持久化的Redis持久化
- 【趙渝強老師】Redis的RDB資料持久化Redis持久化
- Redis 資料持久化方案的介紹及應用Redis持久化
- redis georadius原始碼分析與效能最佳化Redis原始碼
- preact原始碼分析(五)React原始碼
- Docker資料持久化Docker持久化
- fabric資料持久化持久化
- 高可用Redis(七):Redis持久化Redis持久化
- 詳細分析Redis的持久化操作——RDB與AOFRedis持久化
- Redis資料結構—跳躍表 skiplist 實現原始碼分析Redis資料結構原始碼
- Redis 資料傾斜與 JD 開源 hotkey 原始碼分析揭秘Redis原始碼