天天看點

Redis 哨兵高模式搭建-及Java代碼配置Redis 的下載下傳和安裝及遇到問題的解決  準備配置檔案分别準備三個server的配置檔案 啟動三個server  配置主從 檢查叢集是否已經就緒redis-cli info 指令各數值含義對照  準備哨兵配置檔案(3個節點) 增加三個配置檔案啟動哨兵節點從日志中分析哨兵間的通信及新mater的生成 哨兵同步pubsub機制發出來的消息 Java使用哨兵模式

Redis 的下載下傳和安裝及遇到問題的解決 

 準備配置檔案

# 配置檔案進行了精簡,完整配置可自行和官方提供的完整conf檔案進行對照。端口号自行對應修改
# 背景啟動的意思
daemonize yes 

# 端口号
port 6380

# IP綁定,redis不建議對公網開放,直接綁定0.0.0.0沒毛病
bind 0.0.0.0

# redis資料檔案存放的目錄
dir /usr/local/redis/data

# 開啟AOF
appendonly yes

# 開啟叢集
cluster-enabled yes

# 會自動生成在上面配置的dir目錄下
cluster-config-file nodes-6381.conf 
cluster-node-timeout 5000

# 這個檔案會自動生成
pidfile /var/run/redis_6381.pid 
           

分别準備三個server的配置檔案 

[[email protected] conf]# ll |grep redis | grep -v 6379
-rw-r--r-- 1 root root   489 7月  28 14:49 redis-6380.conf
-rw-r--r-- 1 root root   571 7月  28 18:09 redis-6381.conf
-rw-r--r-- 1 root root   600 7月  28 18:09 redis-6382.conf
           

啟動三個server 

#使用 redis-server 指令,并指定配置檔案
 /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6380.conf

 /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6381.conf

 /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6382.conf
           

 配置主從

#通過 redis-cli用戶端指令将指定端口下的服務作為指定ip端口下的從屬節點
/mnt/redis/bin/redis-cli -p 6381 192.168.16.40 6380

/mnt/redis/bin/redis-cli -p 6382 192.168.16.40 6380

#此時6380為主節點其他節點為從屬節點
           

 檢查叢集是否已經就緒

# 此指令可檢視redis叢集中的 server/Clients/memory/persistence/stats
#                         replication/cpu/modules/cluster/keyspace等資訊
/mnt/redis/bin/redis-cli -p 6380 info 


# 通過指定replication擷取叢集資訊
/mnt/redis/bin/redis-cli -p 6380 info  replication
           

redis-cli info 指令各數值含義對照 

# Server
redis_version:3.2.0 #redis 版本
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:85def9ed04ebeee4
redis_mode:cluster #運作模式(standalone,cluster)
os:Linux 3.0.13-0.27-default x86_64 #運作系統核心版本
arch_bits:64 #字長
multiplexing_api:epoll #Redis使用的事件處理機制
gcc_version:4.3.4 #編譯Redis時所使用的GCC版本
process_id:26327 #Redis程序PID
run_id:e833bf79e98daa5b5917c510b4d9f056cfc5059c #Redis伺服器的編号(用于叢集)
tcp_port:7001 #監聽的端口
uptime_in_seconds:587882 #已運作秒數
uptime_in_days:6 #已運作天數
hz:10 #用于執行背景任務的函數被調用的頻率
lru_clock:10570417 #用于LRU管理的計時器,機關為分鐘
executable:/home/rediscluster/7001/redis/./bin/redis-server #bin檔案位置
config_file:/home/rediscluster/7001/redis/./config/redis.conf #配置檔案位置

# Clients
connected_clients:1 #連接配接的用戶端數
client_longest_output_list:0 #目前用戶端連接配接中最長的輸出清單
client_biggest_input_buf:0 #目前用戶端連接配接中最大的輸入緩存
blocked_clients:0 #阻塞的用戶端數

# Memory
used_memory:2421816 #消耗的記憶體
used_memory_human:2.31M
used_memory_rss:3973120 #作業系統配置設定給Redis的記憶體
used_memory_rss_human:3.79M
used_memory_peak:2421816 #記憶體消耗的峰值
used_memory_peak_human:2.31M
total_system_memory:8250241024 #系統總記憶體
total_system_memory_human:7.68G
used_memory_lua:37888 #Lua腳本消耗的記憶體
used_memory_lua_human:37.00K
maxmemory:0 #記憶體使用限制
maxmemory_human:0B
maxmemory_policy:noeviction #超出記憶體限制時的行為
mem_fragmentation_ratio:1.64 #記憶體碎片率(=used_memory_rss/used_memory)
mem_allocator:jemalloc-4.0.3 #記憶體配置設定器

# Persistence
loading:0 #是否正在載入持久化檔案
rdb_changes_since_last_save:0 #上次持久化以來修改的鍵值數
rdb_bgsave_in_progress:0 #是否正在背景儲存RDB檔案
rdb_last_save_time:1469670746 #上次RDB持久化的時間戳
rdb_last_bgsave_status:ok #上次RDB持久化的結果
rdb_last_bgsave_time_sec:0 #上次建立RDB檔案消耗的秒數
rdb_current_bgsave_time_sec:-1 #如果正在建立RDB檔案,記錄已經消耗了多少時間
aof_enabled:1 #是否啟用AOF持久化
aof_rewrite_in_progress:0 #是否正在重寫AOF檔案
aof_rewrite_scheduled:0 #是否将要重寫AOF檔案
aof_last_rewrite_time_sec:-1 #上次AOF重寫消耗的時間
aof_current_rewrite_time_sec:-1 #目前AOF重寫已消耗的時間
aof_last_bgrewrite_status:ok #上次重寫AOF檔案的結果
aof_last_write_status:ok #上次寫入AOF檔案的結果
aof_current_size:54 #目前AOF檔案的大小
aof_base_size:0 #上一個AOF檔案的大小
aof_pending_rewrite:0 #是否有AOF重寫操作在等待RDB檔案的建立
aof_buffer_length:0 #AOF寫入緩沖區大小
aof_rewrite_buffer_length:0 #AOF重寫緩沖區大小
aof_pending_bio_fsync:0 #正在I/O隊列中等待的fsync()的數量
aof_delayed_fsync:0 #被延遲執行的fsync()的數量

# Stats
total_connections_received:9 #伺服器已接受的連接配接請求數
total_commands_processed:586729 #伺服器已經執行的指令數量
instantaneous_ops_per_sec:1 #目前每秒執行的指令數量
total_net_input_bytes:22855989 #接受的資料包總大小
total_net_output_bytes:849760 #發送的資料包總大小
instantaneous_input_kbps:0.05 #目前下行速率
instantaneous_output_kbps:0.01 #目前上行速率
rejected_connections:0 #被拒絕的連接配接請求數
sync_full:1 #主從同步狀态
sync_partial_ok:0
sync_partial_err:0
expired_keys:0 #過期的鍵數
evicted_keys:0 #因記憶體達到上限被剔除的鍵數
keyspace_hits:0 #命中key的次數
keyspace_misses:0 #未命中的次數
pubsub_channels:0 #目前被訂閱的頻道和模式數
pubsub_patterns:0
latest_fork_usec:640 #最後一次fork()消耗的毫秒數
migrate_cached_sockets:0 #為節點遷移緩存的TCP連接配接數

# Replication
role:master #主節點還是從節點
connected_slaves:1 #已連接配接的從節點數
slave0:ip=127.0.0.1,port=7004,state=online,offset=821435,lag=1 #從節點資訊 ip 端口 資料新度等
master_repl_offset:821435 #主節點資料新度
repl_backlog_active:1 #是否為主從同步啟用積壓空間
repl_backlog_size:1048576 #積壓空間大小
repl_backlog_first_byte_offset:2 #積壓空間開頭的資料新度
repl_backlog_histlen:821434 #積壓空間目前資料量

# CPU
used_cpu_sys:255.39 #核心态CPU時間
used_cpu_user:257.42 #使用者态CPU時間
used_cpu_sys_children:0.00 #子程序核心态CPU時間
used_cpu_user_children:0.00 #子程序使用者态CPU時間

# Cluster
cluster_enabled:1 #是否啟用叢集

# Keyspace
db0:keys=1,expires=0,avg_ttl=0 #各資料庫的鍵數、過期鍵數、資料庫中鍵的平均過期時間戳估測值
           

 準備哨兵配置檔案(3個節點)

# 配置檔案:sentinel.conf,在sentinel運作期間是會被動态修改的
# sentinel如果重新開機時,根據這個配置來恢複其之前所監控的redis叢集的狀态
# 綁定IP
bind 0.0.0.0

# 背景運作
daemonize yes

# 預設yes,沒指定密碼或者指定IP的情況下,外網無法通路
protected-mode no

# 哨兵的端口,用戶端通過這個端口來發現redis
port 26380

# 哨兵自己的IP,手動設定也可自動發現,用于與其他哨兵通信
# sentinel announce-ip

# 臨時檔案夾
dir "/tmp"

# 日志
logfile "/mnt/redis/logs/sentinel-26380.log"

# sentinel監控的master的名字叫做mymaster,初始位址為 192.168.16.40 6380,2代表兩個及以上哨兵認定為死亡,才認為是真的死亡
sentinel myid fa62676c970da6800e30b28b9cc732e2cee85952

# 發送心跳PING來确認master是否存活
# 如果master在“一定時間範圍”内不回應PONG 或者是回複了一個錯誤消息,那麼這個sentinel會主觀地(單方面地)認為這個master已經不可用了
sentinel deny-scripts-reconfig yes

# 如果在該時間(ms)内未能完成failover操作,則認為該failover失敗
sentinel monitor mymaster 192.168.16.40 6381 2

# 指定了在執行故障轉移時,最多可以有多少個從Redis執行個體在同步新的主執行個體,在從Redis執行個體較多的情況下這個數字越小,同步的時間越長,完成故障轉移所需的時間就越長
sentinel down-after-milliseconds mymaster 1000
           

 增加三個配置檔案

[[email protected] conf]# ll | grep sentinel
-rw-r--r-- 1 root root  1989 7月  28 18:09 sentinel-26380.conf
-rw-r--r-- 1 root root  1989 7月  28 18:09 sentinel-26381.conf
-rw-r--r-- 1 root root  1989 7月  28 18:09 sentinel-26382.conf
           

啟動哨兵節點

# 可使用redis-server + sentinel參數啟動
 /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26380.conf --sentinel

 /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26381.conf --sentinel

 /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26382.conf --sentinel


# 直接使用redis-sentinel啟動
 /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26380.conf

 /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26381.conf

 /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26382.conf
           
# 停掉master,主從切換過程
啟動哨兵(用戶端通過哨兵發現Redis執行個體資訊)

哨兵通過連接配接master發現主從叢集内的所有執行個體資訊

哨兵監控redis執行個體的健康狀況

哨兵一旦發現master不能正常提供服務,則通知給其他哨兵

當一定數量的哨兵都認為master挂了

選舉一個哨兵作為故障轉移的執行者

執行者在slave中選取一個作為新的master

将其他slave重新設定為新master的從屬 
           
# 因為6380的端口是主節點
[[email protected] bin]# ps -ef | grep redis| grep 6380
root     30325     1  0 19:09 ?        00:00:00 /mnt/redis/bin/redis-server 0.0.0.0:6380
root     30415     1  0 19:10 ?        00:00:01 /mnt/redis/bin/redis-sentinel 0.0.0.0:26380 [sentinel]
[[email protected] bin]# kill -9 30325

           

從日志中分析哨兵間的通信及新mater的生成 

####################################啟動日志#######################################
31551:X 28 Jul 2020 19:35:23.289 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
31551:X 28 Jul 2020 19:35:23.289 # Redis version=6.0.5, bits=64, commit=00000000, modified=0, pid=31551, just started
31551:X 28 Jul 2020 19:35:23.289 # Configuration loaded
31552:X 28 Jul 2020 19:35:23.293 * Running mode=sentinel, port=26380.
31552:X 28 Jul 2020 19:35:23.293 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
31552:X 28 Jul 2020 19:35:23.294 # Sentinel ID is fa62676c970da6800e30b28b9cc732e2cee85952
31552:X 28 Jul 2020 19:35:23.294 # +monitor master mymaster 192.168.16.40 6380 quorum 2
31552:X 28 Jul 2020 19:35:24.344 # +sdown sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380
31552:X 28 Jul 2020 19:35:24.345 # +sdown sentinel 20d8240e06a10cd887b752026c00de0318761eb8 192.168.16.40 26382 @ mymaster 192.168.16.40 6380
31552:X 28 Jul 2020 19:35:26.471 # -sdown sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380
31552:X 28 Jul 2020 19:35:29.621 # -sdown sentinel 20d8240e06a10cd887b752026c00de0318761eb8 192.168.16.40 26382 @ mymaster 192.168.16.40 6380
####################################殺掉主節點之後日志1###################################

31552:X 28 Jul 2020 19:37:42.950 # +sdown master mymaster 192.168.16.40 6380
31552:X 28 Jul 2020 19:37:43.018 # +new-epoch 3
31552:X 28 Jul 2020 19:37:43.019 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3
31552:X 28 Jul 2020 19:37:44.023 # +odown master mymaster 192.168.16.40 6380 #quorum 3/2
31552:X 28 Jul 2020 19:37:44.023 # Next failover delay: I will not start a failover before Tue Jul 28 19:37:49 2020
31552:X 28 Jul 2020 19:37:44.098 # +config-update-from sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380
31552:X 28 Jul 2020 19:37:44.098 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381
31552:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381
31552:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381
31552:X 28 Jul 2020 19:37:45.169 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381

####################################殺掉主節點之後日志2###################################
31557:X 28 Jul 2020 19:37:42.952 # +sdown master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.014 # +odown master mymaster 192.168.16.40 6380 #quorum 2/2
31557:X 28 Jul 2020 19:37:43.014 # +new-epoch 3
31557:X 28 Jul 2020 19:37:43.014 # +try-failover master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.016 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3
31557:X 28 Jul 2020 19:37:43.019 # fa62676c970da6800e30b28b9cc732e2cee85952 voted for 4cabf69629c1401289b6d3d239eba18b45da0041 3
31557:X 28 Jul 2020 19:37:43.019 # 20d8240e06a10cd887b752026c00de0318761eb8 voted for 4cabf69629c1401289b6d3d239eba18b45da0041 3
31557:X 28 Jul 2020 19:37:43.087 # +elected-leader master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.087 # +failover-state-select-slave master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.140 # +selected-slave slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.140 * +failover-state-send-slaveof-noone slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:43.216 * +failover-state-wait-promotion slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:44.023 # +promoted-slave slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:44.023 # +failover-state-reconf-slaves master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:44.097 * +slave-reconf-sent slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:45.095 * +slave-reconf-inprog slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:45.095 * +slave-reconf-done slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:45.172 # -odown master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:45.172 # +failover-end master mymaster 192.168.16.40 6380
31557:X 28 Jul 2020 19:37:45.172 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381
31557:X 28 Jul 2020 19:37:45.172 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381
31557:X 28 Jul 2020 19:37:45.172 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381
31557:X 28 Jul 2020 19:37:46.226 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381

####################################殺掉主節點之後日志3###################################
31563:X 28 Jul 2020 19:37:42.970 # +sdown master mymaster 192.168.16.40 6380
31563:X 28 Jul 2020 19:37:43.018 # +new-epoch 3
31563:X 28 Jul 2020 19:37:43.019 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3
31563:X 28 Jul 2020 19:37:43.023 # +odown master mymaster 192.168.16.40 6380 #quorum 3/2
31563:X 28 Jul 2020 19:37:43.023 # Next failover delay: I will not start a failover before Tue Jul 28 19:37:49 2020
31563:X 28 Jul 2020 19:37:44.098 # +config-update-from sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380
31563:X 28 Jul 2020 19:37:44.098 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381
31563:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381
31563:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381
31563:X 28 Jul 2020 19:37:45.124 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381
           

哨兵同步pubsub機制發出來的消息

# https://redis.io/topics/sentinel#pubsub-messages

+reset-master <instance details> -- 當master被重置時.

+slave <instance details> -- 當檢測到一個slave并添加進slave清單時.

+failover-state-reconf-slaves <instance details> -- Failover狀态變為reconf-slaves狀态時

+failover-detected <instance details> -- 當failover發生時

+slave-reconf-sent <instance details> -- sentinel發送SLAVEOF指令把它重新配置時

+slave-reconf-inprog <instance details> -- slave被重新配置為另外一個master的slave,但資料複制還未發生時。

+slave-reconf-done <instance details> -- slave被重新配置為另外一個master的slave并且資料複制已經與master同步時。

-dup-sentinel <instance details> -- 删除指定master上的備援sentinel時 (當一個sentinel重新啟動時,可能會發生這個事件).

+sentinel <instance details> -- 當master增加了一個sentinel時。

+sdown <instance details> -- 進入SDOWN狀态時;

-sdown <instance details> -- 離開SDOWN狀态時。

+odown <instance details> -- 進入ODOWN狀态時。

-odown <instance details> -- 離開ODOWN狀态時。

+new-epoch <instance details> -- 目前配置版本被更新時。

+try-failover <instance details> -- 達到failover條件,正等待其他sentinel的選舉。

+elected-leader <instance details> -- 被選舉為去執行failover的時候。

+failover-state-select-slave <instance details> -- 開始要選擇一個slave當選新master時。

+no-good-slave <instance details> -- 沒有合适的slave來擔當新master

+selected-slave <instance details> -- 找到了一個适合的slave來擔當新master

+promoted-slave -- 确認成功

+failover-state-reconf-slaves -- 開始對slaves進行reconfig操作

+slave-reconf-sent -- 向指定的slave發送“slaveof”指令,告知此slave跟随新的master

+slave-reconf-inprog -- 此slave正在執行slaveof + SYNC過程,slave收到“+slave-reconf-sent”之後将會執行slaveof操作

+slave-reconf-done -- 此slave同步完成,此後leader可以繼續下一個slave的reconfig操作

failover-state-send-slaveof-noone <instance details> -- 當把選擇為新master的slave的身份進行切換的時候。

failover-end-for-timeout <instance details> -- failover由于逾時而失敗時。

failover-end <instance details> -- failover成功完成,故障轉移結束

switch-master <master name> <oldip> <oldport> <newip> <newport> -- 當master的位址發生變化時。通常這是用戶端最感興趣的消息了。

+tilt -- 進入Tilt模式。
           
 至此,Redis哨兵模式基本上可以健壯運作了。

 Java使用哨兵模式

@Configuration
publicclass SentinelRedisAppConfig {
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        System.out.println("使用哨兵版本");
        RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
                .master("mymaster")
                // 哨兵位址
                .sentinel("192.168.16.40", 26380)
                .sentinel("192.168.16.40", 26381)
                .sentinel("192.168.16.40", 26381);
        return new LettuceConnectionFactory(sentinelConfig);
    }
}
           

繼續閱讀