Redis之分布式緩存使用解讀
單節(jié)點(diǎn)Redis問題:
- 數(shù)據(jù)丟失:實(shí)現(xiàn)Redis數(shù)據(jù)持久化,保存在磁盤
- 存儲能力:搭建分片集群,利用插槽機(jī)制實(shí)現(xiàn)動態(tài)擴(kuò)容
- 并發(fā)能力:搭建主從集群,實(shí)現(xiàn)讀寫分離
- 故障回復(fù):利用Redis哨兵,實(shí)現(xiàn)檢測和自動恢復(fù)
Redis持久化
RDB持久化
Redis數(shù)據(jù)備份文件,也被叫做Redis數(shù)據(jù)快照,就是把內(nèi)存中所有數(shù)據(jù)都記錄到磁盤,當(dāng)Redis實(shí)例故障重啟后,從磁盤讀取快照文件恢復(fù)數(shù)據(jù)
——主動宕機(jī)會自動執(zhí)行一次RDB
save //由Redis主進(jìn)程執(zhí)行RDB,會阻塞所有命令 bgsave //開啟子進(jìn)程執(zhí)行RDB,避免主進(jìn)程受到影響
Redis內(nèi)部有觸發(fā)RDB的機(jī)制,可以在redis.conf文件找到:
Redis配置文件中的RDB持久化規(guī)則 save 900 1 # 900秒(15分鐘)內(nèi),如果至少有1個(gè)key被修改,則執(zhí)行bgsave save 300 10 # 300秒(5分鐘)內(nèi),如果至少有10個(gè)key被修改,則執(zhí)行bgsave save 60 10000 # 60秒(1分鐘)內(nèi),如果至少有10000個(gè)key被修改,則執(zhí)行bgsave ? 禁用RDB持久化(生產(chǎn)環(huán)境慎用) save ""
RDB的其他配置也可以在redis.conf文件設(shè)置:
# RDB持久化壓縮配置(默認(rèn)開啟,建議不開啟,壓縮會消耗CPU,磁盤不值錢) rdbcompression yes # 是否壓縮RDB文件,yes開啟壓縮,no關(guān)閉壓縮 ? # RDB文件名稱配置 dbfilename dump.rdb # RDB文件的名稱 ? # RDB文件保存目錄配置 dir ./ # RDB文件保存的目錄路徑
bgsave開始時(shí)會fork主進(jìn)程得到子進(jìn)程,子進(jìn)程共享主進(jìn)程的內(nèi)存數(shù)據(jù),完成fork讀取內(nèi)存數(shù)據(jù)并寫入RDB文件
fork采用copy-on-write技術(shù):
- 當(dāng)主進(jìn)程執(zhí)行讀操作時(shí),訪問共享內(nèi)存
- 當(dāng)主進(jìn)程執(zhí)行寫操作時(shí),則會拷貝一份數(shù)據(jù)看,執(zhí)行寫操作
RDB總結(jié)
RDB方式bgsave基本流程:
- → fork主進(jìn)程得到一個(gè)子進(jìn)程,共享內(nèi)存空間
- → 子進(jìn)程讀取內(nèi)存數(shù)據(jù)并寫入新的RDB文件
- → 用新的RDB文件替代舊的RDB文件
RDB執(zhí)行時(shí)機(jī):
默認(rèn)是服務(wù)停止時(shí)
RDB的缺點(diǎn):
- RDB執(zhí)行間隔時(shí)間長,兩次RDB之間寫入數(shù)據(jù)有丟失的風(fēng)險(xiǎn)
- fork子進(jìn)程、壓縮、寫入RDB文件比較耗時(shí)
AOF持久化
因?yàn)槭怯涗浢?,AOF文件比RDB文件大,而且AOF會記錄對同一個(gè)key的多次寫操作,但只有最后一次寫操作才有意義
——執(zhí)行bgrewriteaof命令,可以讓AOF文件執(zhí)行重寫功能,用最少命令達(dá)到相同效果
AOF默認(rèn)關(guān)閉,需要修改redis.conf配置文件來開啟AOF
# AOF持久化開關(guān) appendonly yes # 是否開啟AOF功能,默認(rèn)是no ? # AOF文件名稱 appendfilename "appendonly.aof" # AOF文件的名稱
AOF的命令記錄的頻率也可以通過redis.conf文件配置
//表示每執(zhí)行一次寫命令,立即記錄到AOF文件 appendfsync always //寫命令執(zhí)行完先放入AOF緩沖區(qū),然后每個(gè)1秒將緩沖區(qū)數(shù)據(jù)寫到AOF文件(默認(rèn))3 appendfsync everysec //寫命令執(zhí)行完先放入AOF緩沖區(qū),由操作系統(tǒng)決定何時(shí)將緩沖區(qū)內(nèi)容寫回磁盤
| 策略 | 配置值 | 同步時(shí)機(jī) | 數(shù)據(jù)安全 | 性能影響 | 適用場景 |
|---|---|---|---|---|---|
| always | appendfsync always | 每次寫命令后立即同步 | 最高(零丟失) | 最低(性能差) | 金融交易、支付系統(tǒng) |
| everysec | appendfsync everysec | 每秒同步一次(默認(rèn)) | 較高(最多丟失1秒) | 中等(推薦) | 大多數(shù)生產(chǎn)環(huán)境 |
| no | appendfsync no | 由操作系統(tǒng)決定(通常30秒) | 最低(可能丟失>30秒) | 最高(性能最好) | 緩存、非關(guān)鍵數(shù)據(jù) |
Redis會在觸發(fā)閾值時(shí)自動去重寫AOF文件,閾值可在redis.conf中配置
//AOF文件比上次文件增長超過多少百分比則觸發(fā)重寫 auto-aof-rerite-percentage 100 //AOF文件體積最小多大以上才觸發(fā)重寫 auto-aof-rerite-min-size 64mb
AOF和RDB對比
AOF和RDB各有優(yōu)缺點(diǎn),如果對數(shù)據(jù)安全性要求高,在實(shí)際開發(fā)中會結(jié)合兩者使用
| 對比維度 | RDB | AOF |
|---|---|---|
| 持久化方式 | 定時(shí)對整個(gè)內(nèi)存做快照 | 記錄每一次執(zhí)行的命令 |
| 數(shù)據(jù)完整性 | 不完整,兩次備份之間會丟失 | 相對完整,取決于刷盤策略 |
| 文件大小 | 會有壓縮,文件體積小 | 記錄命令,文件體積很大 |
| 宕機(jī)恢復(fù)速度 | 很快 | 慢 |
| 數(shù)據(jù)恢復(fù)優(yōu)先級 | 低,因?yàn)閿?shù)據(jù)完整性不如AOF | 高,因?yàn)閿?shù)據(jù)完整性更高 |
| 系統(tǒng)資源占用 | 高,大量CPU和內(nèi)存消耗(fork子進(jìn)程) | 低,主要是磁盤IO資源但AOF重寫時(shí)會占用大量CPU和內(nèi)存資源 |
| 使用場景 | 可以容忍數(shù)分鐘的數(shù)據(jù)丟失,追求更快的啟動速度 | 對數(shù)據(jù)安全性要求較高常見 |
Redis主從
單節(jié)點(diǎn)Redis的并發(fā)能力有上限,要進(jìn)一步提高Redis的并發(fā)能力需要搭建主從集群,實(shí)現(xiàn)讀寫分離.
搭建方式存儲于文件Redis集群.md下
數(shù)據(jù)同步原理
通過master判斷slave是不是第一次來同步數(shù)據(jù)需要掌握兩個(gè)重要概念:
- Replication Id:簡稱replid,是數(shù)據(jù)集的標(biāo)記,id一致則說明是同一數(shù)據(jù)集。每一個(gè)master都有唯一的replid,slave則會繼承master節(jié)點(diǎn)的replid
- offset :偏移量,隨著記錄在repl_baklog中的數(shù)據(jù)增多而逐漸增大。slave完成同步時(shí)也會記錄當(dāng)前同步的offset。如果slave的offset小于master的offset,說明slave數(shù)據(jù)落后于master,需要更新
- 因此slave做數(shù)據(jù)同步,必須向master聲明自己的replication id 和offset,master才可以判斷到底需要同步哪些數(shù)據(jù)
一、主從第一次同步是全量同步:

結(jié)合兩個(gè)重要概念后:

全量同步流程:
- slave節(jié)點(diǎn)請求增量同步
- master節(jié)點(diǎn)判斷replid,發(fā)現(xiàn)不一致,拒絕增量同步
- master將完整內(nèi)存數(shù)據(jù)生成RDB,發(fā)送RDB到slave
- slave清空本地?cái)?shù)據(jù),加載master的RDB
- master將RDB期間的命令記錄在repl_baklog,并持續(xù)將log中的命令發(fā)給slave
- slave執(zhí)行接收到的命令,保持于master之間的同步
二、主從第一次同步是全量同步,但如果slave重啟后同步則執(zhí)行增量同步

注意:repl_baklog大小上限,寫滿后會覆蓋最早的數(shù)據(jù)。如果slave斷開時(shí)間過久,導(dǎo)致尚未備份的數(shù)據(jù)被覆蓋,則無法基于log做增量同步,只能再次全量同步
優(yōu)化Redis主從集群方案:
- 在master中配置repl-diskless-sync yes啟用無磁盤復(fù)制,避免全量同步的磁盤IO
- Redis單節(jié)點(diǎn)上的內(nèi)存占用不要太大,減少RDB導(dǎo)致的過多磁盤IO
- 適當(dāng)提高repl_baklog的大小,發(fā)現(xiàn)slave宕機(jī)盡快實(shí)現(xiàn)故障恢復(fù),盡可能避免全量同步
- 限制一個(gè)master上的slave節(jié)點(diǎn)數(shù)量,如果實(shí)在過多slave則采用主-從-從鏈?zhǔn)浇Y(jié)構(gòu),減少master壓力

Redis主從總結(jié)
全量同步和主從同步的區(qū)別:
- 全量同步:master將完整內(nèi)存數(shù)據(jù)生成RDB,發(fā)送到slave。后續(xù)命令則記錄在repl_baklog,逐個(gè)發(fā)送給slave
- 增量同步:slave提交自己的offset到master,master獲取repl_baklog中從offset之后的命令交給slave
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
redis lua腳本實(shí)戰(zhàn)秒殺和減庫存的實(shí)現(xiàn)
本文主要是學(xué)習(xí)一下redis lua腳本的編寫,以及在redisson這個(gè)redis客戶端中是怎樣使用的,實(shí)戰(zhàn)一下秒殺場景redis減庫存lua腳本的編寫,并偽真實(shí)環(huán)境壓測查看效果。感興趣的可以了解一下2021-11-11
Redis+Caffeine實(shí)現(xiàn)分布式二級緩存組件實(shí)戰(zhàn)教程
這篇文章主要介紹了Redis+Caffeine實(shí)現(xiàn)分布式二級緩存組件實(shí)戰(zhàn)教程,介紹了分布式二級緩存的優(yōu)勢,使用組件的方法,通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
Redis發(fā)布訂閱和實(shí)現(xiàn).NET客戶端詳解
發(fā)布訂閱在應(yīng)用級其作用是為了減少依賴關(guān)系,通常也叫觀察者模式。主要是把耦合點(diǎn)單獨(dú)抽離出來作為第三方,隔離易變化的發(fā)送方和接收方。下面這篇文章主要給大家介紹了關(guān)于Redis發(fā)布訂閱和實(shí)現(xiàn).NET客戶端的相關(guān)資料,需要的朋友可以參考下2017-03-03
Redis實(shí)現(xiàn)鎖續(xù)期的項(xiàng)目實(shí)踐
本文介紹了使用Redis實(shí)現(xiàn)分布式鎖的續(xù)期,包括使用Lua腳本、Redlock算法和Redisson客戶端等方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12
Redis過期時(shí)間的設(shè)計(jì)與實(shí)現(xiàn)代碼
在?Redis?中,鍵的過期時(shí)間設(shè)計(jì)與實(shí)現(xiàn)是一個(gè)重要的功能,這使得?Redis?可以自動刪除在指定時(shí)間后不再需要的鍵,下面詳細(xì)介紹?Redis?過期時(shí)間的設(shè)計(jì)和實(shí)現(xiàn),包括設(shè)置過期時(shí)間、過期鍵的存儲結(jié)構(gòu)、過期鍵的刪除策略等,需要的朋友可以參考下2024-08-08

