石頭剪刀布
redis持久化
Redis是一種記憶體型資料庫,一旦伺服器程序退出,資料庫的資料就會丟失,為了解決這個問題,Redis提供了兩種持久化的方案,將記憶體中的資料儲存到磁碟中,避免資料的丟失,rdb
與aof
。
RDB持久化
redis提供了RDB持久化的功能,這個功能可以將redis在記憶體中的的狀態儲存到硬碟中,它可以手動執行。也可以再redis.conf中配置,定期執行。RDB持久化產生的RDB檔案是一個經過壓縮的二進位制檔案,這個檔案被儲存在硬碟中,redis可以通過這個檔案還原資料庫當時的狀態。
優點:速度快,適合做備份,主從複製就是基於RDB持久化功能實現
缺點:耗時,耗效能:不可控,可能會丟失資料
觸發機制-主要三種方式
''' save(同步) 1 客戶端執行save命令----》redis服務端----》同步建立RDB二進位制檔案 2 會造成redis的阻塞(資料量非常大的時候) 3 檔案策略:如果老的RDB存在,會替換老的 4 複雜度 o(n) ''' ''' bgsave(非同步,Backgroud saving started) 1 客戶端執行bgsave命令----》redis服務端----》非同步建立RDB二進位制檔案(fork函式生成一個子程序(fork會阻塞reids),執行createRDB,執行成功,返回給reids訊息) 2 此時訪問redis,會正常響應客戶端 3 檔案策略:跟save相同,如果老的RDB存在,會替換老的 4 複雜度 o(n) ''' ''' 自動(通過配置) 配置 seconds changes save 900 1 save 300 10 save 60 10000 如果60s中改變了1w條資料,自動生成rdb 如果300s中改變了10條資料,自動生成rdb 如果900s中改變了1條資料,自動生成rdb 以上三條符合任意一條,就自動生成rdb,內部使用bgsave ''' #配置: save 900 1 #配置一條 save 300 10 #配置一條 save 60 10000 #配置一條 dbfilename dump.rdb #rdb檔案的名字,預設為dump.rdb dir ./ #rdb檔案存在當前目錄 stop-writes-on-bgsave-error yes #如果bgsave出現錯誤,是否停止寫入,預設為yes rdbcompression yes #採用壓縮格式 rdbchecksum yes #是否對rdb檔案進行校驗和檢驗 #最佳配置 save 900 1 save 300 10 save 60 10000 dbfilename dump-${port}.rdb #以埠號作為檔名,可能一臺機器上很多reids,不會亂 dir /bigdiskpath #儲存路徑放到一個大硬碟位置目錄 stop-writes-on-bgsave-error yes #出現錯誤停止 rdbcompression yes #壓縮 rdbchecksum yes #校驗
觸發機制-不容忽略的方式
1 全量複製 #沒有執行save和bgsave沒有新增rdb策略,還會生成rdb檔案,如果開啟主從複製,主會自動生成rdb
2 debug reload #debug級別的重啟,不會將記憶體中的資料清空
3 shutdown save#關閉會出發rdb的生成
RDB實踐
- 啟動redis服務端,準備配置檔案
daemonize yes port 6379 logfile /data/6379/redis.log dir /data/6379 #定義持久化檔案儲存位置 dbfilename dbmp.rdb #rdb持久化檔案 bind 10.0.0.10 127.0.0.1 #redis繫結地址 requirepass redhat #redis登入密碼 save 900 1 #rdb機制 每900秒 有1個修改記錄 save 300 10 #每300秒 10個修改記錄 save 60 10000 #每60秒內 10000修改記錄
-
啟動redis服務端
-
登入redis設定一個key
redis-cli -a redhat
-
此時檢查目錄,/data/6379底下沒有dbmp.rdb檔案
-
通過save觸發持久化,將資料寫入RDB檔案
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> save
OK
AOF
記錄伺服器執行的所有變更操作命令(例如set del等),並在伺服器啟動時,通過重新執行這些命令來還原資料集
AOF 檔案中的命令全部以redis協議的格式儲存,新命令追加到檔案末尾。
優點:最大程式保證資料不丟
缺點:日誌記錄非常大
AOF的三種策略
AOF持久化配置,兩條引數
appendonly yes
appendfsync always 總是修改類的操作
everysec 每秒做一次持久化
no 依賴於系統自帶的快取大小機制
日誌不是直接寫到硬碟上,而是先放在緩衝區,緩衝區根據一些策略,寫到硬碟上
always:redis--》寫命令重新整理的緩衝區---》每條命令fsync到硬碟---》AOF檔案
everysec(預設值):redis——》寫命令重新整理的緩衝區---》每秒把緩衝區fsync到硬碟--》AOF檔案
no:redis——》寫命令重新整理的緩衝區---》作業系統決定,緩衝區fsync到硬碟--》AOF檔案
命令 | always | everysec | no |
---|---|---|---|
優點 | 不丟失資料 | 每秒一次fsync,丟失1秒資料 | 不用管 |
缺點 | IO開銷大,一般的sata盤只有幾百TPS | 丟1秒資料 | 不可控 |
案例
1.準備aof配置檔案 redis.conf
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379
dbfilename dbmp.rdb
requirepass redhat
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
2.啟動redis服務
redis-server /etc/redis.conf
3.檢查redis資料目錄/data/6379/是否產生了aof檔案
[root@web02 6379]# ls
appendonly.aof dbmp.rdb redis.log
4.登入redis-cli,寫入資料,實時檢查aof檔案資訊
[root@web02 6379]# tail -f appendonly.aof
5.設定新key,檢查aof資訊,然後關閉redis,檢查資料是否持久化
redis-cli -a redhat shutdown
redis-server /etc/redis.conf
redis-cli -a redhat
AOF 重寫
隨著命令的逐步寫入,併發量的變大, AOF檔案會越來越大,通過AOF重寫來解決該問題
原生AOF | AOF重寫 |
---|---|
set hello world set hello java set hello hehe incr counter incr counter rpush mylist a rpush mylist b rpush mylist c 過期資料 |
set hello hehe set counter 2 rpush mylist a b c |
本質就是把過期的,無用的,重複的,可以優化的命令,來優化
這樣可以減少磁碟佔用量,加速恢復速度
實現方式
bgrewriteaof:
客戶端向服務端傳送bgrewriteaof命令,服務端會起一個fork程序,完成AOF重寫
AOF重寫配置:
配置名 | 含義 |
---|---|
auto-aof-rewrite-min-size | AOF檔案重寫需要尺寸 |
auto-aof-rewrite-percentage | AOF檔案增長率 |
統計名 | 含義 |
---|---|
aof_current_size | AOF當前尺寸(單位:位元組) |
aof_base_size | AOF上次啟動和重寫的尺寸(單位:位元組) |
自動觸發時機(兩個條件同時滿足):
aof_current_size>auto-aof-rewrite-min-size:當前尺寸大於重寫需要尺寸
(aof_current_size-aof_base_size)/aof_base_size>auto-aof-rewrite-percentage:(增長率)當前尺寸減去上次重寫的尺寸,除以上次重寫的尺寸如果大於配置中的增長率
重寫流程
配置
appendonly yes #將該選項設定為yes,開啟
appendfilename "appendonly-${port}.aof" #檔案儲存的名字
appendfsync everysec #採用第二種策略
dir /bigdiskpath #存放的路徑
no-appendfsync-on-rewrite yes #在aof重寫的時候,是否要做aof的append操作,因為aof重寫消耗效能,磁碟消耗,正常aof寫磁碟有一定的衝突,這段期間的資料,允許丟失
RDB和AOF的選擇
rdb:基於快照的持久化,速度更快,一般用作備份,主從複製也是依賴於rdb持久化功能
aof:以追加的方式記錄redis操作日誌的檔案。可以最大程度的保證redis資料安全,類似於mysql的binlog
rdb和aof的比較
命令 | rdb | aof |
---|---|---|
啟動優先順序 | 低 | 高(掛掉重啟,會載入aof的資料) |
體積 | 小 | 大 |
恢復速度 | 快 | 慢 |
資料安全性 | 丟資料 | 根據策略決定 |
輕重 | 重 | 輕 |
rdb最佳策略
rdb關掉,主從操作時
集中管理:按天,按小時備份資料
主從配置,從節點開啟
aof最佳策略
開:快取和儲存,大部分情況都開啟,
aof重寫集中管理
everysec:通過每秒重新整理的策略
RDB持久化切換AOF持久化
注意:確保redis版本在2.2以上
[root@pyyuc /data 22:23:30]#redis-server -v
Redis server v=4.0.10 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=64cb6afcf41664c
本文在redis4.0中,通過config set命令,達到不重啟redis服務,從RDB持久化切換為AOF
- redis.conf服務端配置檔案
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379
dbfilename dbmp.rdb
save 900 1 #rdb機制 每900秒 有1個修改記錄
save 300 10 #每300秒 10個修改記錄
save 60 10000 #每60秒內 10000修改記錄
- 啟動redis服務端
redis-server redis.conf
- 登入redis-cli插入資料,手動持久化
127.0.0.1:6379> set name chaoge
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> set addr shahe
OK
127.0.0.1:6379> save
OK
- 檢查RDB檔案
[root@pyyuc /data 22:34:16]#ls 6379/
dbmp.rdb redis.log
- 備份這個rdb檔案,保證資料安全
[root@pyyuc /data/6379 22:35:38]#cp dbmp.rdb /opt/
- 執行命令,開啟AOF持久化
127.0.0.1:6379> CONFIG set appendonly yes #開啟AOF功能
OK
127.0.0.1:6379> CONFIG SET save "" #關閉RDB功能
OK
- 確保資料庫的key數量正確
127.0.0.1:6379> keys *
1) "addr"
2) "age"
3) "name"
- 確保插入新的key,AOF檔案會記錄
127.0.0.1:6379> set title golang
OK
此時RDB已經正確切換AOF,注意還得修改redis.conf新增AOF設定,不然重啟後,通過config set的配置將丟失