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