Redis学习(一)之 持久化、主从与哨兵架构
jiaruredis持久化
RDB快照:在默認(rèn)情況下, Redis 將內(nèi)存數(shù)據(jù)庫(kù)快照保存在名字為 dump.rdb 的二進(jìn)制文件中。
你可以對(duì) Redis 進(jìn)行設(shè)置, 讓它在“ N 秒內(nèi)數(shù)據(jù)集至少有 M 個(gè)改動(dòng)”這一條件被滿足時(shí), 自動(dòng)保存一次數(shù)據(jù)集。比如說, 以下設(shè)置會(huì)讓 Redis 在滿足"60 秒內(nèi)有至少有 1000 個(gè)鍵被改動(dòng)"這一條件時(shí), 自動(dòng)保存一次 數(shù)據(jù)集:
# save 60 1000 //關(guān)閉RDB只需要將所有的save保存策略注釋掉即可。 還可以手動(dòng)執(zhí)行命令生成RDB快照,進(jìn)入redis客戶端執(zhí)行命令save或bgsave可以生成dump.rdb文件,每次命令執(zhí)行都會(huì)將所有redis內(nèi)存快照到一個(gè)新的rdb文件里,并覆蓋原有rdb快照文件。 bgsave的寫時(shí)復(fù)制(COW)機(jī)制: Redis 借助操作系統(tǒng)提供的寫時(shí)復(fù)制技術(shù)(Copy-On-Write, COW)在生成快照的同時(shí),依然可以正常 處理寫命令。簡(jiǎn)單來說,bgsave 子進(jìn)程是由主線程 fork 生成的,可以共享主線程的所有內(nèi)存數(shù)據(jù)。bgsave 子進(jìn)程運(yùn)行后,開始讀取主線程的內(nèi)存數(shù)據(jù),并把它們寫入 RDB 文件。 此時(shí),如果主線程對(duì)這些 數(shù)據(jù)也都是讀操作,那么,主線程和 bgsave 子進(jìn)程相互不影響。但是,如果主線程要修改一塊數(shù)據(jù),那 么,這塊數(shù)據(jù)就會(huì)被復(fù)制一份,生成該數(shù)據(jù)的副本。然后,bgsave 子進(jìn)程會(huì)把這個(gè)副本數(shù)據(jù)寫入 RDB 文 件,而在這個(gè)過程中,主線程仍然可以直接修改原來的數(shù)據(jù)。 AOF(append-only file): 快照功能并不是非常耐久(durable): 如果 Redis 因?yàn)槟承┰蚨斐晒收贤C(jī), 那么服務(wù)器將丟失 最近寫入、且仍未保存到快照中的那些數(shù)據(jù)。從 1.1 版本開始, Redis 增加了一種完全耐久的持久化方 式: AOF 持久化,將修改的每一條指令記錄進(jìn)文件appendonly.aof中(先寫入os cache,每隔一段時(shí)間 fsync到磁盤) 可以通過修改配置文件來打開 AOF 功能:?# appendonly yes 可以配置 Redis 多久才將數(shù)據(jù) fsync 到磁盤一次。 有三個(gè)選項(xiàng):- appendfsync always:每次有新命令追加到 AOF 文件時(shí)就執(zhí)行一次 保存?,非常慢,也非常安全。
- appendfsync everysec:每秒 保存?一次,足夠快,并且在故障時(shí)只會(huì)丟失 1 秒鐘的數(shù)據(jù)。
- ?appendfsync no:從不 保存,將數(shù)據(jù)交給操作系統(tǒng)來處理。更快,也更不安全的選擇。
推薦(并且也是默認(rèn))的措施為每秒 保存?一次, 這種 策略可以兼顧速度和安全性。
AOF重寫:AOF文件里可能有太多沒用指令,所以AOF會(huì)定期根據(jù)內(nèi)存的最新數(shù)據(jù)生成aof文件
例如,執(zhí)行了如下幾條命令:?最后重寫成:(過程不重要,直接重寫為結(jié)果6)
?如下兩個(gè)配置可以控制AOF自動(dòng)重寫頻率:
- ?# auto‐aof‐rewrite‐min‐size 64mb //aof文件至少要達(dá)到64M才會(huì)自動(dòng)重寫,文件太小恢復(fù)速度本來就 很快,重寫的意義不大
- ?# auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重寫后文件大小增長(zhǎng)了100%則再次觸發(fā)重寫
Redis 4.0 混合持久化:
重啟 Redis 時(shí),我們很少使用 RDB來恢復(fù)內(nèi)存狀態(tài),因?yàn)闀?huì)丟失大量數(shù)據(jù)。我們通常使用 AOF 日志重 放,但是重放 AOF 日志性能相對(duì) RDB來說要慢很多,這樣在 Redis 實(shí)例很大的情況下,啟動(dòng)需要花費(fèi)很 長(zhǎng)的時(shí)間。 Redis 4.0 為了解決這個(gè)問題,帶來了一個(gè)新的持久化選項(xiàng)——混合持久化。通過如下配置可以開啟混合持久化(必須先開啟aof):
# aof‐use‐rdb‐preamble yes?如果開啟了混合持久化,AOF在重寫時(shí),不再是單純將內(nèi)存數(shù)據(jù)轉(zhuǎn)換為RESP命令寫入AOF文件,而是將 重寫這一刻之前的內(nèi)存做RDB快照處理,并且將RDB快照內(nèi)容和增量的AOF修改內(nèi)存數(shù)據(jù)的命令存在一 起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會(huì)進(jìn)行改名,覆蓋原有的AOF文件,完成新舊兩個(gè)AOF文件的替換。
于是在 Redis 重啟的時(shí)候,可以先加載 RDB 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重啟效率大幅得到提升。Redis主從架構(gòu):
linux安裝redis步驟可以移步這一篇文章:linux環(huán)境下安裝redis(一)_酒書的博客-CSDN博客_linux下安裝redis
參考redis的安裝可以發(fā)現(xiàn)安裝好了一臺(tái)redis,端口號(hào)6379
然后著手搭建主從同步:
注意:搭建之前一定要主從機(jī)器的自我保護(hù),不然主機(jī)會(huì)拒絕連接的
?step1:復(fù)制一份redis.conf文件
step2:將相關(guān)配置修改為如下值: port 6380 pidfile /var/run/redis_6380.pid # 把pid進(jìn)程號(hào)寫入pidfile配置的文件 logfile "6380.log" dir /usr/local/redis‐5.0.3/data/6380 # 指定數(shù)據(jù)存放目錄 # 需要注釋掉bind # bind 127.0.0.1(bind綁定的是自己機(jī)器網(wǎng)卡的ip,如果有多塊網(wǎng)卡可以配多個(gè)ip,代表允許客戶端通 過機(jī)器的哪些網(wǎng)卡ip去訪問,內(nèi)網(wǎng)一般可以不配置bind,注釋掉即可) //配置主從復(fù)制 replicaof 192.168.0.60 6379 # 從本機(jī)6379的redis實(shí)例復(fù)制數(shù)據(jù),Redis 5.0之前使用slaveofreplica‐read‐only yes # 配置從節(jié)點(diǎn)只讀?
step3:啟動(dòng)從節(jié)點(diǎn)
step4:連接從節(jié)點(diǎn)
?step5:測(cè)試6379上寫數(shù)據(jù),6380機(jī)器是否同步到相關(guān)數(shù)據(jù)
主從搭建成功,一主一從!!!!?
Redis主從工作原理:
? ? ? ? 如果你為master配置了一個(gè)slave,不管這個(gè)salve是否是第一次連接上master,它都會(huì)發(fā)送一個(gè)PSYNC的命令給master請(qǐng)求復(fù)制數(shù)據(jù);master收到PSYNC命令后,會(huì)在后臺(tái)進(jìn)行數(shù)據(jù)持久化通過bgsave生成最新的rdb快照文件,持久化期間master會(huì)繼續(xù)接收客戶端的請(qǐng)求,它會(huì)把這些可能修改數(shù)據(jù)的請(qǐng)求緩存到內(nèi)存中;當(dāng)持久化進(jìn)行完畢以后,master會(huì)把這份rdb文件數(shù)據(jù)集發(fā)送給slave,slave會(huì)把接收到的數(shù)據(jù)進(jìn)行持久化生成rdb,然后再加載到內(nèi)存中。然后master再將之前緩存在內(nèi)存中的命令發(fā)送給slave。
? ? ? ? 當(dāng)master與salve之間的連接由于某些原因而斷開時(shí),slave能夠自動(dòng)重連master,如果master收到了多個(gè)slave并發(fā)連接請(qǐng)求,它只會(huì)進(jìn)行一次持久化,而不是一個(gè)連接一次,然后再把這一份持久化的數(shù)據(jù)發(fā)送給多個(gè)并發(fā)連接的slave。
主從復(fù)制(全量復(fù)制流程圖):
?數(shù)據(jù)部分復(fù)制:
當(dāng)master和slave斷開重連后,一般都會(huì)對(duì)整份數(shù)據(jù)進(jìn)行復(fù)制。但從redis2.8版本開始,redis改用可以支持部分?jǐn)?shù)據(jù)復(fù)制的命令PSYNC去master同步數(shù)據(jù),slave與master能夠在網(wǎng)絡(luò)連接斷開重連后只進(jìn)行部分?jǐn)?shù)據(jù)復(fù)制(斷點(diǎn)續(xù)傳)。
master會(huì)在其內(nèi)存中創(chuàng)建一個(gè)復(fù)制數(shù)據(jù)用的緩存隊(duì)列,緩存最近一段時(shí)間的數(shù)據(jù),master和它所有slave都維護(hù)了復(fù)制的數(shù)據(jù)下標(biāo)offset和master的進(jìn)程id,因此當(dāng)網(wǎng)絡(luò)連接斷開后再連接,slave會(huì)請(qǐng)求master繼續(xù)進(jìn)行未完成的復(fù)制,從所記錄的數(shù)據(jù)下標(biāo)開始;如果master進(jìn)程id變化了或者從節(jié)點(diǎn)數(shù)據(jù)下標(biāo)offset太舊,已經(jīng)不在master的緩存隊(duì)列里了,那么將會(huì)進(jìn)行一次全量數(shù)據(jù)的復(fù)制。
主從復(fù)制(部分復(fù)制、斷點(diǎn)續(xù)傳)流程圖:
如果有很多從節(jié)點(diǎn),為了緩解主從復(fù)制風(fēng)暴(多個(gè)從節(jié)點(diǎn)同時(shí)復(fù)制主節(jié)點(diǎn)導(dǎo)致主節(jié)點(diǎn)壓力過大),可 以做如 下架構(gòu),讓部分從節(jié)點(diǎn)與從節(jié)點(diǎn)(與主節(jié)點(diǎn)同步)同步數(shù)據(jù):ps:主從架構(gòu)當(dāng)主服務(wù)器掛了之后需要運(yùn)維手動(dòng)修改某個(gè)從節(jié)點(diǎn)為主節(jié)點(diǎn),主從架構(gòu)中的slave的主要功能就是做數(shù)據(jù)備份使用
Redis哨兵架構(gòu):
?sentinel哨兵是特殊的redis服務(wù),不提供讀寫服務(wù),主要用來監(jiān)控redis實(shí)例節(jié)點(diǎn)。
哨兵架構(gòu)下client端第一次從哨兵找出redis的主節(jié)點(diǎn),后續(xù)就直接訪問redis的主節(jié)點(diǎn),不會(huì)每次都通過sentinel代理訪問redis的主節(jié)點(diǎn),當(dāng)redis的主節(jié)點(diǎn)發(fā)生變化,哨兵會(huì)第一時(shí)間感知到,并且將新的redis主節(jié)點(diǎn)通知給client端(這里面redis的client端一般都實(shí)現(xiàn)了訂閱功能,訂閱sentinel發(fā)布的節(jié)點(diǎn)變動(dòng)消息)。
哨兵架構(gòu)搭建步驟:
step1:我在主從基礎(chǔ)上再搞一臺(tái)從機(jī)slave6381(步驟可以參考從機(jī)6380的搭建)
step2:測(cè)試6381可用
?
?現(xiàn)在就是一主二從的架構(gòu)了,接著搭建哨兵架構(gòu)
step3:搭建哨兵
在安裝好redis之后在redis文件夾下可以看到是有一個(gè)sentinel.conf的
1、復(fù)制一份sentinel.conf:cp sentinel.conf? sentinel-26379.conf
2、將相關(guān)配置修改為如下值:
port 26379 daemonize yes pidfile "/var/run/redis‐sentinel‐26379.pid" logfile "26379.log" dir "/usr/local/redis‐5.0.3/data" # sentinel monitor <master‐redis‐name> <master‐redis‐ip> <master‐redis‐port> <quorum> # quorum是一個(gè)數(shù)字,指明當(dāng)有多少個(gè)sentinel認(rèn)為一個(gè)master失效時(shí)(值一般為:sentinel總數(shù)/2 + 1),master才算真正失效 sentinel monitor mymaster 192.168.0.60 6379 2 # mymaster這個(gè)名字隨便取,客戶端訪問時(shí)會(huì)用 到step4:啟動(dòng)sentinel哨兵實(shí)例
src/redis‐sentinel? ?sentinel‐26379.conf
step5:同理繼續(xù)配置兩個(gè)哨兵,端口26380和26381,注意上述配置文件里的對(duì)應(yīng)數(shù)字都要修改
step6:查看sentinel的info信息
src/redis‐cli ‐p 26379
info
?可以看到一主二從三哨兵搭建完成!!!
sentinel集群都啟動(dòng)完畢后,會(huì)將哨兵集群的元數(shù)據(jù)信息寫入所有的sentinel的配置文件里去(追加在文件的最下面),我們查看如下配置文件sentinel-26379.conf,如下所示:
sentinel known‐replica mymaster 116.62.71.39?6380 #代表redis主節(jié)點(diǎn)的從節(jié)點(diǎn)信息 sentinel known‐replica mymaster 116.62.71.39?6381?#代表redis主節(jié)點(diǎn)的從節(jié)點(diǎn)信息 sentinel known‐sentinel mymaster 116.62.71.39 26381? xxxxx?#代表感知到的其它哨兵節(jié)點(diǎn)sentinel known‐sentinel mymaster 116.62.71.39 26380? xxxxx?#代表感知到的其它哨兵節(jié)點(diǎn)
如果redis主節(jié)點(diǎn)掛了,哨兵集群會(huì)重新選舉出新的redis主節(jié)點(diǎn),同時(shí)會(huì)修改所有sentinel節(jié)點(diǎn)配置文件的集群元數(shù)據(jù)信息,同時(shí)還會(huì)修改sentinel文件里之前配置的mymaster對(duì)應(yīng)的端口,當(dāng)6379的redis實(shí)例再次啟動(dòng)時(shí),哨兵集群根據(jù)集群元數(shù)據(jù)信息就可以將6379端口的redis節(jié)點(diǎn)作為從節(jié)點(diǎn)加入集群。
哨兵的jedis連接代碼:
下面用代碼演示:當(dāng)主節(jié)點(diǎn)掛了之后哨兵重新選舉,客戶端是否能夠動(dòng)態(tài)感知
引入依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>配置文件:
?測(cè)試controller:
?然后我啟動(dòng)程序調(diào)用接口訪問:可以看到一直在set值
這個(gè)時(shí)候我將redis主節(jié)點(diǎn)6379給停掉:可以看到會(huì)出現(xiàn)短暫的報(bào)錯(cuò)
在短暫報(bào)錯(cuò)之后,新的主節(jié)點(diǎn)選舉出來之后就會(huì)繼續(xù)進(jìn)行set值,如下圖所示:
?這個(gè)時(shí)候我登錄6381機(jī)器,使用info命令查看集群信息:6381成了master
總結(jié)
以上是生活随笔為你收集整理的Redis学习(一)之 持久化、主从与哨兵架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python3,异常进阶写法之retry
- 下一篇: PostgreSQL下载和安装教程