Redis bgsave的使用小結(jié)
什么是bgsave?
BGSAVE 是 Redis 用于生成 RDB 持久化文件的核心操作,它的本質(zhì)是:
- 主線程 fork 一個(gè)子進(jìn)程,子進(jìn)程會(huì)獨(dú)立遍歷 Redis 內(nèi)存數(shù)據(jù),將其序列化并寫入磁盤(生成.rdb 文件);
- 整個(gè)過程中,主線程完全不參與數(shù)據(jù)遍歷,仍能正常處理業(yè)務(wù)請(qǐng)求。
什么時(shí)候會(huì)用到bgsave?
定期備份
定期備份策略
# 生產(chǎn)環(huán)境典型備份計(jì)劃 0 2 * * * /usr/local/bin/redis-backup.sh # 每天凌晨2點(diǎn)執(zhí)行 # 備份腳本示例 #!/bin/bash redis-cli BGSAVE wait_for_bgsave_complete cp /var/lib/redis/dump.rdb /backup/redis/dump-$(date +%Y%m%d).rdb
適用場(chǎng)景:
- 數(shù)據(jù)庫(kù)每日/每周全量備份
- 災(zāi)備恢復(fù)準(zhǔn)備
- 數(shù)據(jù)遷移前的快照
數(shù)據(jù)遷移
源服務(wù)器: redis-cli BGSAVE scp dump.rdb new-server:/path/to/redis/ 目標(biāo)服務(wù)器: systemctl stop redis cp dump.rdb /var/lib/redis/ systemctl start redis
故障排查與數(shù)據(jù)分析
# 使用RDB文件進(jìn)行分析 redis-cli BGSAVE # 等待完成后使用工具分析 rdb --command memory dump.rdb --bytes 128 --largest 10 // 大key分析
分析場(chǎng)景:
- 查找內(nèi)存泄漏原因
- 分析大Key分布
- 優(yōu)化數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
AOF重寫機(jī)制
# AOF重寫內(nèi)部流程
1. redis-cli BGREWRITEAOF
2. Redis執(zhí)行fork()創(chuàng)建子進(jìn)程
3. 子進(jìn)程基于當(dāng)前數(shù)據(jù)生成新的AOF文件
4. 實(shí)際上就是執(zhí)行了一次BGSAVE+命令回放
** AOF重寫 = BGSAVE + 命令回放**
主從復(fù)制初始化
# 新從節(jié)點(diǎn)加入集群時(shí)
主節(jié)點(diǎn)流程:
1. 接收到SLAVEOF命令
2. 執(zhí)行BGSAVE創(chuàng)建RDB快照
3. 將RDB文件發(fā)送給從節(jié)點(diǎn)
4. 從節(jié)點(diǎn)加載RDB完成初始化
bgsave會(huì)存在哪些問題?
GSAVE 會(huì)導(dǎo)致 “業(yè)務(wù)抖動(dòng)” 和 “實(shí)例抖動(dòng)”。
BGSAVE 雖然不阻塞主線程,但會(huì)占用大量系統(tǒng)資源(CPU、內(nèi)存、磁盤 IO) ,這些資源搶占會(huì)間接影響 Redis 服務(wù)和依賴它的業(yè)務(wù),具體體現(xiàn)在三個(gè)方面:
1. CPU 搶占
CPU 搶占:導(dǎo)致業(yè)務(wù)請(qǐng)求響應(yīng)變慢(業(yè)務(wù)抖動(dòng))
BGSAVE 子進(jìn)程的核心工作是 “遍歷內(nèi)存數(shù)據(jù) + 序列化 + 寫磁盤”,這三個(gè)步驟都需要消耗 CPU。比如:子進(jìn)程要把一個(gè) 1GB 的哈希表序列化到磁盤,需要持續(xù)占用 CPU 進(jìn)行數(shù)據(jù)結(jié)構(gòu)解析和二進(jìn)制編碼 —— 如果單機(jī) CPU 是 4 核,子進(jìn)程可能會(huì)占用 1 核的 80% 以上資源。
而 Redis 主線程(處理業(yè)務(wù)請(qǐng)求)也需要 CPU:比如執(zhí)行HGET user:100 name需要解析 key、查找哈希表、返回結(jié)果。當(dāng)子進(jìn)程搶占大量 CPU 時(shí),主線程能拿到的 “CPU 時(shí)間片” 會(huì)減少,直接導(dǎo)致:
- 正常情況下 1
2ms 就能響應(yīng)的請(qǐng)求,延遲可能飆升到 1020ms; - 高并發(fā)場(chǎng)景(如每秒 10 萬請(qǐng)求)下,部分請(qǐng)求會(huì)因超時(shí)被業(yè)務(wù)端重試,甚至返回失敗 —— 這就是 “業(yè)務(wù)請(qǐng)求抖動(dòng)”。
2. 內(nèi)存復(fù)制
內(nèi)存復(fù)制:可能觸發(fā) “內(nèi)存交換”(Redis 實(shí)例抖動(dòng))
BGSAVE 子進(jìn)程創(chuàng)建時(shí),會(huì)用到 Linux 的寫時(shí)復(fù)制(Copy-On-Write,COW) 機(jī)制,這個(gè)機(jī)制是為了 “節(jié)省內(nèi)存”,但也可能引發(fā)新問題。
COW 的邏輯是:
- 子進(jìn)程剛創(chuàng)建時(shí),不直接拷貝主線程的內(nèi)存數(shù)據(jù),而是和主線程共享同一塊內(nèi)存;
- 只有當(dāng)主線程修改某塊內(nèi)存(比如執(zhí)行
SET key new_val)時(shí),系統(tǒng)才會(huì) “復(fù)制” 這塊內(nèi)存的舊版本給子進(jìn)程(確保子進(jìn)程能拿到修改前的數(shù)據(jù),生成一致快照)。
如果 Redis 內(nèi)存占用很高(比如 16GB 內(nèi)存用了 14GB),且 BGSAVE 期間有大量寫操作(比如每秒 1 萬次SET),會(huì)發(fā)生什么?
- 大量?jī)?nèi)存被 “復(fù)制”:主線程每修改一塊內(nèi)存,就會(huì)生成一份副本,導(dǎo)致系統(tǒng)可用內(nèi)存驟降;
- 觸發(fā) Swap(內(nèi)存交換):當(dāng)可用內(nèi)存不足時(shí),操作系統(tǒng)會(huì)把部分內(nèi)存數(shù)據(jù)寫到磁盤的 “交換分區(qū)”(Swap 分區(qū)),而磁盤 IO 速度比內(nèi)存慢 1000 倍以上;
- Redis 實(shí)例卡頓:主線程要讀取被交換到磁盤的數(shù)據(jù)時(shí),需要等待磁盤 IO,響應(yīng)延遲會(huì)從毫秒級(jí)變成百毫秒級(jí),甚至出現(xiàn) “實(shí)例短暫無響應(yīng)”—— 這就是 “Redis 服務(wù)實(shí)例抖動(dòng)”。
3. 磁盤 IO 搶占
磁盤 IO 搶占:拖慢 AOF 持久化(雪上加霜)
如果你的 Redis 同時(shí)開啟了 AOF 持久化(AppendOnly yes,生產(chǎn)環(huán)境大多會(huì)開),BGSAVE 還會(huì)和 AOF 搶占磁盤 IO 資源。
AOF 的邏輯是:主線程執(zhí)行修改命令后,會(huì)把命令寫入 AOF 緩沖區(qū),再由后臺(tái)線程定期將緩沖區(qū)內(nèi)容刷到磁盤(默認(rèn)每秒一次,appendfsync everysec)。
而 BGSAVE 子進(jìn)程需要把 16GB 的內(nèi)存數(shù)據(jù)寫入磁盤(生成.rdb 文件),會(huì)占用大量磁盤寫 IO—— 比如原本 AOF 刷盤每秒只需要 10MB IO,BGSAVE 執(zhí)行時(shí)磁盤寫 IO 可能飆升到 100MB/s,導(dǎo)致:
- AOF 刷盤延遲:原本 1ms 能完成的刷盤,變成 20ms;
- 主線程等待刷盤:如果 AOF 緩沖區(qū)滿了,主線程會(huì)暫時(shí)阻塞等待刷盤完成,進(jìn)一步加劇業(yè)務(wù)請(qǐng)求延遲。
到此這篇關(guān)于Redis bgsave的使用小結(jié)的文章就介紹到這了,更多相關(guān)Redis bgsave使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)讀寫分離詳解
Redis的主從架構(gòu),能幫助我們實(shí)現(xiàn)讀多,寫少的情況,下面這篇文章主要給大家介紹了關(guān)于Redis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
詳解Redis單線程架構(gòu)的優(yōu)勢(shì)與不足
很多人都遇到過這么一道面試題:Redis是單線程還是多線程?這個(gè)問題既簡(jiǎn)單又復(fù)雜,說他簡(jiǎn)單是因?yàn)榇蠖鄶?shù)人都知道Redis是單線程,說復(fù)雜是因?yàn)檫@個(gè)答案其實(shí)并不準(zhǔn)確,本文就給大家講講Redis單線程架構(gòu)的優(yōu)勢(shì)與不足,需要的朋友可以參考下2024-02-02
Redis?生成分布式業(yè)務(wù)單號(hào)的實(shí)現(xiàn)
在業(yè)務(wù)系統(tǒng)中很多場(chǎng)景下需要生成不重復(fù)的ID,本文主要介紹了Redis生成分布式業(yè)務(wù)單號(hào)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
Windows操作系統(tǒng)下Redis服務(wù)安裝圖文教程
這篇文章主要介紹了Windows操作系統(tǒng)下Redis服務(wù)安裝圖文教程,文中給大家提供了redis的下載地址,安裝程序步驟,需要的朋友可以參考下2018-03-03
redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)
使用Redis計(jì)數(shù)器可以輕松地解決數(shù)量控制的問題,同時(shí)還能有效地提高應(yīng)用的性能,本文主要介紹了redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
使用redis實(shí)現(xiàn)令牌桶算法和漏桶算法方式
這篇文章主要介紹了使用redis實(shí)現(xiàn)令牌桶算法和漏桶算法方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-07-07
Redis設(shè)置Hash數(shù)據(jù)類型的過期時(shí)間
在Redis中,我們可以使用Hash數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)一組鍵值對(duì),而有時(shí)候,我們可能需要設(shè)置這些鍵值對(duì)的過期時(shí)間,本文主要介紹了Redis設(shè)置Hash數(shù)據(jù)類型的過期時(shí)間,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01

