本篇內(nèi)容主要講解“redis在Docker中的數(shù)據(jù)持久化是什么意思”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis在Docker中的數(shù)據(jù)持久化是什么意思”吧!
創(chuàng)新互聯(lián)公司長期為近千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為遂溪企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站建設、外貿(mào)營銷網(wǎng)站建設,遂溪網(wǎng)站改版等技術(shù)服務。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
項目Github地址:github/booklet
Redis 提供了兩種不同的持久化方法來將數(shù)據(jù)存儲到硬盤里面。一種方法叫快照(snapshotting,RDB),它可以將存在于某一時刻的所有數(shù)據(jù)都寫入硬盤里面。
另一種方法叫只追加文件(append-only file,AOF),它會在執(zhí)行寫命令時,將被執(zhí)行的寫命令復制到硬盤里面。
這篇文章梳理了Redis兩種持久化方法的知識點,并通過Docker + Docker-Compose進行環(huán)境的模擬,來進行數(shù)據(jù)的備份與恢復等操作。
至于測試數(shù)據(jù),我通過一個python腳本批量錄入三百萬條key-value鍵值對(會消耗719.42M內(nèi)存,來源于redis-cli info信息),沒有python環(huán)境的同學,可以使用我在項目里準備的另一個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("開始插入三百萬條數(shù)據(jù),每10萬條數(shù)據(jù)提交一次批處理") with r.pipeline(transaction=True) as p: value = 0 while value < 3000000: print("開始插入" + str(value) + "條數(shù)據(jù)") p.sadd("key" + str(value), "value" + str(value)) value += 1 if (value % 100000) == 0: p.execute()
RDB持久化是通過創(chuàng)建快照來獲得數(shù)據(jù)副本,即簡單粗暴的直接保存鍵值對數(shù)據(jù)內(nèi)容
要啟用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: 多久執(zhí)行一次自動快照操作
比如設置為 save 60 1000
,那么就表示在60秒之內(nèi),如果有1000次寫入的話,Redis就會自動觸發(fā)BGSAVE命令
一般來說,我們都會希望Redis可以有一個固定的周期來創(chuàng)建快照,那么可以這樣設置
save 900 1
,意思就是讓Redis服務器每隔900秒,并且至少執(zhí)行了一次寫入操作后,就觸發(fā)BGSAVE指令
stop-writes-on-bgsave-error: 在創(chuàng)建快照失敗后是否仍然繼續(xù)執(zhí)行寫命令
rdbcompression: 是否對快照文件進行壓縮
yes: 開啟,這種情況下,Redis會采用LZF算法對rdb文件進行壓縮
no: 關閉
dbfilename: 快照文件名
dir: 快照文件存放目錄
RDB的觸發(fā)條件會比AOF麻煩,大致可以分為以下幾種:
通過redis-cli等客戶端直接發(fā)送指令: BGSAVE
BGSAVE指令,會讓Redis調(diào)用fork創(chuàng)建一個子進程在后臺運行,子進程將會負責創(chuàng)建快照到磁盤中
在演示案例中,啟動redis的docker容器后,在redis-cli中輸入 BGSAVE
后,能夠在./redis_data目錄下生成一個temp-17.rdb文件(或者其他以rdb結(jié)尾的)
通過redis-cli等客戶端直接發(fā)送指令:SAVE
SAVE指令**(注意跟配置中的save沒有半毛錢關系)**,會讓Redis主進程直接開始創(chuàng)建快照,但在創(chuàng)建快照的過程中,Redis不會響應其他命令請求
在演示案例中,啟動redis的docker容器后,在redis-cli中輸入 SAVE
后,能夠在./redis_data目錄下生成一個temp-17.rdb文件(或者其他以rdb結(jié)尾的)
通過配置項save
進行觸發(fā)
具體請參照上文的參數(shù)說明
通過SHUTDOWN命令關閉Redis服務器時,Redis會自動觸發(fā)一個SAVE指令
通過標準TERM信號kill掉Redis服務時,Redis也會自動觸發(fā)一個SAVE指令
通過Redis主從服務器的復制請求
主服務器收到從服務器的復制請求時,會觸發(fā)一次BGSAVE指令(當且僅當主服務器沒有子進程在執(zhí)行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服務所產(chǎn)生的備份文件,映射在宿主機的./redis_data目錄下
修改redis配置文件,使AOF生效,并關閉RDB
這里將上面的redis.conf內(nèi)容復制替換到./redis_config/redis.conf文件中即可
啟動redis服務,并觀察redis_data目錄下是否有dump.rdb文件生成,有生成,則證明備份成功
數(shù)據(jù)恢復的話,我們不需要做其他操作,只要確保該dump.rdb存在,redis便會自動去讀取其中的數(shù)據(jù)
AOF持久化會將被執(zhí)行的寫命令寫到AOF文件的末尾,以此來記錄數(shù)據(jù)發(fā)生的變化。因此,Redis 只要從頭到尾重新執(zhí)行一次AOF 文件包含的所有寫命令,就可以恢復AOF文件所記錄的數(shù)據(jù)集。
要啟用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后的數(shù)據(jù)同步頻率
alaways: 每個Redis寫命令都要同步寫入硬盤。這樣做會嚴重降低Redis 的速度 (不建議)
everysec: 每秒執(zhí)行一次同步,顯式地將多個寫命令同步到硬盤 (推薦,對性能沒有太大影響)
no: 讓操作系統(tǒng)來決定應該何時進行同步。(不建議)
Redis將不對AOF文件執(zhí)行任何顯式的同步操作,如果用戶的硬盤處理寫入操作的速度不夠快的話,那么當緩沖區(qū)被等待寫入硬盤的數(shù)據(jù)填滿時,Redis的寫入操作將被阻塞,并導致Redis處理命令請求的速度變慢
no-appendfsync-on-rewrite:在對AOF進行壓縮(也被稱為重寫機制)的時候能否執(zhí)行同步操作
yes: 不允許
no: 允許
auto-aof-rewrite-percentage:多久執(zhí)行一次AOF壓縮,單位是百分比
auto-aof-rewrite-min-size:需要壓縮的文件達到多少時開始執(zhí)行
auto-aof-rewrite-percentage跟auto-aof-rewrite-min-size需要配套使用,比如當我們設置auto-aof-rewrite-percentage為100,設置auto-aof-rewrite-min-size為64mb時
redis會在AOF產(chǎn)生的文件比64M大時,并且AOF文件的體積比上一次重寫之后至少增大了一倍(100%)才執(zhí)行BGREWRITEAOF重寫命令
如果覺得AOF重寫執(zhí)行得過于頻繁,我們可以把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:備份文件存放目錄
直接根據(jù)appendfsync的設置進行觸發(fā)
在上面的配置中,已經(jīng)通過auto-aof-rewrite-percentage和auto-aof-rewrite-min-size兩個參數(shù),簡單介紹了Redis的BGREWRITEAOF重寫命令
那么,為什么要用AOF重寫機制呢?
因為AOF持久化是通過保存被執(zhí)行的寫命令來記錄Redis數(shù)據(jù)庫狀態(tài)的,所以AOF文件隨著時系統(tǒng)運行會越來越大
而過于龐大的AOF文件會產(chǎn)生以下不良影響
影響Redis服務性能;
占用服務器磁盤空間;
AOF還原數(shù)據(jù)狀態(tài)的時間增加;
所以Redis提供了一套AOF重寫機制,通過創(chuàng)建一個新的AOF文件來替換掉舊的AOF文件,這兩個文件所保存的數(shù)據(jù)狀態(tài)是相同的,但新的AOF文件不會包含冗余命令,所以體積會較舊AOF文件小很多
但在實際的使用中,我們需要非常小心,不能讓Redis的重寫命令執(zhí)行的過于頻繁 (注意:auto-aof-rewrite-percentage的單位是百分比,值越大,重寫頻率越低,也千萬別出現(xiàn)0這種值)因為BGREWRITEAOF的工作原理和BGSAVE創(chuàng)建快照的工作原理非常相似:Redis會創(chuàng)建一個子進程,然后由子進程負責對AOF文件進行重寫,因為AOF文件重寫也需要用到子進程,所以快照持久化因為創(chuàng)建子進程而導致的性能問題和內(nèi)存占用問題,在AOF持久化中也同樣存在
更具體的AOF重寫工作原理:
Fork主進程,產(chǎn)生一個帶有數(shù)據(jù)副本的子進程在后臺執(zhí)行
Redis這樣設計可以確保在重寫過程中,不影響Redis主進程的服務正常運行,同時通過處理數(shù)據(jù)副本來保證數(shù)據(jù)的安全性**(注意,重寫是針對數(shù)據(jù)副本來進行處理,而不是針對舊的AOF文件)**
子進程Fork完成后,Redis將啟用AOF重寫緩沖區(qū),此刻開始,新的寫入命令會被寫入AOF緩沖區(qū)和AOF重寫緩沖區(qū)中
這里啟用的AOF重寫緩沖區(qū)可以確保:在執(zhí)行AOF重寫的過程中,任何新的寫入命令產(chǎn)生,都不會導致新AOF文件的數(shù)據(jù)狀態(tài)與Redis數(shù)據(jù)庫狀態(tài)不一致
子進程完成對AOF文件的重寫后,通知父進程
父進程收到通知后,將AOF重寫緩沖區(qū)的內(nèi)容全部寫入新的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服務所產(chǎn)生的備份文件,映射在宿主機的./redis_data目錄下
修改redis配置文件,使AOF生效,并關閉RDB
這里將上面的redis.conf內(nèi)容復制替換到./redis_config/redis.conf文件中即可
啟動redis服務,并觀察redis_data目錄下是否有appendonly.aof文件生成,有生成,則證明備份成功
另外我們可以發(fā)現(xiàn),3百萬條數(shù)據(jù)(700M)的備份文件,其實際占用磁盤空間約為170M,這便是Redis重寫機制強大的地方
數(shù)據(jù)恢復的話,我們不需要做其他操作,只要確保該appendonly.aof存在,redis便會自動去讀取其中的數(shù)據(jù)
RDB跟AOF都可以確保Redis的數(shù)據(jù)持久化,但各有特點
RDB因為有默認的指令SAVE跟BGSAVE支持,所以比較適合對數(shù)據(jù)庫做全量備份,比如每天凌晨3點開始執(zhí)行一次BGSAVE
而AOF因為是保存的寫命令,因而更適合實時備份,事實上現(xiàn)在企業(yè)應用也基本都是采用的AOF
但光是使用了RDB或AOF、甚至兩個一起用,也還是不夠的
對于一個需要支持可擴展的分布式平臺而言,我們還需要提供一套復制備份機制,允許在一個周期內(nèi),自動將AOF或者RDB的文件備份到不同的服務器下
這種情況下,我們就需要使用Redis的復制并生成數(shù)據(jù)副本功能,具體內(nèi)容我會在下一篇文章進行實操記錄
到此,相信大家對“Redis在Docker中的數(shù)據(jù)持久化是什么意思”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!
本文題目:Redis在Docker中的數(shù)據(jù)持久化是什么意思
當前地址:http://chinadenli.net/article18/iejcdp.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、App開發(fā)、移動網(wǎng)站建設、網(wǎng)站建設、企業(yè)網(wǎng)站制作、網(wǎng)站導航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)