您好,登錄后才能下訂單哦!
本篇內容主要講解“Redis在Docker中的數據持久化是什么意思”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis在Docker中的數據持久化是什么意思”吧!
項目Github地址:github/booklet
Redis 提供了兩種不同的持久化方法來將數據存儲到硬盤里面。一種方法叫快照(snapshotting,RDB),它可以將存在于某一時刻的所有數據都寫入硬盤里面。
另一種方法叫只追加文件(append-only file,AOF),它會在執行寫命令時,將被執行的寫命令復制到硬盤里面。
這篇文章梳理了Redis兩種持久化方法的知識點,并通過Docker + Docker-Compose進行環境的模擬,來進行數據的備份與恢復等操作。
至于測試數據,我通過一個python腳本批量錄入三百萬條key-value鍵值對(會消耗719.42M內存,來源于redis-cli info信息),沒有python環境的同學,可以使用我在項目里準備的另一個shell腳本
python腳本代碼:
# -*- coding: UTF-8 -*- # file write.py # author liumapp # github https://github.com/liumapp # email liumapp.com@gmail.com # homepage http://www.liumapp.com # date 2019/9/9 # import redis r = redis.Redis(host="127.0.0.1", port=6379, db=0, password="admin123") print("開始插入三百萬條數據,每10萬條數據提交一次批處理") with r.pipeline(transaction=True) as p: value = 0 while value < 3000000: print("開始插入" + str(value) + "條數據") p.sadd("key" + str(value), "value" + str(value)) value += 1 if (value % 100000) == 0: p.execute()
RDB持久化是通過創建快照來獲得數據副本,即簡單粗暴的直接保存鍵值對數據內容
要啟用RDB(并關閉AOF),我們需要修改Redis的配置文件(./redis_config/redis.conf):
requirepass admin123 save 60 1000 stop-writes-on-bgsave-error no rdbcompression no dbfilename dump.rdb appendonly no appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb dir /data/
上述配置會通過docker-compose的配置,映射到Redis容器中并啟用,具體在下面的實操中介紹
上述配置中與RDB相關的配置如下
save: 多久執行一次自動快照操作
比如設置為 save 60 1000
,那么就表示在60秒之內,如果有1000次寫入的話,Redis就會自動觸發BGSAVE命令
一般來說,我們都會希望Redis可以有一個固定的周期來創建快照,那么可以這樣設置
save 900 1
,意思就是讓Redis服務器每隔900秒,并且至少執行了一次寫入操作后,就觸發BGSAVE指令
stop-writes-on-bgsave-error: 在創建快照失敗后是否仍然繼續執行寫命令
rdbcompression: 是否對快照文件進行壓縮
yes: 開啟,這種情況下,Redis會采用LZF算法對rdb文件進行壓縮
no: 關閉
dbfilename: 快照文件名
dir: 快照文件存放目錄
RDB的觸發條件會比AOF麻煩,大致可以分為以下幾種:
通過redis-cli等客戶端直接發送指令: BGSAVE
BGSAVE指令,會讓Redis調用fork創建一個子進程在后臺運行,子進程將會負責創建快照到磁盤中
在演示案例中,啟動redis的docker容器后,在redis-cli中輸入 BGSAVE
后,能夠在./redis_data目錄下生成一個temp-17.rdb文件(或者其他以rdb結尾的)
通過redis-cli等客戶端直接發送指令:SAVE
SAVE指令**(注意跟配置中的save沒有半毛錢關系)**,會讓Redis主進程直接開始創建快照,但在創建快照的過程中,Redis不會響應其他命令請求
在演示案例中,啟動redis的docker容器后,在redis-cli中輸入 SAVE
后,能夠在./redis_data目錄下生成一個temp-17.rdb文件(或者其他以rdb結尾的)
通過配置項save
進行觸發
具體請參照上文的參數說明
通過SHUTDOWN命令關閉Redis服務器時,Redis會自動觸發一個SAVE指令
通過標準TERM信號kill掉Redis服務時,Redis也會自動觸發一個SAVE指令
通過Redis主從服務器的復制請求
主服務器收到從服務器的復制請求時,會觸發一次BGSAVE指令(當且僅當主服務器沒有子進程在執行BGSAVE)
通過docker-compose啟動Redis容器
docker-compose.yml配置如下
version: "2" services: redis: image: 'redis:3.2.11' restart: always hostname: redis container_name: redis ports: - '6379:6379' command: redis-server /usr/local/etc/redis/redis.conf volumes: - ./redis_config/redis.conf:/usr/local/etc/redis/redis.conf - ./redis_data/:/data/
我將Docker容器中的redis服務所產生的備份文件,映射在宿主機的./redis_data目錄下
修改redis配置文件,使AOF生效,并關閉RDB
這里將上面的redis.conf內容復制替換到./redis_config/redis.conf文件中即可
啟動redis服務,并觀察redis_data目錄下是否有dump.rdb文件生成,有生成,則證明備份成功
數據恢復的話,我們不需要做其他操作,只要確保該dump.rdb存在,redis便會自動去讀取其中的數據
AOF持久化會將被執行的寫命令寫到AOF文件的末尾,以此來記錄數據發生的變化。因此,Redis 只要從頭到尾重新執行一次AOF 文件包含的所有寫命令,就可以恢復AOF文件所記錄的數據集。
要啟用AOF(并關閉RDB),我們需要修改Redis的配置文件(./redis_config/redis.conf)
requirepass admin123 #save 60 1000 stop-writes-on-bgsave-error no rdbcompression no dbfilename dump.rdb appendonly yes appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb dir /data/
上述配置會通過docker-compose的配置,映射到Redis容器中并啟用,具體在下面的實操中介紹
上述配置中與AOF相關的配置如下
appendonly: 是否啟用AOF
yes: 啟用AOF
no: 關閉AOF
appendfsync: 啟用AOF后的數據同步頻率
alaways: 每個Redis寫命令都要同步寫入硬盤。這樣做會嚴重降低Redis 的速度 (不建議)
everysec: 每秒執行一次同步,顯式地將多個寫命令同步到硬盤 (推薦,對性能沒有太大影響)
no: 讓操作系統來決定應該何時進行同步。(不建議)
Redis將不對AOF文件執行任何顯式的同步操作,如果用戶的硬盤處理寫入操作的速度不夠快的話,那么當緩沖區被等待寫入硬盤的數據填滿時,Redis的寫入操作將被阻塞,并導致Redis處理命令請求的速度變慢
no-appendfsync-on-rewrite:在對AOF進行壓縮(也被稱為重寫機制)的時候能否執行同步操作
yes: 不允許
no: 允許
auto-aof-rewrite-percentage:多久執行一次AOF壓縮,單位是百分比
auto-aof-rewrite-min-size:需要壓縮的文件達到多少時開始執行
auto-aof-rewrite-percentage跟auto-aof-rewrite-min-size需要配套使用,比如當我們設置auto-aof-rewrite-percentage為100,設置auto-aof-rewrite-min-size為64mb時
redis會在AOF產生的文件比64M大時,并且AOF文件的體積比上一次重寫之后至少增大了一倍(100%)才執行BGREWRITEAOF重寫命令
如果覺得AOF重寫執行得過于頻繁,我們可以把auto-aof-rewrite-percentage設置100以上,比如200,就可以降低重寫頻率
這里可以參考Redis的官方手冊,寫的非常清楚:https://redislabs.com/ebook/part-2-core-concepts/chapter-4-keeping-data-safe-and-ensuring-performance/4-1-persistence-options/4-1-3-rewritingcompacting-append-only-files/
dir:備份文件存放目錄
直接根據appendfsync的設置進行觸發
在上面的配置中,已經通過auto-aof-rewrite-percentage和auto-aof-rewrite-min-size兩個參數,簡單介紹了Redis的BGREWRITEAOF重寫命令
那么,為什么要用AOF重寫機制呢?
因為AOF持久化是通過保存被執行的寫命令來記錄Redis數據庫狀態的,所以AOF文件隨著時系統運行會越來越大
而過于龐大的AOF文件會產生以下不良影響
影響Redis服務性能;
占用服務器磁盤空間;
AOF還原數據狀態的時間增加;
所以Redis提供了一套AOF重寫機制,通過創建一個新的AOF文件來替換掉舊的AOF文件,這兩個文件所保存的數據狀態是相同的,但新的AOF文件不會包含冗余命令,所以體積會較舊AOF文件小很多
但在實際的使用中,我們需要非常小心,不能讓Redis的重寫命令執行的過于頻繁 (注意:auto-aof-rewrite-percentage的單位是百分比,值越大,重寫頻率越低,也千萬別出現0這種值) 因為BGREWRITEAOF的工作原理和BGSAVE創建快照的工作原理非常相似:Redis會創建一個子進程,然后由子進程負責對AOF文件進行重寫,因為AOF文件重寫也需要用到子進程,所以快照持久化因為創建子進程而導致的性能問題和內存占用問題,在AOF持久化中也同樣存在
更具體的AOF重寫工作原理:
Fork主進程,產生一個帶有數據副本的子進程在后臺執行
Redis這樣設計可以確保在重寫過程中,不影響Redis主進程的服務正常運行,同時通過處理數據副本來保證數據的安全性**(注意,重寫是針對數據副本來進行處理,而不是針對舊的AOF文件)**
子進程Fork完成后,Redis將啟用AOF重寫緩沖區,此刻開始,新的寫入命令會被寫入AOF緩沖區和AOF重寫緩沖區中
這里啟用的AOF重寫緩沖區可以確保:在執行AOF重寫的過程中,任何新的寫入命令產生,都不會導致新AOF文件的數據狀態與Redis數據庫狀態不一致
子進程完成對AOF文件的重寫后,通知父進程
父進程收到通知后,將AOF重寫緩沖區的內容全部寫入新的AOF文件中
父進程將新的AOF文件替換掉舊的AOF文件**(注意,這一步會造成Redis阻塞,但問題不大)**
BGREWRITEAOF的工作流程圖如下所示**(繪圖源代碼在項目的./articles/bgrewriteaof.puml文件下)**:
通過docker-compose啟動Redis容器
docker-compose.yml配置如下
version: "2" services: redis: image: 'redis:3.2.11' restart: always hostname: redis container_name: redis ports: - '6379:6379' command: redis-server /usr/local/etc/redis/redis.conf volumes: - ./redis_config/redis.conf:/usr/local/etc/redis/redis.conf - ./redis_data/:/data/
我將Docker容器中的redis服務所產生的備份文件,映射在宿主機的./redis_data目錄下
修改redis配置文件,使AOF生效,并關閉RDB
這里將上面的redis.conf內容復制替換到./redis_config/redis.conf文件中即可
啟動redis服務,并觀察redis_data目錄下是否有appendonly.aof文件生成,有生成,則證明備份成功
另外我們可以發現,3百萬條數據(700M)的備份文件,其實際占用磁盤空間約為170M,這便是Redis重寫機制強大的地方
數據恢復的話,我們不需要做其他操作,只要確保該appendonly.aof存在,redis便會自動去讀取其中的數據
RDB跟AOF都可以確保Redis的數據持久化,但各有特點
RDB因為有默認的指令SAVE跟BGSAVE支持,所以比較適合對數據庫做全量備份,比如每天凌晨3點開始執行一次BGSAVE
而AOF因為是保存的寫命令,因而更適合實時備份,事實上現在企業應用也基本都是采用的AOF
但光是使用了RDB或AOF、甚至兩個一起用,也還是不夠的
對于一個需要支持可擴展的分布式平臺而言,我們還需要提供一套復制備份機制,允許在一個周期內,自動將AOF或者RDB的文件備份到不同的服務器下
這種情況下,我們就需要使用Redis的復制并生成數據副本功能,具體內容我會在下一篇文章進行實操記錄
到此,相信大家對“Redis在Docker中的數據持久化是什么意思”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。