天天看點

redis主從複制、哨兵機制和叢集

1、複制(master-slave)

redis主從複制、哨兵機制和叢集

配置過程 修改 slave機器的 redis.conf 增加如下配置

slaveof

我這裡兩台slave 都配置

slaveof 192.168.159.10 6379

重新開機三台reidis 服務後 啟動

執行 ./redis-cli 連結 本機redis 服務 然後執行info replication 可以看到主從狀态資訊如下

master:

[[email protected] bin]# ./redis-cli 
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.159.12,port=6379,state=online,offset=99,lag=1
slave1:ip=192.168.159.11,port=6379,state=online,offset=99,lag=1
master_repl_offset:99
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:98
           

slave :

[[email protected] bin]# ./redis-cli 
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.159.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:99
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
           

然後在主節點自行 set name zhang 從節點執行 get name 也是zhang

并且從節點預設不能進行寫操作。執行 set name zhang 報錯如下(redis.conf 中有預設配置 slave-read-only yes):

127.0.0.1:6379> set name zhang
(error) READONLY You can't write against a read only slave.
127.0.0.1:6379> get name
           

實作原理 :

1)slave第一次或重新連接配接到master 後 會向master發送一個sunc 指令

2)master收到sync 的時候做兩件事

a)執行bgsave rdb快照儲存資料到磁盤 并把檔案傳送給salve,slave收到檔案會把檔案中的資料加載到記憶體

b)把新收到的修改指令儲存到緩沖區,并将指令發送給slave 實作同步

驗證同步操作。

在slave幾點執行sync 可以看到 指令同步過程如下:

主幾點執行 set name li 後 slave 收到了 set name li

127.0.0.1:6379> sync
Entering slave output mode...  (press Ctrl-C to quit)
SYNC with master, discarding 42 bytes of bulk transfer...
SYNC done. Logging commands from master.
"PING"
"PING"
"PING"
"PING"
"PING"
"SELECT","0"
"set","name","li"
           

主從資料不一緻問題解決:

redis.conf 中 slave-serve-stale-data 選項可以配置,在從節點完成同步之前是否正常接收用戶端請求 為yes 表示正常接收 no 如果沒有同步完資料 有用戶端請求時傳回錯誤(具體參見redis.conf 中的說明)

複制方式:

基于rdb檔案的複制

無硬碟複制

增量複制

2、哨兵機制 sentinel

哨兵可以檢測master 和slave 的狀态

當master挂掉以後選舉出新的master (哨兵也可以做叢集,增加可用性)

哨兵監控redis狀态的同時也會監控其他哨兵的狀态。

redis主從複制、哨兵機制和叢集

配置哨兵:

1)複制sentinel.conf 配置檔案到bin目錄

2)修改配置

sentinel monitor mymaster 192.168.159.10 6379 2 配置要監控的master節點 ip 端口 第三個參數2 表示有幾個哨兵投票才起作用 我們三個哨兵配置為2

sentinel down-after-milliseconds mymaster 10000 配置在多少毫秒之内 主節點沒有響應就判斷為離線

然後開始從 slave中選舉出新的master

3)啟動哨兵

運作 ./redis-sentinel ./sentinel.conf

[[email protected] bin]# ./redis-sentinel ./sentinel.conf
8577:X 05 Feb 22:56:04.349 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.7 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 8577
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

8577:X 05 Feb 22:56:04.351 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
8577:X 05 Feb 22:56:04.351 # Sentinel runid is e01630b36aa383688bf8609a9622045d2620d017
8577:X 05 Feb 22:56:04.351 # +monitor master mymaster 192.168.159.10 6379 quorum 2
8577:X 05 Feb 22:56:04.404 * +slave slave 192.168.159.12:6379 192.168.159.12 6379 @ mymaster 192.168.159.10 6379
8577:X 05 Feb 22:56:04.461 * +slave slave 192.168.159.11:6379 192.168.159.11 6379 @ mymaster 192.168.159.10 6379
           

4)哨兵叢集

直接在多台伺服器啟動哨兵即可 這裡 三台伺服器都按照上述步驟修改配置并啟動哨兵。

多台哨兵啟動時可以看到哨兵同僚監控了哨兵的狀态 如下:

[[email protected] bin]# ./redis-sentinel ./sentinel.conf
7971:X 05 Feb 23:02:31.869 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.7 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 7971
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

7971:X 05 Feb 23:02:31.872 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7971:X 05 Feb 23:02:31.873 # Sentinel runid is e83812b0bad75bb5e50886b76363668a4fc0d1b7
7971:X 05 Feb 23:02:31.873 # +monitor master mymaster 192.168.159.10 6379 quorum 2
7971:X 05 Feb 23:02:33.608 * +sentinel sentinel 192.168.159.11:26379 192.168.159.11 26379 @ mymaster 192.168.159.10 6379
7971:X 05 Feb 23:02:33.811 * +sentinel sentinel 192.168.159.12:26379 192.168.159.12 26379 @ mymaster 192.168.159.10 6379
           

哨兵選舉示範。

通過用戶端關閉master redis 可以看到哨兵重新選舉了新的 master 節點 為 192.168.159.12 如下:

8507:X 05 Feb 23:09:39.961 # +sdown master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.028 # +odown master mymaster 192.168.159.10 6379 #quorum 2/2
8507:X 05 Feb 23:09:40.028 # +new-epoch 1
8507:X 05 Feb 23:09:40.028 # +try-failover master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.098 # +vote-for-leader 0ffa476301677a36b9e83e4a3305df9837cb06ee 1
8507:X 05 Feb 23:09:40.109 # 192.168.159.10:26379 voted for e83812b0bad75bb5e50886b76363668a4fc0d1b7 1
8507:X 05 Feb 23:09:40.124 # 192.168.159.11:26379 voted for 0ffa476301677a36b9e83e4a3305df9837cb06ee 1
8507:X 05 Feb 23:09:40.165 # +elected-leader master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.165 # +failover-state-select-slave master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.272 # +selected-slave slave 192.168.159.12:6379 192.168.159.12 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.273 * +failover-state-send-slaveof-noone slave 192.168.159.12:6379 192.168.159.12 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:40.361 * +failover-state-wait-promotion slave 192.168.159.12:6379 192.168.159.12 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:41.121 # +promoted-slave slave 192.168.159.12:6379 192.168.159.12 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:41.121 # +failover-state-reconf-slaves master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:41.201 * +slave-reconf-sent slave 192.168.159.11:6379 192.168.159.11 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:42.157 * +slave-reconf-inprog slave 192.168.159.11:6379 192.168.159.11 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:42.343 # -odown master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:43.205 * +slave-reconf-done slave 192.168.159.11:6379 192.168.159.11 6379 @ mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:43.310 # +failover-end master mymaster 192.168.159.10 6379
8507:X 05 Feb 23:09:43.310 # +switch-master mymaster 192.168.159.10 6379 192.168.159.12 6379
8507:X 05 Feb 23:09:43.316 * +slave slave 192.168.159.11:6379 192.168.159.11 6379 @ mymaster 192.168.159.12 6379
8507:X 05 Feb 23:09:43.317 * +slave slave 192.168.159.10:6379 192.168.159.10 6379 @ mymaster 192.168.159.12 6379
8507:X 05 Feb 23:09:53.336 # +sdown slave 192.168.159.10:6379 192.168.159.10 6379 @ mymaster 192.168.159.12 6379
           

在 192.168.159.12 redis中 執行指令 set name zhang 其他節點 執行 get name 可以擷取到 zhang 如下:

127.0.0.1:6379> get name
"zhang"
127.0.0.1:6379> 
           

再次啟動 192.168.159.10(原來的master節點)發現節點狀态變為了 slave 如下

8507:X 05 Feb 23:18:11.923 # -sdown slave 192.168.159.10:6379 192.168.159.10 6379 @ mymaster 192.168.159.12 6379
           
[[email protected] bin]# ./redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.159.12
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:136084
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> 
           

哨兵+複制 才能組成redis 高可用

3、叢集(3.0以後的功能)

之前redis 中所有的資料都儲存在一個節點中,資料量大時會有性能問題。redis叢集會把資料分片儲存到多個節點,多個master共同儲存一份資料,每個master又都有自己的slave 和哨兵,如下圖

redis主從複制、哨兵機制和叢集

3.0之前實作方式:用戶端 根據key 的hash值對服務節點數量取模,進行資料分片

3.0之後 redis提供了分片的機制 用戶端不用做處理

slot(槽) 的概念 在redis叢集中一共會有16384個槽

根據key 的 crc16算法 ,得到的結果再對16384進行取模。假如有有三個節點 16384/3=5460

node 1 儲存槽位 0-5460

node2 儲存槽位5461-10922

node3 儲存槽位10923-15383

如果增加了節點 就會出現資料遷移 1-3個節點上都有一部分資料要遷移到新節點中。

需要人工遷移, 有一個腳本 redis-trib.rb

目前使用這種方案的比較少,因為3.0剛提供,3.0之前市面上提供了叢集方案如下。

1)redis shardding jedis用戶端支援shardding操作。 根據一緻性hash取模 實作

2)codis (豌豆莢提供的分片政策 目前 應用比較廣泛)基于redis2.8代碼分支開發了一個codis-server。內建了分片操作。

3)twemproxy

不管用哪種方案,增删節點時都會涉及到 資料的遷移。目前應用廣泛的解決方式就是 pre-shardding (預分片)

假如我隻需要三台redis服務,那麼我部署9台。每台伺服器上部署三台(共九個redis節點),這樣不用增加硬體,前期redis資料量不大時還可以提高cpu使用率。日後如果資料量變大,隻需要将每台機器上的三台redis服務遷移到新的伺服器上就可以了。不用進行任何資料分片處理

繼續閱讀