羅永浩調侃俞敏洪轉行做主播?交個朋友公關負責人迴應
一、AOF持久化
除了RDB持久化功能之外,Redis還提供了AOF(Append Only File)持久化功能。與RDB持久化通過儲存資料庫中的鍵值對來記錄數 據庫狀態不同,AOF持久化是通過儲存Redis伺服器所執行的寫命令來 記錄資料庫狀態的。
當對空白資料庫執行鍵值對命令時,RDB持久化是將鍵值儲存到RDB檔案中,而AOF持久化儲存資料庫狀態的方法是將命令寫入到AOF檔案中。被寫入AOF檔案的所有命令都是以Redis的命令請求協議格式儲存 的,因為Redis的命令請求協議是純文字格式,所以我們可以直接開啟 一個AOF檔案,觀察裡面的內容。
AOF持久化功能的實現可以分為命令追加(append)、檔案寫入、 檔案同步(sync)三個步驟。
當AOF持久化功能處於開啟狀態時,伺服器在執行完一個寫命令之 後,會以協議格式將被執行的寫命令追加到伺服器狀態的aof_buf緩衝區 的末尾:
struct redisServer { // ... // AOF 緩衝區 sds aof_buf; // ... };
Redis的伺服器程序就是一個事件迴圈(loop),這個迴圈中的檔案 事件負責接收客戶端的命令請求,以及向客戶端傳送命令回覆,而時間 事件則負責執行像serverCron函式這樣需要定時執行的函式。 因為伺服器在處理檔案事件時可能會執行寫命令,使得一些內容被 追加到aof_buf緩衝區裡面,所以在伺服器每次結束一個事件迴圈之前, 它都會呼叫flushAppendOnlyFile函式,考慮是否需要將aof_buf緩衝區中 的內容寫入和儲存到AOF檔案裡面。
flushAppendOnlyFile函式的行為由伺服器配置的appendfsync選項的 值來決定,各個不同值產生的行為。
如果使用者沒有主動為appendfsync選項設定值,那麼appendfsync選項 的預設值為everysec,關於appendfsync選項的更多資訊,請參考Redis項 目附帶的示例配置檔案redis.conf。
檔案寫入和同步:
為了提高檔案的寫入效率,在現代作業系統中,當用戶呼叫write 函式,將一些資料寫入到檔案的時候,作業系統通常會將寫入資料暫 時儲存在一個記憶體緩衝區裡面,等到緩衝區的空間被填滿、或者超過 了指定的時限之後,才真正地將緩衝區中的資料寫入到磁盤裡面。 這種做法雖然提高了效率,但也為寫入資料帶來了安全問題,因 為如果計算機發生停機,那麼儲存在記憶體緩衝區裡面的寫入資料將會 丟失。 為此,系統提供了fsync和fdatasync兩個同步函式,它們可以強制 讓作業系統立即將緩衝區中的資料寫入到硬盤裡面,從而確保寫入數 據的安全性。
AOF持久化的效率和安全性:
伺服器配置appendfsync選項的值直接決定AOF持久化功能的效率 和安全性。
- 當appendfsync的值為always時,伺服器在每個事件迴圈都要將 aof_buf緩衝區中的所有內容寫入到AOF檔案,並且同步AOF檔案,所 以always的效率是appendfsync選項三個值當中最慢的一個,但從安全 性來說,always也是最安全的,因為即使出現故障停機,AOF持久化 也只會丟失一個事件迴圈中所產生的命令資料。
- 當appendfsync的值為everysec時,伺服器在每個事件迴圈都要 將aof_buf緩衝區中的所有內容寫入到AOF檔案,並且每隔一秒就要在 子執行緒中對AOF檔案進行一次同步。從效率上來講,everysec模式足夠快,並且就算出現故障停機,資料庫也只丟失一秒鐘的命令資料。
- 當appendfsync的值為no時,伺服器在每個事件迴圈都要將 aof_buf緩衝區中的所有內容寫入到AOF檔案,至於何時對AOF檔案進 行同步,則由作業系統控制。因為處於no模式下的 flushAppendOnlyFile呼叫無須執行同步操作,所以該模式下的AOF文 件寫入速度總是最快的,不過因為這種模式會在系統快取中積累一段 時間的寫入資料,所以該模式的單次同步時長通常是三種模式中時間 最長的。從平攤操作的角度來看,no模式和everysec模式的效率類 似,當出現故障停機時,使用no模式的伺服器將丟失上次同步AOF文 件之後的所有寫命令資料。