天天看點

Redis Sentinel(哨兵) 和 Master+Slave(主從)的實作和原理分析Redis Sentinel(哨兵) 和 Master+Slave(主從)的實作和原理分析

Redis Sentinel(哨兵) 和 Master+Slave(主從)的實作和原理分析

Author QiuRiMangCao 秋日芒草

單節點

server01

server02 } redis 單節點

server03

master slave

server01

server02 } redis (master,slave)[資料備份][讀寫分離] slave減輕master的壓力,當master挂了,slave不支援寫,隻支援讀,是以服務還是不可用

server03

叢集

server01 } { node2 (master,slave)資料備份][讀寫分離] slave減輕master的壓力,當master挂了,slave不支援寫,隻支援讀,是以服務還是不可用,整個節點不可用

server02 } redis { node1 (master,slave)

server03 } { node3 (master,slave)

sentinel

server01

server02 } redis (master,slave,redis-sentinel)sentinel用于切換master或slave,這樣都可以寫了

server03

主從配置(master,slave)

修改redis.conf 檔案,設定主從配置

或者修改redis.conf檔案,使用daemonize yes

./redis-server &

指定配置檔案啟動

./redis-server /etc/redis/6379.conf

指定端口連接配接

redis-cli -p 6380

啟動

redis redis-server /etc/myredis/redis.config

然後再測試啟動成功與否

redis-cli ping

如果不是使用腳本啟動則需要使用redis-cli shutdown指令來停止

指令:

redis-cli -p 8888 shutdown

查詢redis的版本資訊

[[email protected] bin]# ./redis-server -v

vim 定位行

跳轉到檔案尾

輸入冒号(:),打開指令輸入框

輸入指令:$

跳轉到檔案頭

輸入冒号(:),打開指令輸入框

輸入指令1,是“一”的阿拉伯數字,不是小寫的L

master日志資訊

3311:M 20 Oct 15:37:58.872 * Ready to accept connections

3311:M 20 Oct 15:39:45.855 * Slave 127.0.0.1:1001 asks for synchronization

3311:M 20 Oct 15:39:45.855 * Full resync requested by slave 127.0.0.1:1001

3311:M 20 Oct 15:39:45.855 * Starting BGSAVE for SYNC with target: disk

3311:M 20 Oct 15:39:45.855 * Background saving started by pid 3325

3325:C 20 Oct 15:39:45.859 * DB saved on disk

3325:C 20 Oct 15:39:45.860 * RDB: 0 MB of memory used by copy-on-write

3311:M 20 Oct 15:39:45.932 * Background saving terminated with success

3311:M 20 Oct 15:39:45.933 * Synchronization with slave 127.0.0.1:1001 succeeded

slave日志資訊

3321:S 20 Oct 15:39:45.854 * Connecting to MASTER 127.0.0.1:1000

3321:S 20 Oct 15:39:45.854 * MASTER <-> SLAVE sync started

3321:S 20 Oct 15:39:45.855 * Non blocking connect for SYNC fired the event.

3321:S 20 Oct 15:39:45.855 * Master replied to PING, replication can continue…

3321:S 20 Oct 15:39:45.855 * Partial resynchronization not possible (no cached master)

3321:S 20 Oct 15:39:45.855 * Full resync from master: 1a326d8a3bc1af413789dfa9dca65954072418d5:0

3321:S 20 Oct 15:39:45.933 * MASTER <-> SLAVE sync: receiving 175 bytes from master

3321:S 20 Oct 15:39:45.933 * MASTER <-> SLAVE sync: Flushing old data

3321:S 20 Oct 15:39:45.933 * MASTER <-> SLAVE sync: Loading DB in memory

3321:S 20 Oct 15:39:45.933 * MASTER <-> SLAVE sync: Finished with success

查詢redis上的所有key

127.0.0.1:1000> keys *

存入master

[[email protected] redis]# ./bin/redis-cli -p 1000

127.0.0.1:1000> set password 123456

slave同步資料

[[email protected] redis]# ./bin/redis-cli -p 1001

127.0.0.1:1001> keys *

1) “password”

slave服務不讓寫

127.0.0.1:1001> set user:password zhangsan:123456

(error) READONLY You can’t write against a read only slave.

檢視服務資訊

127.0.0.1:1000> info

Server

redis_version:4.0.1

redis_git_sha1:00000000

redis_git_dirty:0

redis_build_id:92e72a18d61bfe4f

redis_mode:standalone

os:Linux 3.10.0-693.el7.x86_64 x86_64

主備資訊-master

# Replication
role:master #角色
connected_slaves:
# slave0:ip=127.0.0.1,port=1001 - slave資訊
slave0:ip=,port=,state=online,offset=,lag=
master_replid:a326d8a3bc1af413789dfa9dca65954072418d5
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:
           

主備資訊-slave

# Replication
role:slave
master_host:
master_port:
master_link_status:up
master_last_io_seconds_ago:
master_sync_in_progress:
slave_repl_offset:
slave_priority:
slave_read_only:
connected_slaves:
master_replid:a326d8a3bc1af413789dfa9dca65954072418d5
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:
           

memcached 和 redis的差別,redis可以緩存到硬碟,而memcached不可用

通訊過程:slave(在啟動的時候會向master發送同步指令),master(将鏡像資料以檔案的形式同步到slave),新資料(增量[心跳]同步資料到slave),在同步資料的時候,master是非阻塞的狀态,而slave是阻塞的狀态,目的:防止slave在同步資料的時候,應用伺服器來讀取資料出現問題

主從配置(master,slave)+ redis-sentinel 高可用

redis本身不具備master-slave切換,是以要使用redis-sentinel來完成(master-slave)的自動切換

redis-sentinel可以監控擴充多個節點,就是多個(master-slave)的叢集

(master-slave)的叢集中slave可以多個,友善哨兵的切換到任意一個slave

sentinel配置檔案在運作期間可以被多态修改,會在master服務不好用的時候将配置檔案修改成slave的配置,重新開機sentinel會被恢複配置

sentinel在網絡環境中如何知道master節點是否好用的? 是根據互相ping - pong 來判斷是否可用的

但網絡還是會存在不穩定的情況,可以導緻一次或多次ping不通伺服器,是以sentinel會有一個規則去識别—->然後就産生了選舉(投票)- 還必須滿足記數才能選舉出

sentinel可以有奇數個來參加選舉并投票,滿足一般以上挂掉整個叢集就挂掉了

移動sentinel配置檔案到指定目錄

mv ./sentinel.conf ./sentinel

移動指定檔案夾到指定目錄

mv sentinel/ ../

sentinel的啟動

[[email protected] bin]# ./redis-sentinel ../redis-pub/sentinel/sentinel.conf

檢視sentinel和master,slave啟動情況

[[email protected] bin]# ps -ef | grep redis

root 3311 1 0 15:37 ? 00:00:05 ./bin/redis-server 127.0.0.1:1000

root 3321 1 0 15:39 ? 00:00:05 ./bin/redis-server 127.0.0.1:1001

root 3336 1726 0 15:44 pts/1 00:00:00 ./bin/redis-cli -p 1000

root 3532 1802 0 16:55 pts/2 00:00:00 ./redis-sentinel *:26379 [sentinel]

root 3537 2678 0 16:56 pts/3 00:00:00 grep –color=auto redis

sentinel 啟動時監控的master和slave

3532:X 20 Oct 16:55:58.458 # Sentinel ID is ddcf5dd45ac986e979558ce338948d3bc463a9d5

3532:X 20 Oct 16:55:58.458 # +monitor master mymaster 127.0.0.1 1000 quorum 1

3532:X 20 Oct 16:55:58.459 * +slave slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

配置sentinel後再去slave存入資料,還是提示失敗

[[email protected] bin]# ./redis-cli -p 1001

127.0.0.1:1001> get password

“123456”

127.0.0.1:1001> set username zhaojian

(error) READONLY You can’t write against a read only slave.

停掉master:1000,并檢視sentinel和slave資訊

[[email protected] redis]# ./bin/redis-cli -p 1000 shutdown

[[email protected] redis]# ps -ef | grep redis

root 3321 1 0 15:39 ? 00:00:05 ./bin/redis-server 127.0.0.1:1001

root 3532 1802 0 16:55 pts/2 00:00:00 ./redis-sentinel *:26379 [sentinel]

root 3538 1373 0 17:00 pts/0 00:00:00 ./redis-cli -p 1001

root 3578 1726 0 17:02 pts/1 00:00:00 grep –color=auto redis

過配置檔案中的30s後,會在啟動Sentinel啟動頁面上輸出日志資訊

3532:X 20 Oct 16:55:58.455 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

3532:X 20 Oct 16:55:58.458 # Sentinel ID is ddcf5dd45ac986e979558ce338948d3bc463a9d5

3532:X 20 Oct 16:55:58.458 # +monitor master mymaster 127.0.0.1 1000 quorum 1

3532:X 20 Oct 16:55:58.459 * +slave slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.847 # +sdown master mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.847 # +odown master mymaster 127.0.0.1 1000 #quorum 1/1

3532:X 20 Oct 17:03:11.847 # +new-epoch 1

3532:X 20 Oct 17:03:11.847 # +try-failover master mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.850 # +vote-for-leader ddcf5dd45ac986e979558ce338948d3bc463a9d5 1

3532:X 20 Oct 17:03:11.850 # +elected-leader master mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.850 # +failover-state-select-slave master mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.927 # +selected-slave slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.927 * +failover-state-send-slaveof-noone slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:11.999 * +failover-state-wait-promotion slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:12.006 # +promoted-slave slave 127.0.0.1:1001 127.0.0.1 1001 @ mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:12.007 # +failover-state-reconf-slaves master mymaster 127.0.0.1 1000

3532:X 20 Oct 17:03:12.065 # +failover-end master mymaster 127.0.0.1 1000

master從1000裝換到現在的1001,是以master-slave切換成功

3532:X 20 Oct 17:03:12.066 # +switch-master mymaster 127.0.0.1 1000 127.0.0.1 1001

3532:X 20 Oct 17:03:12.066 * +slave slave 127.0.0.1:1000 127.0.0.1 1000 @ mymaster 127.0.0.1 1001

3532:X 20 Oct 17:03:42.085 # +sdown slave 127.0.0.1:1000 127.0.0.1 1000 @ mymaster 127.0.0.1 1001

現在之前slave角色變為master,這就是sentinel機制的作用,已經啟動監控的作用,已經将slave切換成master

# Replication
role:master
connected_slaves:
master_replid:ee7b0607cda24f609821af975cd5b3c802f
master_replid2:a326d8a3bc1af413789dfa9dca65954072418d5
master_repl_offset:
second_repl_offset:
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:
           

現在再給1001(之前的slave)存值成功

127.0.0.1:1001> set username zhaojian

OK

現在再去連1000,會連不上

再啟動1000 redis

[[email protected] bin]# ./redis-server ../redis-pub/master/redis.conf

現在1000這個已經成為slave了

# Replication
role:slave
master_host:
master_port:
master_link_status:up
master_last_io_seconds_ago:
master_sync_in_progress:
slave_repl_offset:
slave_priority:
slave_read_only:
connected_slaves:
master_replid:ad3eb737bc808a362da9b06c2943f4b35711de5
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:
           

因為是slave,是以不能寫入

127.0.0.1:1000> keys *

1) “password”

2) “username”

127.0.0.1:1000> set age 11

(error) READONLY You can’t write against a read only slave.

總結:master和slave的配置檔案沒變,隻是sentinel的配置檔案在動态的變

檢視sentinel配置檔案資訊

[[email protected] sentinel]# cat sentinel.conf

之前的master連接配接資訊變成如下

sentinel myid ddcf5dd45ac986e979558ce338948d3bc463a9d5

當時配置的1000已經動态變為1001了

# Default is 30 seconds.
sentinel monitor mymaster   
           

末尾動态增加如下,目的:是描述目前master和slave辨別狀态

sentinel known-slave mymaster 127.0.0.1 1000

sentinel current-epoch 1

停掉1000 和 1001 保留sentinel,之前在1001配置了slaveof 127.0.0.1 1000。

[[email protected] redis]# ./bin/redis-cli -p 1000 shutdown

[[email protected] redis]# ./bin/redis-cli -p 1001 shutdow

重新啟動

[[email protected] bin]# ./redis-server ../redis-pub/master/redis.conf

[[email protected] bin]# ./redis-server ../redis-pub/slave/redis.conf

[[email protected] bin]# ps -ef | grep redis

root 3532 1802 0 16:55 pts/2 00:00:05 ./redis-sentinel *:26379 [sentinel]

root 3665 1 0 17:37 ? 00:00:00 ./redis-server 127.0.0.1:1000

root 3670 1 0 17:37 ? 00:00:00 ./redis-server 127.0.0.1:1001

root 3676 1373 0 17:37 pts/0 00:00:00 grep –color=auto redis

連接配接1000用戶端,并檢視資訊

[[email protected] redis]# ./bin/redis-cli -p 1000

127.0.0.1:1000> info

重新開機後1000還是沒從slave變成master,sentinel并沒有停止,是以說明是sentinel在起作用了。

# Replication
role:slave
master_host:
master_port:
master_link_status:up
master_last_io_seconds_ago:
master_sync_in_progress:
slave_repl_offset:
slave_priority:
slave_read_only:
connected_slaves:
master_replid:c54c599d796c83615067b1b665502a81061285a
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
           

如果将master和slave切換過來需要怎麼做? 可以直接修改sentinel的配置資訊或者殺掉sentinel的程序,再重新啟動master+slave+sentinel

繼續閱讀