Redis RDB 備份測試

  1. 前言
  2. 環境
  3. RDB 檔備份策略
    1. 手動快照
    2. 自動快照
    3. 自動快照測試
  4. 災難異常復原模擬
  5. 參考文件

前言

透過 docker 建置 Redis,並測試 RDB 檔備份

環境

Linux VM = ubuntu-1804-lts
Redis Docker映像檔 = redis:6.0.0

# 先準備 volumn 資料夾 redis、redisdata
mkdir redis && mkdir redisdata

# 創建 docker network
docker network create --driver bridge --subnet 172.18.0.0/24 --gateway 172.18.0.1 redis_network

# 拉取 Redis Image
docker pull redis:6.0.0

RDB 檔備份策略

RDB 快照備份檔是一個二進位置壓縮過的檔案,透過 RDB 檔恢復資料會比 AOF 檔快速
但因快照是對所有內存資料做快照,若操作太過頻繁會對Redis性能造成影響

若以每15分鐘快照一次來例,當服務異常發生時,有可能會損失最近15分鐘內尚未快照到的資料
若不能允許資料丟失的話,則不要用 RDB 檔備份,改用 AOF 備份機制,或者也有 RDB、AOF 混合備份機制

redis.conf 可設定每隔多久時間 對 Redis 內存資料自動快照到硬碟上,也可以手動執行 RDB 檔備份

手動快照

進入 Redis 機器服務內手動操作CMD
redis-cli save => 執行同步操作做 RDB 檔備份,會堵塞當前線程,其他請求無法進入
redis-cli bgsave => 會由子線程做 RDB 檔備份,不會堵塞當前線程

自動快照

可透過 redis.conf 設定間隔時間來自動快照
save 60 10 => 60 秒內 若有 10 個 Key 有異動,觸發 bgsave,將目前內存資料快照成 RDB 檔

自動快照測試

新增 redis.conf (開啟 RDB、關閉 AOF)

vi ./redis/redis.conf
bind 127.0.0.1 172.18.0.2
protected-mode no

# RDB
dbfilename dump.rdb
dir ./
save 60 10

# AOF
appendonly no

建立 redis 容器

docker run --name redis1 \
--network=redis_network \
--ip 172.18.0.2 \
-p 6379:6379 \
-v /home/leozheng0411/redis:/usr/local/etc/redis \
-v /home/leozheng0411/redisdata:/data \
-d redis:6.0.0 \
redis-server /usr/local/etc/redis/redis.conf

測試一下服務是否正常

docker exec -it redis1 redis-cli ping

# 輸出
PONG

目前 redis.conf 是設定 60 秒內 若有 10 個 Key 有異動,則會快照資料到 RDB 檔

程式端以每秒更新一筆Key來測試

internal class Program
{
    static IConnectionMultiplexer conn = ConnectionMultiplexer.Connect(new ConfigurationOptions()
    {
        EndPoints = { "x.x.x.x:6379" },
        AbortOnConnectFail = false
    });

    static void Main(string[] args)
    {
        try
        {
            for (int i = 0; i < 1000; i++)
            {
                conn.GetDatabase().StringSet($"Key{i}", i.ToString());

                Console.WriteLine($"已更新 Key{i} 為 {i}");

                Thread.Sleep(1000);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        Console.ReadKey();
    }
}

確認 dump.rdb 資料修改時間為每一分鐘更新

stat dump.rdb

# 輸出
  File: dump.rdb
  Size: 92              Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d      Inode: 521220      Links: 1
Access: (0644/-rw-r--r--)  Uid: (  999/ UNKNOWN)   Gid: (  999/ UNKNOWN)
Access: 2023-06-16 07:45:49.630866358 +0000
Modify: 2023-06-16 07:45:49.630866358 +0000
Change: 2023-06-16 07:45:49.634866699 +0000
 Birth: -

# 隔一分鐘後再查看
stat dump.rdb

# 輸出
  File: dump.rdb
  Size: 366             Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d      Inode: 521216      Links: 1
Access: (0644/-rw-r--r--)  Uid: (  999/ UNKNOWN)   Gid: (  999/ UNKNOWN)
Access: 2023-06-16 07:46:50.044034851 +0000
Modify: 2023-06-16 07:46:50.044034851 +0000
Change: 2023-06-16 07:46:50.048035193 +0000
 Birth: -

災難異常復原模擬

# 強制關閉服務
docker rm -f redis1

# 重啟服務
docker run --name redis1 \
--network=redis_network \
--ip 172.18.0.2 \
-p 6379:6379 \
-v /home/leozheng0411/redis:/usr/local/etc/redis \
-v /home/leozheng0411/redisdata:/data \
-d redis:6.0.0 \
redis-server /usr/local/etc/redis/redis.conf

# 查看 Log 確認啟動時有載入 RDB 快照檔
docker logs redis1

# 輸出
1:C 16 Jun 2023 08:17:39.285 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 16 Jun 2023 08:17:39.285 # Redis version=6.0.0, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 16 Jun 2023 08:17:39.285 # Configuration loaded
1:M 16 Jun 2023 08:17:39.288 * Running mode=standalone, port=6379.
1:M 16 Jun 2023 08:17:39.288 # Server initialized
1:M 16 Jun 2023 08:17:39.288 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
1:M 16 Jun 2023 08:17:39.288 * Loading RDB produced by version 6.0.0
1:M 16 Jun 2023 08:17:39.288 * RDB age 104 seconds
1:M 16 Jun 2023 08:17:39.288 * RDB memory usage when created 0.85 Mb
1:M 16 Jun 2023 08:17:39.288 * DB loaded from disk: 0.000 seconds
1:M 16 Jun 2023 08:17:39.288 * Ready to accept connections

# 確認資料正常復原
docker exec -it redis1 redis-cli GET Key0

# 輸出
"0"

參考文件

Colin Lin (紫鴛) の 技術分享 - [Redis]-修改Redis Bind IP位置
稀土掘金 Jony_zhang - Redis 数据持久化(RDB/AOF/混合持久化)
知乎 程序员囧辉 - 面试必问的 Redis:RDB、AOF、混合持久化


轉載請註明來源,若有任何錯誤或表達不清楚的地方,歡迎在下方評論區留言,也可以來信至 leozheng0621@gmail.com
如果文章對您有幫助,歡迎斗內(donate),請我喝杯咖啡

斗內💰

×

歡迎斗內

github