Stories

Detail Return Return

【趙渝強老師】Redis的AOF數據持久化 - Stories Detail

​Redis 是內存數據庫,如果不將內存中的數據庫狀態保存到磁盤,那麼一旦服務器進程退出會造成服務器中的數據庫狀態也會消失。所以 Redis 提供了數據持久化功能。Redis支持兩種方式的持久化,一種是RDB方式;另一種是AOF(append-only-file)方式。兩種持久化方式可以單獨使用,也可以將這兩種方式結合使用。

視頻講解如下:
https://www.bilibili.com/video/BV1LrvwejEbq/?aid=112867328133...

AOF持久化以日誌的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。Redis還可以同時使用AOF持久化和RDB持久化。在這種情況下當重新啓動時,Redis會優先使用AOF文件來還原數據集。因為AOF文件保存的數據集通常比RDB文件所保存的數據集更完整。

視頻講解如下:
https://www.bilibili.com/video/BV1vmv4eEE8e/?aid=112881639097...

一、AOF持久化機制的工作流程

Redis提供的AOF持久化機制的工作流程如下:
(1)所有的命令都會追加到AOF緩衝區中。
(2)AOF緩衝區根據對應的策略向磁盤同步操作。
(3)隨着AOF文件越來越大,需要定期對AOF重寫,達到壓縮目的。
(4)當Redis服務器重啓時,可以加載AOF文件進行數據恢復。

但在默認情況下,Redis關閉了AOF持久化的功能。這是由redis.conf中下面的參數決定的:

###### APPEND ONLY MODE ######
......
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of
# writes in a dramatic event like a server power outage, or a single
# write if something wrong with the Redis process itself happens,
# but the operating system is still running correctly.
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is
# the file with the better durability guarantees.
# Please check https://redis.io/topics/persistence for more information.
#**appendonly yes 默認值為no,改為yes啓用AOF。**
# The name of the append only file (default: "appendonly.aof")
# **appendfilename "appendonly.aof" AOF默認生成的日誌文件名稱**
......

重啓Redis服務器端,將在Redis的安裝目錄下自動生成文件appendonly.aof。如下所示:

[root@nosql11 redis]# pwd
/root/training/redis
[root@nosql11 redis]# ll
total 16
**-rw-r--r--. 1 root root 0 Apr 16 16:01 appendonly.aof**
drwxr-xr-x. 2 root root 134 Apr 16 09:38 bin
drwxr-xr-x. 2 root root 24 Apr 16 16:01 conf
-rw-r--r--. 1 root root 10405 Apr 16 16:01 dump.rdb
-rw-r--r--. 1 root root 3955 Apr 16 16:01 redis.log
提示:AOF持久化機制在默認情況下將每隔一秒將Redis操作寫入日誌,這是由下面的參數決定的:
# appendfsync always
appendfsync everysec
# appendfsync no

Redis監控AOF最直接的方法當然就是使用系統提供的info命令來做了。只需要執行下面一條命令,就能獲得Redis關於AOF的狀態報告。

bin/redis-cli info | grep aof_

# 輸出的信-息如下:
aof_enabled:1                    AOF日誌是否啓用
aof_rewrite_in_progress:0        表示當前是否在進行寫入AOF日誌操作
aof_rewrite_scheduled:0            是否有AOF操作等待執行。
aof_last_rewrite_time_sec:-1        表示上次寫入AOF日誌的時間戳
aof_current_rewrite_time_sec:-1    當前正在執行的AOF重寫操作已經消耗的時間。
aof_last_bgrewrite_status:ok        表示上次執行AOF日誌重寫的狀態
aof_last_write_status:ok            表示上次寫入AOF日誌的狀態
aof_last_cow_size:0                AOF執行中父進程與子進程相比執行了多少修改
aof_current_size:0                AOF日誌的當前大小
aof_base_size:0                    最近一次重寫後AOF日誌的大小。
aof_pending_rewrite:0            是否有AOF操作在等待執行。
aof_buffer_length:0                AOF緩衝區的大小。
aof_rewrite_buffer_length:0        AOF重寫緩衝區的大小。
aof_pending_bio_fsync:0            在等待執行的fsync操作的數量。
aof_delayed_fsync:0                fsync操作延遲執行的次數。

二、【實戰】AOF日誌的重寫

因為AOF持久化是通過保存被執行的寫命令來記錄數據庫狀態的,所以隨着服務器運行時間的流逝,AOF文件中的內容會越來越多,文件的體積也會越來越大,如果不加以控制的話,體積過大的AOF文件很可能對Redis服務器、甚至整個宿主計算機造成影響,並且AOF文件的體積越大,使用AOF文件來進行數據還原所需的時間就越多。

為了解決AOF文件體積膨脹的問題,Redis提供了AOF文件重寫功能。通過該功能,Redis服務器可以創建一個新的AOF文件來替代現有的AOF文件,新舊兩個AOF文件所保存的數據庫狀態相同,但新AOF文件不會包含任何浪費空間的冗餘命令,所以新AOF文件的體積通常會比舊AOF文件的體積要小得多。

下面通過一個簡單的示例來測試AOF日誌的重寫。
(1)使用Redis的提供的基準測試工具模擬產生20萬個操作。

bin/redis-benchmark -n 200000

(2)觀察aof日誌文件的大小。

ll appendonly.aof 
-rw-r--r--. 1 root root 659 Apr 24 10:47 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 1663409 Apr 24 11:24 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 25115259 Apr 24 11:24 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 51573511 Apr 24 11:24 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 61600852 Apr 24 11:24 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 74649125 Apr 24 11:25 appendonly.aof
ll appendonly.aof 
-rw-r--r--. 1 root root 41135984 Apr 24 11:25 appendonly.aof
提示:在輸出信息的最後可以看出生成的appendonly.aof文件由74649125變成了41135984,這説明發生了AOF日誌的重寫。而AOF日誌的重寫由以下參數決定:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

三、剖析AOF持久化機制

在aof.c文件中可以找到創建RDB文件的函數flushAppendOnlyFile(),函數定義如下:

void flushAppendOnlyFile(int force) {
    //每秒刷入的時候,判斷一下aof的fsync是否在bio線程裏執行了
    if (server.aof_fsync == AOF_FSYNC_EVERYSEC)
        sync_in_progress = aofFsyncInProgress();
    
    //每秒並且非強制刷入
    if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) {
        if (sync_in_progress) {
        //刷入延期開始時間為0,表示沒有任何的執行
        if (server.aof_flush_postponed_start == 0) {
            //先將刷入延期開始時間置為當前時間
            server.aof_flush_postponed_start = server.unixtime;
            return;
         }else if(server.unixtime -server.aof_flush_postponed_start<2){
                return;
            }
            server.aof_delayed_fsync++;
        }
    }
    //寫入到aof文件裏
    nwritten = aofWrite(server.aof_fd,server.aof_buf,sdslen(server.aof_buf));
    //寫完aof後,將刷入延期開始時間置為0
    server.aof_flush_postponed_start = 0;
    //省略異常的處理
    //記錄aof當前的大小
    server.aof_current_size += nwritten;
    /**
    * aof的可用buf比較小了,就清空buf
    */
    if ((sdslen(server.aof_buf)+sdsavail(server.aof_buf)) < 4000) {
        sdsclear(server.aof_buf);
    } else {
            sdsfree(server.aof_buf);
        server.aof_buf = sdsempty();
    }
}
user avatar Faith-zhang Avatar _61e9689d548cc Avatar guangmingleiluodetouyingyi_bccdlf Avatar
Favorites 3 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.