aof 檔案的載入和資料還原
aof 重寫
注意實際例子
參考鏈結
redis 原始碼簡潔剖析系列
伺服器在執行完乙個寫命令後,會以協議格式將被執行的寫命令
追加到伺服器狀態的aof_buf 緩衝區
的末尾:
struct redisserver
流程:aof 持久化是通過儲存被執行的寫命令來記錄資料庫狀態的,隨著伺服器執行時間的流逝,aof 檔案的內容會越來越多,檔案體積越來越大
。如果客戶端執行了下面的命令:
127.0.0.1:6379> set name yano
ok127.0.0.1:6379> set name yano2
ok127.0.0.1:6379> set name yano3
ok
那麼 aof 檔案就需要儲存 3 條命令,不僅使儲存的 aof 檔案體積變大,還使得 redis 啟動時載入資料變慢。
aof 檔案重寫(rewrite
),建立新的 aof 檔案替代現有的 aof 檔案,新舊兩個 aof 檔案所儲存的資料庫狀態相同,但新 aof 檔案不會包含任何浪費空間的冗餘命令,體積更小。
不是讀取和分析現有的 aof 檔案內容,而是直接從資料庫讀取值組成相應的命令 aof 檔案。
重寫函式 aof_rewrite 會進行大量的寫入操作,執行這個函式的執行緒會被長時間阻塞,但是 redis 伺服器使用單個執行緒來處理命令請求,如果直接在主線程直接更新,在重寫期間,伺服器將無法處理客戶端發來的命令請求。所以將 aof 重寫程式放到子程序中執行。
子程序在進行 aof 重寫期間,伺服器程序還需要繼續處理命令請求,新的命令可能對現有的資料庫狀態進行修改,導致伺服器當前資料庫狀態和重寫後的 aof 檔案儲存的資料狀態不一致。
為了解決這種資料不一致
的問題,redis 設定了乙個aof 重寫緩衝區
,在伺服器建立子程序之後開始使用,當 redis 伺服器執行完乙個寫命令後,同時將這個寫命令傳送給aof 緩衝區
和aof 重寫緩衝區
:
當子程序完成 aof 重寫工作後,它會向父程序傳送乙個訊號,父程序在收到這個訊號後,會呼叫乙個訊號處理函式:
將 aof 重寫緩衝區的所有內容寫入新的 aof 檔案,這樣新 aof 檔案所儲存的資料庫狀態就與伺服器當前的資料庫狀態一致;
對新 aof 檔案改名,原子覆蓋現有的 aof 檔案,完成新舊 aof 檔案的替換。
下圖左邊是正常流程,右邊是 aof 重寫期間的流程:
在實際中,為了避免在執行命令時造成客戶端輸入緩衝區的溢位,重寫程式在處理列表、雜湊表、集合、有序集合可能帶有多個元素的鍵時,會先檢查鍵所包含的元素數量,如果元素數量超過了乙個常量閾值,重寫程式會使用多條命令來記錄鍵的值。
配置redis.conf
檔案,使用 aof:
dir ./
啟動 redis server:
src/redis-server redis.conf&
啟動 redis client:
src/redis-cli
設定 key:
127.0.0.1:6379> set name yano
ok127.0.0.1:6379> set name yano2
ok127.0.0.1:6379> set name yano3
ok
*2
$6select$10
*3$3
set$4
name
$4yano
*3$3
set$4
name
$5yano2
*3$3
set$4
name
$5yano3
redis原始碼剖析 skiplist
試想乙個業務場景 遊戲需要實現乙個實時更新的排行榜應該如何實現 首先想到使用有序的雙端鍊錶,因為插入的時間複雜度為o 1 但是定位的平均時間複雜度為o n 當頻繁更新排行榜的時候效率比較低 有沒有乙個結構 能夠滿足快速定位到相應的位置並插入?跳躍表就能滿足這個需求 跳躍表的思想是給資料結點建立索引 ...
redis原始碼剖析 dict
typedef struct dictentry v struct dictentry next dictentry typedef struct dicttype dicttype this is our hash table structure.every dictionary has two ...
原始碼剖析 Hashtable 原始碼剖析
hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...