redis主從、哨兵、集羣

一、主從

通過持久化功能,Redis保證了即使在服務器重啓的情況下也不會損失(或少量損失)數據,因爲持久化會把內存中數據保存到硬盤上,重啓會從硬盤上加載數據。
。但是由於數據是存儲在一臺服務器上的,如果這臺服務器出現硬盤故障等問題,也會導致數據丟失。爲了避免單點故障,通常的做法是將數據庫複製多個副本以部署在不同的服務器上,這樣即使有一臺服務器出現故障,其他服務器依然可以繼續提供服務。爲此, redis 提供了複製(replication)功能,可以實現當一臺數據庫中的數據更新後,自動將更新的數據同步到其他數據庫上。

在複製的概念中,數據庫分爲兩類,一類是主數據庫(master),另一類是從數據庫[1] (slave)。主數據庫可以進行讀寫操作,當寫操作導致數據變化時會自動將數據同步給從數據庫。而從數據庫一般是隻讀的,並接受主數據庫同步過來的數據。一個主數據庫可以擁有多個從數據庫,而一個從數據庫只能擁有一個主數據庫。

主從數據庫的配置

master  slave
主不用配置,從redis的conf文件加入 slaveof ip port 就可以了
或者從redis啓動時  redis-server –port 6380 –slaveof 127.0.0.1 6379
    從數據庫一般是隻讀,可以改爲可寫,但寫入的數據很容易被主同步沒,所以還是隻讀就可以。
也可以在運行是使用slaveof ip port命令,停止原來的主,切換成剛剛設置的主  slaveof no one會把自己變成主

複製原理

當從數據庫啓動時,會向主數據庫發送sync命令,主數據庫接收到sync後開始在後臺報錯快照rdb,在保存快照期間受到的命名緩存起來,當快照完成時,主數據庫會將快照和緩存的命令一塊發送給從。複製初始化結束。
之後,主每受到1個命令就同步發送給從。
當出現斷開重連後,2.8之後的版本會將斷線期間的命令傳給重數據庫。增量複製

主從複製是樂觀複製,當客戶端發送寫執行給主,主執行完立即將結果返回客戶端,並異步的把命令發送給從,從而不影響性能。也可以設置至少同步給多少個從主纔可寫。
無硬盤複製:如果硬盤效率低將會影響複製性能,2.8之後可以設置無硬盤複製,repl-diskless-sync yes

二、哨兵

當主數據庫遇到異常中斷服務後,開發者可以通過手動的方式選擇一個從數據庫來升格爲主數據庫,以使得系統能夠繼續提供服務。然而整個過程相對麻煩且需要人工介入,難以實現自動化。 爲此,Redis 2.8中提供了哨兵工具來實現自動化的系統監控和故障恢復功能。
哨兵的作用就是監控redis主、從數據庫是否正常運行,主出現故障自動將從數據庫轉換爲主數據庫。

顧名思義,哨兵的作用就是監控Redis系統的運行狀況。它的功能包括以下兩個。

    (1)監控主數據庫和從數據庫是否正常運行。
    (2)主數據庫出現故障時自動將從數據庫轉換爲主數據庫。

image
可以用info replication查看主從情況
例子:
1主2從  1哨兵,可以用命令起也可以用配置文件裏
可以使用雙哨兵,更安全,
redis-server –port 6379
redis-server –port 6380 –slaveof 192.168.0.167 6379
redis-server –port 6381 –slaveof 192.168.0.167 6379


redis-sentinel sentinel.conf
哨兵配置文件
    sentinel.conf
        sentinel monitor mymaster 192.168.0.167 6379 1 

其中mymaster表示要監控的主數據庫的名字,可以自己定義一個。這個名字必須僅由大小寫字母、數字和“.-_”這 3 個字符組成。後兩個參數表示主數據庫的地址和端口號,這裏我們要監控的是主數據庫6379。
注意:

    1、使用時不能用127.0.0.1,需要用真實IP,不然Java程序通過哨兵會連到java程序所在的機器(127.0.0.1 )

    2、配置哨兵監控一個系統時,只需要配置其監控主數據庫即可,哨兵會自動發現所有複製該主數據庫的從數據庫

 

這樣哨兵就能監控主6379和從6380、6381,一旦6379掛掉,哨兵就會在2個從中選擇一個作爲主,根據優先級選,如果一樣就選個id小的,當6379再起來就作爲從存在。

主從切換過程:

(1)      slave leader升級爲master
(2)      其他slave修改爲新master的slave
(3)      客戶端修改連接
(4)      老的master如果重啓成功,變爲新master的slave


哨兵監控1主2從,停掉主,哨兵會選出1個從作爲主,變成1主1從。然而當我把原來的主再起來,它不會作爲從,只是個獨立的節點。

如果在新的主剛被選出來時,我把原來的主起來,它就能成爲新主的從節點。
如果在新的主選出來過一會再起原來的主,就不能成爲新主的從節點
或者在老的主起來後,重啓哨兵也能把它變成從,哨兵配置文件裏有,哨兵會執行“+convert-to-slave”

這很奇怪,我也沒弄明白是怎麼回事。


三、集羣

即使使用哨兵,redis每個實例也是全量存儲,每個redis存儲的內容都是完整的數據,浪費內存且有木桶效應。爲了最大化利用內存,可以採用集羣,就是分佈式存儲。即每臺redis存儲不同的內容,
共有16384個slot。每個redis分得一些slot,hash_slot = crc16(key) mod 16384 找到對應slot,鍵是可用鍵,如果有{}則取{}內的作爲可用鍵,否則整個鍵是可用鍵
集羣至少需要3主3從,且每個實例使用不同的配置文件,主從不用配置,集羣會自己選。

修改每個實例的配置文件:

    cluster-enabled yes  –開啓集羣

    cluster-config-file nodes-6382.conf –集羣配置文件名,每個實例配置的要不同,redis會根據文件名自動新建

用集羣工具創建集羣:

我們可以用集羣工具進行集羣,該工具是redis源碼包中,用ruby編寫,所以需要先安裝ruby。

1、安裝rubygems

    yum install ruby
    yum install rubygems 
    gem install redis

 

2、把6個redis實例都起來,每個實例的集羣都打開。

3、redis安裝目錄的src執行./redis-trib.rb create –replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385

提示信息如下

  1. Connecting to node 127.0.0.1:6380: OK   
  2. Connecting to node 127.0.0.1:6381: OK   
  3. Connecting to node 127.0.0.1:6382: OK   
  4. Connecting to node 127.0.0.1:6383: OK   
  5. Connecting to node 127.0.0.1:6384: OK   
  6. Connecting to node 127.0.0.1:6385: OK   
  7. >>> Performing hash slots allocation on 6 nodes…   
  8. Using 3 masters:   
  9. 127.0.0.1:6380   
  10. 127.0.0.1:6381   
  11. 127.0.0.1:6382   
  12. Adding replica 127.0.0.1:6383 to 127.0.0.1:6380   
  13. Adding replica 127.0.0.1:6384 to 127.0.0.1:6381   
  14. Adding replica 127.0.0.1:6385 to 127.0.0.1:6382   
  15. M: d4f906940d68714db787a60837f57fa496de5d12 127.0.0.1:6380 slots:0-5460 (5461 slots) master   
  16. M: b547d05c9d0e188993befec4ae5ccb430343fb4b 127.0.0.1:6381 slots:5461-10922 (5462 slots) master   
  17. M: 887fe91bf218f203194403807e0aee941e985286 127.0.0.1:6382 slots:10923-16383 (5461 slots) master  
  18. S: e0f6559be7a121498fae80d44bf18027619d9995 127.0.0.1:6383 replicates d4f906940d68714db787a60837f57fa496de5d12   
  19. S: a61dbf654c9d9a4d45efd425350ebf720a6660fc 127.0.0.1:6384 replicates b547d05c9d0e188993befec4ae5ccb430343fb4b   
  20. S: 551e5094789035affc489db267c8519c3a29f35d 127.0.0.1:6385 replicates 887fe91bf218f203194403807e0aee941e985286   
  21. Can I set the above configuration? (type ’yes’ to accept):  
Connecting to node 127.0.0.1:6380: OK 
Connecting to node 127.0.0.1:6381: OK 
Connecting to node 127.0.0.1:6382: OK 
Connecting to node 127.0.0.1:6383: OK 
Connecting to node 127.0.0.1:6384: OK 
Connecting to node 127.0.0.1:6385: OK 
>>> Performing hash slots allocation on 6 nodes... 
Using 3 masters: 
127.0.0.1:6380 
127.0.0.1:6381 
127.0.0.1:6382 
Adding replica 127.0.0.1:6383 to 127.0.0.1:6380 
Adding replica 127.0.0.1:6384 to 127.0.0.1:6381 
Adding replica 127.0.0.1:6385 to 127.0.0.1:6382 
M: d4f906940d68714db787a60837f57fa496de5d12 127.0.0.1:6380 slots:0-5460 (5461 slots) master 
M: b547d05c9d0e188993befec4ae5ccb430343fb4b 127.0.0.1:6381 slots:5461-10922 (5462 slots) master 
M: 887fe91bf218f203194403807e0aee941e985286 127.0.0.1:6382 slots:10923-16383 (5461 slots) master
S: e0f6559be7a121498fae80d44bf18027619d9995 127.0.0.1:6383 replicates d4f906940d68714db787a60837f57fa496de5d12 
S: a61dbf654c9d9a4d45efd425350ebf720a6660fc 127.0.0.1:6384 replicates b547d05c9d0e188993befec4ae5ccb430343fb4b 
S: 551e5094789035affc489db267c8519c3a29f35d 127.0.0.1:6385 replicates 887fe91bf218f203194403807e0aee941e985286 
Can I set the above configuration? (type 'yes' to accept):


輸入yes,這樣集羣就建立了。

登錄任一臺redis,執行 info cluster,提示cluster_enabled:1

集羣過程:

首先redis-trib.rb會以客戶端的形式嘗試連接所有的節點,併發送PING命令以確定節點能夠正常服務。如果有任何節點無法連接,則創建失敗。同時發送 INFO 命令獲取每個節點的運行ID以及是否開啓了集羣功能(即cluster_enabled爲1)。 準備就緒後集羣會向每個節點發送 CLUSTER MEET命令,格式爲 CLUSTER MEET ip port,這個命令用來告訴當前節點指定ip和port上在運行的節點也是集羣的一部分,從而使得6個節點最終可以歸入一個集羣。

然後redis-trib.rb會分配主從數據庫節點,分配的原則是儘量保證每個主數據庫運行在不同的IP地址上,同時每個從數據庫和主數據庫均不運行在同一IP地址上,以保證系統的容災能力

3主3從,當1個主故障,大家會給對應的從投票,把從立爲主,若沒有從數據庫可以恢復則redis集羣就down了。

客戶端連接:

使用redis-cli -c -p 任意一個端口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章