第一节 Redis 使用及哨兵集群 2022-1-2
Java組件總目錄
Redis 使用及哨兵集群
- Java組件總目錄
- 一 Redis基本數據類型使用場景
- 1 String
- 2 List 存儲列表結構
- 3 Hash
- 4 Set
- 5 Zset
- 二級目錄
- 三級目錄
- 二 Redis 的補充數據類型
- 1 BitMap
- 2 HyperLogLog
- 3 Geospatial
- 三 Redis 消息模式 (了解)
- 3.1 隊列模式
- 注意事項:
- 缺點:
- 3.2 發布訂閱模式
- 四 Redis Stream
- 4.1 消息隊列相關命令:
- 4.2 消費者組相關命令:
- 五 Redis 事務
- 5.1 事務失敗處理
- Redis 語法錯誤
- Redis 運行錯誤
- 六 Redis 和lua 整合
- 6.1 Redis中使用lua的好處
- 6.2 EVAL命令
- 6.3 lua 腳本調用Redis 命令
- redis.call();
- redis.pcall();
- redis-cli --eval
- 七 Redis 持久化(重點)
- 7.1 RDB
- 7.2 AOF
- 1 AOF介紹
- 2 同步磁盤數據
- 3 AOF重寫原理(優化AOF文件)
- 4 如何選擇RDB和AOF
- 7.3 混合持久化方式
- 八 Redis 主從復制
- 8.1 什么是主從復制
- 8.2 實現原理
- 1 數據同步
- 2 runid
- 3 復制偏移量
- 4 全量同步
- 5 增量同步
- 8.3 主從配置
- 8.3.1 安裝
- 8.3.2 配置說明
- 九 Redis 哨兵機制
- 9.1 Redis Sentinel 工作原理分析
- 1 為什么要用到哨兵
- 2 哨兵機制(sentinel)的高可用
- 3 哨兵的定時監控
- 4 哨兵lerder選舉流程
- 5 自動故障轉移機制
- 9.2 哨兵進程的作用
- 9.3 哨兵配置
- quorum的解釋如下:
- 如果有一個sentinel:
- 如果有2個sentinel
- 如果是經典的3節點哨兵集群
一 Redis基本數據類型使用場景
redis:應用的場景高并發所有數據都是保存在內存中。存取速度快,適合于做緩存。一些重要數據一定要保存到關系型數據庫中,例如mysql。適合做緩存的: string, hash1 String
應用: JSONstring 緩存功能 計數器 共享用戶Session 分布式鎖 setnx
2 List 存儲列表結構
粉絲列表,文章評論列表, lrange 基于Redis實現簡單的高性能分頁, 簡單的消息隊列
3 Hash
應用: 爆品 商品 秒殺倉庫 秒殺商品 商品1 庫存量
4 Set
基于Redis進行全局的Set去重 共同好友 你可能認識
5 Zset
排行榜,有權重的消息隊列 熱搜 前面是名稱 后面試熱度值
二級目錄
三級目錄
二 Redis 的補充數據類型
1 BitMap
BitMap 就是通過一個 bit 位來表示某個元素對應的值或者狀態, 其中的 key 就是對應元素本身,實際上底層也是通過對字符串的操作來實現。Redis 從 2.2 版本之后新增了setbit, getbit, bitcount 等幾個bitmap 相關命令。雖然是新命令,但是本身都是對字符串的操作,我們先來看看語法
# 其中 offset 必須是數字,value 只能是 0 或者 1,offset參數要求大于或等于 0, # 并且小于 2^32(4,294,967,296)這將位圖限制在 512MB SETBIT key offset value設置最后一個可能的位時(偏移量等于 2^32-1)和存儲在鍵中的字符串值尚不保存字符串值,或持有一個小字符串值,Redis 需要分配所有中間內存,這些中間內存可能會阻塞服務器一段時間。完成第一次分配后,對同一key的 SETBIT的后續調用將無內存分配開銷。
通過 bitcount可以很快速的統計,比傳統的關系型數據庫效率高很多。
BITOP operation destkey key [key …]
對一個或多個保存二進制位的字符串 key 進行位元操作,并將結果保存到 destkey 上。operation 可以是 AND 、 OR 、 NOT 、 XOR 這四種操作中的任意一種:
2 HyperLogLog
Redis 在 2.8.9 版本添加了 HyperLogLog 結構。Redis HyperLogLog 是用來做基數統計的算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定的、并且是很小的。
但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以
HyperLogLog 不能像集合那樣,返回輸入的各個元素。
這個數據結構的命令有三個:PFADD、PFCOUNT、PFMERGE
用途:記錄網站IP注冊數,每日訪問的IP數,頁面實時UV、在線用戶人數
局限性:只能統計數量,沒有辦法看具體信息。
3 Geospatial
底層數據結構 Zset。可以用來保存地理位置,并作位置距離計算或者根據半徑計算位置等。有沒有想過用Redis來實現附近的人?或者計算最優地圖路徑?Geo本身不是一種數據結構,它本質上還是借助于Sorted Set(ZSET)
Redis GEO 操作方法有:
- geoadd:添加地理位置的坐標。
- geopos:獲取地理位置的坐標。
- geodist:計算兩個位置之間的距離。
- georadius:根據用戶給定的經緯度坐標來獲取指定范圍內的地理位置集合。
- georadiusbymember:根據儲存在位置集合里面的某個地點獲取指定范圍內的地理位置集合。
- geohash:返回一個或多個位置對象的 geohash 值。
三 Redis 消息模式 (了解)
消息模式差于專門的消息系統 Kafka、 RabbitMQ。消息有可能丟失, 可用于能夠接受消息丟失的場景。如 過濾等。
3.1 隊列模式
使用list類型的lpush和rpop實現消息隊列。
注意事項:
- 消息接收方如果不知道隊列中是否有消息,會一直發送rpop命令,如果這樣的話,會每一次都建立一次連接,這樣顯然不好。
- 可以使用brpop命令,它如果從隊列中取不出來數據,會一直阻塞,在一定范圍內沒有取出則 返回null
缺點:
- 做消費者確認ACK麻煩,不能保證消費者消費消息后是否成功處理的問題(宕機或處理異常等),通常需要維護一個Pending列表,保證消息處理確認。
- 不能做廣播模式,如pub/sub,消息發布/訂閱模型
- 不能重復消費,一旦消費就會被刪除
- 不支持分組消費
3.2 發布訂閱模式
- SUBSCRIBE,用于訂閱信道
- PUBLISH,向信道發送消息
- UNSUBSCRIBE,取消訂閱
此模式允許生產者只生產一次消息,由中間件負責將消息復制到多個消息隊列,每個消息隊列由對應的消費組消費。 理解為群發消息。
四 Redis Stream
Redis 5.0 全新的數據類型:streams,官方把它定義為:以更抽象的方式建模日志的數據結構。由于推出比較遲,應用相對較少。Redis的streams主要是一個append only(AOF)的數據結構,至少在概念上它是一種在內存中表示的抽象數據類型,只不過它們實現了更強大的操作,以克服日志文件本身的限制。
如果你了解MQ,那么可以把streams當做基于內存的MQ。如果你還了解kafka,那么甚至可以把streams當做基于內存的kafka。listpack存儲信息,Rax組織listpack 消息鏈表listpack是對ziplist的改進,它比ziplist少了一個定位最后一個元素的屬性。
streams數據結構本身非常簡單,但是streams依然是Redis到目前為止最復雜的類型,其原因是實現的一些額外的功能:一系列的阻塞操作允許消費者等待生產者加入到streams的新數據。另外還有一個稱為Consumer Groups的概念,Consumer Group概念最先由kafka提出,Redis有一個類似實現,和 kafka的Consumer Groups的目的是一樣的:允許一組客戶端協調消費相同的信息流!
一個組可以有多個消費者,加快了消息的消費。
4.1 消息隊列相關命令:
- XADD - 添加消息到末尾
- XTRIM - 對流進行修剪,限制長度
- XDEL - 刪除消息
- XLEN - 獲取流包含的元素數量,即消息長度
- XRANGE - 獲取消息列表,會自動過濾已經刪除的消息
- XREVRANGE - 反向獲取消息列表,ID 從大到小
- XREAD - 以阻塞或非阻塞方式獲取消息列表
4.2 消費者組相關命令:
- XGROUP CREATE - 創建消費者組
- XREADGROUP GROUP - 讀取消費者組中的消息
- XACK - 將消息標記為"已處理"
- XGROUP SETID - 為消費者組設置新的最后遞送消息ID
- XGROUP DELCONSUMER - 刪除消費者
- XGROUP DESTROY - 刪除消費者組
- XPENDING - 顯示待處理消息的相關信息
- XCLAIM - 轉移消息的歸屬權
- XINFO - 查看流和消費者組的相關信息;
- XINFO GROUPS - 打印消費者組的信息;
- XINFO STREAM - 打印流信息
五 Redis 事務
嚴格意義上說 redis事務只是個批處理 有隔離性 但是沒有原子性。
- Redis 的事務是通過 MULTI(事務開始) 、 EXEC(事務執行,并關閉) 、 DISCARD(清空事務,并關閉) 和 WATCH(設置個事務監控的鍵, 鍵改變時不執行事務,增加一個事務執行的開關) 、UNWATCH (清除監控的鍵)這五個命令來完成的。
- Redis 的單個命令都是原子性的,所以這里需要確保事務性的對象是命令集合。 Redis 將命令集合序列化并確保處于同一事務的命令集合連續且不被打斷的執行
- Redis 不支持回滾操作。
5.1 事務失敗處理
Redis 語法錯誤
語法錯誤會將整個事務的命令在隊列里都清除。
Redis 運行錯誤
在隊列里正確的命令可以執行 (弱事務性)
- 1、在隊列里正確的命令可以執行 (非原子操作)
- 2、不支持回滾
Redis 不支持事務回滾(為什么呢)
- 1、大多數事務失敗是因為語法錯誤或者類型錯誤,這兩種錯誤,在開發階段都是可以預見的。
- 2、 Redis 為了性能方面就忽略了事務回滾。 (Mysql 使用redo-log 實現回滾)
六 Redis 和lua 整合
Redis整合lua是對Redis事務的補充。lua是一種輕量小巧的腳本語言,用標準C語言編寫并以源代碼形式開放, 其設計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能。
6.1 Redis中使用lua的好處
本的過程中無需擔心會出現競態條件。 隔離性
6.2 EVAL命令
在redis客戶端中,執行以下命令:
EVAL script numkeys key [key ...] arg [arg ...] eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second命令說明:
-
script參數:是一段Lua腳本程序,它會被運行在Redis服務器上下文中,這段腳本不必(也不應該)定義為一個Lua函數。
-
numkeys參數:用于指定鍵名參數的個數。
-
key [key …]參數: 從EVAL的第三個參數開始算起,使用了numkeys個鍵(key),表示在腳本中所用到的那些Redis鍵(key),這些鍵名參數可以在Lua中通過全局變量KEYS數組,用1為基址的形式訪問( KEYS[1] , KEYS[2] ,以此類推)。
-
arg [arg …]參數:可以在Lua中通過全局變量ARGV數組訪問,訪問的形式和KEYS變量類似(ARGV[1] 、 ARGV[2] ,諸如此類)。
6.3 lua 腳本調用Redis 命令
redis.call();
返回值就是redis命令執行的返回值。如果出錯,返回錯誤信息,不繼續執行
redis.pcall();
返回值就是redis命令執行的返回值,如果出錯了 記錄錯誤信息,繼續執行
注意事項: 在腳本中,使用return語句將返回值返回給客戶端,如果沒有return,則返回nil
redis-cli --eval
可以使用redis-cli --eval命令指定一個lua腳本文件去執行。
腳本文件(redis.lua),內容如下:
local num = redis.call('GET', KEYS[1]); if not num then return 0; else local res = num * ARGV[1]; redis.call('SET',KEYS[1], res); return res; end在redis客戶機,執行腳本命令:
# 之前設置在redis中設置過 a 為 1 [root@localhost bin]# ./redis-cli --eval redis.lua a , 8 (integer) 8[root@localhost bin]# ./redis-cli --eval redis.lua lua:incrbyml , 8 (integer) 0 # incr 遞增數字 [root@localhost bin]# ./redis-cli incr lua:incrbyml (integer) 1 [root@localhost bin]# ./redis-cli --eval redis.lua lua:incrbyml , 8 (integer) 8- –eval:告訴redis客戶端去執行后面的lua腳本
- redis.lua:具體的lua腳本文件名稱
- lua:incrbymul : lua腳本中需要的key,具體的key值
- 8:lua腳本中需要的value
上面命令中keys和values中間需要使用逗號隔開,并且逗號兩邊都要有空格。 lua:incrbyml , 8
執行.lua腳本 不需要寫key的個數
七 Redis 持久化(重點)
7.1 RDB
RDB 是 Redis 默認采用的持久化方式。
RDB 方式是通過快照( snapshotting )完成的,當符合一定條件時 Redis 會自動將內存中的數據進行快照并持久化到硬盤。 (將當前內存的數據保存。)
觸發RDB快照的時機:
主線程是單線程 4.0 I/O操作 已經有多線程概念
設置快照規則:
save 多少秒內 數據變了多少
save “” : 不使用RDB存儲
save 900 1 : 表示15分鐘(900秒鐘)內至少1個鍵被更改則進行快照。
save 300 10 : 表示5分鐘(300秒)內至少10個鍵被更改則進行快照。
save 60 10000 :表示1分鐘內至少10000個鍵被更改則進行快照。
RDB快照的實現原理
fork 是操作系統的函數 linux/ uinx *nux, fork-調用一個子進程,制作快照,生成RDB文件, 替換掉原來的RDB文件.
注意事項
RDB優缺點:
- 缺點:使用 RDB 方式實現持久化,一旦 Redis 異常退出,就會丟失最后一次快照以后更改的所有數
據。這個時候我們就需要根據具體的應用場景,通過組合設置自動快照條件的方式來將可能發生的
數據損失控制在能夠接受范圍。如果數據相對來說比較重要,希望將損失降到最小,則可以使用
AOF 方式進行持久化 - 優點: RDB 可以最大化 Redis 的性能:父進程在保存 RDB 文件時唯一要做的就是 fork 出一個子進
程,然后這個子進程就會處理接下來的所有保存工作,父進程無需執行任何磁盤 I/O 操作。同時這
個也是一個缺點,如果數據集比較大的時候, fork 可以能比較耗時,造成服務器在一段時間內停
止處理客戶端的請求;
7.2 AOF
1 AOF介紹
默認情況下 Redis 沒有開啟 AOF ( append only file )方式的持久化。
開啟 AOF 持久化后,每執行一條會更改 Redis 中的數據的命令, Redis 就會將該命令寫入硬盤中的 AOF文件,這一過程顯然會降低 Redis 的性能,但大部分情況下這個影響是能夠接受的,另外使用較快的硬盤可以提高 AOF 的性能。
2 同步磁盤數據
Redis 每次更改數據的時候, aof 機制都會將命令記錄到 aof 文件,但是實際上由于操作系統的緩存機制,數據并沒有實時寫入到硬盤,而是進入硬盤緩存。再通過硬盤緩存機制去刷新到保存到文件。
最開始的數據它是通過讀取內存中的數據,轉換成命令。后邊的就是每次的更新指令,進行存儲。
# 每次執行寫入都會進行同步, 這個是最安全但是是效率比較低的方式 appendfsync always # 每一秒執行(默認) appendfsync everysec # 不主動進行同步操作,由操作系統去執行,這個是最快但是最不安全的方式 appendfsync no3 AOF重寫原理(優化AOF文件)
Redis 可以在 AOF 文件體積變得過大時,自動地在后臺對 AOF 進行重寫。重寫后的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。AOF進行優化時候,并不是讀取原來的AOF文件 ,而是讀取redis db 進行轉化。
AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議(RESP)的格式
保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析( parse )也很輕松。
4 如何選擇RDB和AOF
- 內存數據庫 rdb(redis database)+aof 數據不能丟
- 緩存服務器 rdb
- 不建議 只使用 aof (性能差)
- 恢復時: 先aof再rdb
7.3 混合持久化方式
RDB 和 AOF 持久化各有利弊,RDB 可能會導致一定時間內的數據丟失,而 AOF 由于文件較大則會影響Redis 的啟動速度,為了能同時擁有 RDB 和 AOF 的優點,Redis 4.0 之后新增了混合持久化的方式,因此我們在必須要進行持久化操作時,應該選擇混合持久化的方式。
混合持久化是結合了 RDB 和 AOF 的優點,在寫入的時候,先把當前的數據以 RDB 的形式寫入文件的開頭,再將后續的操作命令以 AOF 的格式存入文件,這樣既能保證 Redis 重啟時的速度,又能減低數據丟失的風險。
查詢是否開啟混合持久化可以使用 config get aof-use-rdb-preamble 命令,其中 yes 表示已經開啟混合持久化,no 表示關閉。
需要注意的是,在非必須進行持久化的業務中,可以關閉持久化,這樣可以有效的提升 Redis 的運行速度,不會出現間歇性卡頓的困擾。
八 Redis 主從復制
8.1 什么是主從復制
持久化保證了即使 Redis 服務重啟也不會丟失數據,因為 Redis 服務重啟后會將硬盤上持久化的數據恢復到內存中,但是當 Redis 服務器的硬盤損壞了可能會導致數據丟失,不過通過 Redis 的主從復制機制就可以避免這種單點故障,如下圖:
- 主 Redis 中的數據有兩個副本( replication )即從 redis1 和從 redis2 ,即使一臺 Redis 服務
器宕機其它兩臺 Redis 服務也可以繼續提供服務。 - 主 Redis 中的數據和從 Redis 上的數據保持實時同步,當主 Redis 寫入數據時通過主從復制機制
會復制到兩個從 Redis 服務上。 - 只有一個主 Redis ,可以有多個從 Redis 。
- 主從復制不會阻塞 master ,在同步數據時, master 可以繼續處理 client 請求。
- 一個 Redis 可以即是主又是從服務器。
8.2 實現原理
1 數據同步
Redis在2.8及以上版本使用psync命令完成主從數據同步,同步過程分為:全量復制和部分復制
- 全量復制:一般用于初次復制場景,Redis早期支持的復制功能只有全量復制,它會把主節點全部
數據一次性發送給從節點,當數據量較大時,會對主從節點和網絡造成很大的開銷。 - 部分復制:用于處理在主從復制中因網絡閃斷等原因造成的數據丟失場景,當從節點再次連上主節
點后,如果條件允許,主節點會補發丟失數據給從節點。因為補發的數據遠遠小于全量數據,可以
有效避免全量復制的過高開銷。
部分復制是對老版復制的重大優化,有效避免了不必要的全量復制操作。因此當使用復制功能時,盡量采用2.8以上版本的Redis。
psync命令運行需要以下組件支持:
- 主Redis的復制偏移量(replication offset)和從Redis的復制偏移量。
- 主Redis的復制積壓緩沖區(replication backlog)。
- Redis的運行ID(run ID)。
2 runid
Redis 服務器的隨機標識符(用于 Sentinel 和集群),重啟后就會改變;當復制時發現和之前的 run_id 不同時,將會對數據全量同步。
3 復制偏移量
通過對比主從節點的復制偏移量,可以判斷主從節點數據是否一致。
參與復制的主從節點都會維護自身復制偏移量。主節點(master)在處理完寫入命令后,會把命令
的字節長度做累加記錄,統計信息在info relication中的master_repl_offset指標中:
從節點(slave)每秒鐘上報自身的復制偏移量給主節點,因此主節點也會保存從節點的復制偏移
量,統計指標如下:
從節點在接收到主節點發送的命令后,也會累加記錄自身的偏移量。統計信息在info relication中 的slave_repl_offset指標中:
4 全量同步
Redis 的全量同步過程主要分三個階段:
- 同步快照階段: Master 創建并發送快照給 Slave , Slave 載入并解析快照。 Master 同時將此階段所產生的新的寫命令存儲到緩沖區。
- 同步寫緩沖階段: Master 向 Slave 同步存儲在緩沖區的寫操作命令。
- 同步增量階段: Master 向 Slave 同步寫操作命令。
5 增量同步
- Redis 增量同步主要指 Slave 完成初始化后開始正常工作時, Master 發生的寫操作同步到
Slave 的過程。 - 通常情況下, Master 每執行一個寫命令就會向 Slave 發送相同的寫命令,然后 Slave 接收并執
行。
8.3 主從配置
8.3.1 安裝
# 第一步:安裝 C 語言需要的 GCC 環境 yum install -y gcc-c++ yum install -y wget # 第二步:下載并解壓縮 Redis 源碼壓縮包 wget http://download.redis.io/releases/redis-5.0.4.tar.gz tar -zxf redis-5.0.4.tar.gz # 編譯 Redis 源碼,進入 redis-3.2.9 目錄,執行編譯命令 cd redis-5.0.4 make # 安裝 Redis ,需要通過 PREFIX 指定安裝路徑 make install PREFIX=/kkb/server/redis # 將配置文件復制過來 cp /root/redis-5.0.4/redis.conf /kkb/server/redis/bin/# 配置監聽ip和端口 守護模式運行 bind daemonize yes # 先打開服務端 ./redis-server ./redis.conf # 在打開客戶端 /kkb/server/redis/bin/redis-cli # 設置客戶端 訪問 服務端的 ip 和端口號 redis-cli -h 192.168.56.102 -p 63798.3.2 配置說明
- 主Redis配置 無需配置
- 修改從服務器上的 redis.conf 文件:
九 Redis 哨兵機制
9.1 Redis Sentinel 工作原理分析
1 為什么要用到哨兵
哨兵(Sentinel)主要是為了解決在主從復制架構中出現宕機的情況,主要分為兩種情況:
-
1).從Redis宕機
這個相對而言比較簡單,在Redis中從庫重新啟動后會自動加入到主從架構中,自動完成同步數據。在Redis2.8版本后,主從斷線后恢復的情況下實現增量復制。 -
2).主Redis宕機
這個相對而言就會復雜一些,需要以下2步才能完成
a. 在從數據庫中執行SLAVEOF NO ONE命令,斷開主從關系并且提升為主庫繼續服務
b. 第二步,將主庫重新啟動后,執行SLAVEOF命令,將其設置為其他庫的從庫,這時數據就能更新回來由于這個手動完成恢復的過程其實是比較麻煩的并且容易出錯,所以Redis提供的哨兵(sentinel)的功能來解決。
2 哨兵機制(sentinel)的高可用
Sentinel(哨兵)是Redis 的高可用性解決方案:由一個或多個Sentinel 實例 組成的Sentinel 系統可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,并在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器。 原有主節點恢復將降為從節點。
3 哨兵的定時監控
任務1:每個哨兵節點每10秒會向主節點和從節點發送info命令獲取最新拓撲結構圖,哨兵配置時只要配置對主節點的監控即可,通過向主節點發送info,獲取從節點的信息,并當有新的從節點加入時可以馬上感知到。
任務2:每個哨兵節點每隔2秒會向redis數據節點的指定頻道上發送該哨兵節點對于主節點的判斷以及當前哨兵節點的信息,同時每個哨兵節點也會訂閱該頻道,來了解其它哨兵節點的信息及對主節點的判斷,其實就是通過消息publish和subscribe來完成的。
任務3:每隔1秒每個哨兵會向主節點、從節點及其余哨兵節點發送一次ping命令做一次心跳檢測,這個也是哨兵用來判斷節點是否正常的重要依據。
防止哨兵節點掛機,選用3個哨兵節點。
主觀下線:所謂主觀下線,就是單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網絡不通等等原因)。SDOWN
sentinel會以每秒一次的頻率向所有與其建立了命令連接的實例(master,從服務,其他sentinel)發ping命令,通過判斷ping回復是有效回復,還是無效回復來判斷實例時候在線(對該sentinel來說是“主觀在線”)。
sentinel配置文件中的down-after-milliseconds設置了判斷主觀下線的時間長度,如果實例在down-after-milliseconds毫秒內,返回的都是無效回復,那么sentinel回認為該實例已(主觀)下線,修改其flags狀態為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生產中要注意。
客觀下線:當主觀下線的節點是主節點時,此時該哨兵3節點會通過指令sentinel is-masterdown-by-addr尋求其它哨兵節點對主節點的判斷,如果其他的哨兵也認為主節點主觀線下了,則當認為主觀下線的票數超過了quorum(選舉)個數,此時哨兵節點則認為該主節點確實有問題,這樣就客觀下線了,大部分哨兵節點都同意下線操作,也就說是客觀下線 ODOWN 。
4 哨兵lerder選舉流程
如果主節點被判定為客觀下線之后,就要選取一個哨兵節點來完成后面的故障轉移工作,選舉出一個
leader的流程如下:
- 每個在線的哨兵節點都可以成為領導者,當它確認(比如哨兵3)主節點下線時,會向其它哨兵發is-master-down-by-addr命令,征求判斷并要求將自己設置為領導者,由領導者處理故障轉移;
- 當其它哨兵收到此命令時,可以同意或者拒絕它成為領導者;
- 如果哨兵3發現自己在選舉的票數num 大于等于 (sentinels)/2+1時,將成為領導者,如果沒有超過,繼續選舉…………
如果Sentinel收到其他Sentinel的投票請求,在以下兩種情況下會把自己的票投給請求的Sentinel實例:
5 自動故障轉移機制
在從節點中選擇新的主節點
sentinel狀態數據結構中保存了主服務的所有從服務信息,領頭sentinel按照如下的規則從從服務列表中
挑選出新的主服務
就繼續選擇
有就繼續
更新主從狀態
- 通過slaveof no one命令,讓選出來的從節點成為主節點;并通過slaveof命令讓其他節點成為其從節點。
- 將已下線的主節點設置成新的主節點的從節點,當其回復正常時,復制新的主節點,變成新的主節點的從節點
同理,當已下線的服務重新上線時,sentinel會向其發送slaveof命令,讓其成為新主的從
9.2 哨兵進程的作用
- 監控( Monitoring ): 哨兵( sentinel ) 會不斷地檢查你的 Master 和 Slave 是否運作正常。
- 提醒( Notification ): 當被監控的某個 Redis 節點出現問題時, 哨兵( sentinel ) 可以通過 API向管理員或者其他應用程序發送通知。
- 自動故障遷移( Automatic failover ):當一個 Master 不能正常工作時,哨兵( sentinel ) 會開始一次自動故障遷移操作
推薦的sentinel 集群是1主 2或多從,3哨兵;sentinel的啟動 是redis-sentinel
9.3 哨兵配置
sentinel.conf
# 設置端口 port 26379 # 是否守護進程啟動 daemonize no # 守護進程運行的時候需要保留pidfile pidfile /var/run/redis-sentinel.pid # 日志文件 logfile "/root/log/sentinel.log" ## sentinel monitor master-group-name hostname port quorum sentinel monitor mymaster 127.0.0.1 6379 3 # down-after-milliseconds,超過多少毫秒跟一個redis實例斷了連接(ping不通),哨兵就可能認為這個redis實例掛了 sentinel down-after-milliseconds mymaster 30000 # parallel-syncs,新的master別切換之后,同時有多少個slave被切換到去連接新master,重新做同步,數字越低,花費的時間越多 # 比如:master宕機了,4個slave中有1個切換成了master,剩下3個slave就要掛到新的master上面去 # 這個時候,如果parallel-syncs是1,那么3個slave,一個一個地掛接到新的master上面去,1個掛接完,而且從新的master sync完數據之后,再掛接下一個。 # 如果parallel-syncs是3,那么一次性就會把所有slave掛接到新的master上去 sentinel parallel-syncs mymaster 1 #failover-timeout,執行故障轉移的timeout超時時長,Default is 3 minutes. sentinel failover-timeout mymaster 180000quorum的解釋如下:
-
(1)至少多少個哨兵要一致同意,master進程掛掉了,或者slave進程掛掉了,或者要啟動一個故障轉移操作,quorum是用來識別故障的,真正執行故障轉移的時候,還是要在哨兵集群執行選舉,選舉一個哨兵進程出來執行故障轉移操作 。
-
(2)假設有5個哨兵,quorum設置了2,那么如果5個哨兵中的2個都認為master掛掉了; 2個哨兵中的一個就會做一個選舉,選舉一個哨兵出來,執行故障轉移; 如果5個哨兵中有3個哨兵都是運行的, 那么故障轉移才會被允許執行。
原文是:Note that whatever is the ODOWN quorum, a Sentinel will require to be selected by the majority of the known Sentinels in order to start a failover, so no failover can be performed in minority.
如果有一個sentinel:
實際情況,其實單純從代碼的情況,其實1個Sentinel就能完成主觀下線(sdown,Subjectively Down),客觀下線(odown, Objectively Down) 的判斷,自動發現 Sentinel 和從服務器,并且完成故障轉移。
如果有2個sentinel
2 個的一半以上 2;
如果哨兵集群僅僅部署了個2個哨兵實例,quorum=1。s1和s2中只要有1個哨兵認為master宕機就可以還行切換,同時s1和s2中會選舉出一個哨兵來執行故障轉移。同時這個時候,需要majority,也就是大多數哨兵都是運行的,2個哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=3),如果一個節點掛了那么哨兵也就掛了,哨兵只剩下一個,那么就無法完成故障轉移。
如果是經典的3節點哨兵集群
Configuration: quorum = 2。
majority=2(majority不能配置,由redis自行計算所得。超過一半的最小值)
如果M1所在機器宕機了,那么三個哨兵還剩下2個,S2和S3可以一致認為master宕機,然后選舉
出一個來執行故障轉移。同時3個哨兵的majority是2,所以還剩下的2個哨兵運行著,就可以允許
執行故障轉移。
這就是經典的sentinel3個節點的集群。節省資源的同時又滿足了高可用。
總結
以上是生活随笔為你收集整理的第一节 Redis 使用及哨兵集群 2022-1-2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 笔试:常见题目总结,andro
- 下一篇: IBM小型机+Oracle数据库+EMC