1. 程式人生 > >redis3.2.8 sentinel模式一主兩從高可用環境搭建測試

redis3.2.8 sentinel模式一主兩從高可用環境搭建測試

由於專案需要,研究了一下redis的叢集方式,記錄如下:

環境:centos7,由於是測試,我就把三個redis放在一臺機子上了。反正redis是單執行緒的,倒也無所謂。

redis叢集的方式有好幾種,分類下來其實大概是四種:

1.redis本身的叢集。redis3.x開始引入了redis-cluster,是redis官方推出的叢集方式,官方文件中也全面地說明了設計成當前這個鳥樣的原因,這個無可非議,然而這也帶來了redis-cluster本身無法保證能穩定地在正式生產環境中使用的幾個問題,例如無法解決腦裂問題、遷移困難(這貨用的不是一致性雜湊,而是引入了類似於HashMap那樣雜湊槽的概念)、去中心化設計帶來的多數選舉的問題,以及我們組的leader被坑了的一個節點死掉,叢集全部不能用的問題。由於不能保證在正式環境中穩定使用,直接否決。

2.加代理。加代理本身可選的就比較多了,比較常用的就有豌豆莢的codis、推特的Twemproxy。其中Twemproxy本身配置使用比較簡單,應用廣泛,但是卻不能平滑地增加刪除redis節點,一旦增加節點,工作量很大;而且這貨沒有監控介面。與之相反,codis就有監控介面,而且能平滑地增減redis節點,相對來說更優秀。增加一層代理要增加對訪問的轉發,肯定會降低效率,但相對來講還是可以接受的。對比之下我就先測試了codis,後文講放棄codis的原因。

3. 使用之前的哨兵模式。哨兵模式既可以用來做高可用,也可以結合高可用做叢集分片。確實是個好東西,但依然有些問題,那就是jedis。jedis支援叢集,然而這貨的SharedJedisPool碰到哨兵模式就蒙圈了,不知道為何jedis官方選擇忽略對這個被廣泛用於redis叢集的方案的支援。好在有人寫了對應的連線池

分片Sentinel連線池實現,這玩意兒估計用著就飛起了。我沒用分片叢集,直接用的是sentinel支援的高可用,一主多從的配置,後文講原因。

4.自己分片。這個很猛的,不過現在的敏捷開發階段不太適用這種方式,這玩意兒考慮的問題比較多,週期拉的太長會耽誤專案進度的。下了班之餘可以玩玩。

以上四種方式中,我首先測試的是codis,即第二種方案。對codis的測試可謂一波三折。codis是用go語言寫的,安裝go環境就夠折騰的;之後搭建zookeeper叢集倒是很順利,但隨即發現github下載地址總是無法下載release版的codis,無奈通過centos命令列下載原始碼自己編譯。好不容易編譯完畢,配置的複雜又讓我眼前一黑,艱苦地搞定之後,死活啟動不起來。無奈之下放棄codis。codis是個好東西,不過依賴環境繁雜也就罷了,本身的配置有些太麻煩了,怪不得很多部落格裡面都寫到,聯絡了codis的作者,看來不聯絡要費好長時間還未必能搞定。

放棄的時候我想起了leader的話,leader說咱們做的這個玩意兒壓力沒那麼大,追求的是穩定性。好,方向直指高可用,於是我直奔哨兵模式就過去了。sentinel的分片可以後續考慮,先搞定高可用,一主多從上上上。本文就是記錄的這個過程。

步驟一:安裝redis

我扒拉了一臺正在用的測試伺服器,開始搞測試。為了便於隨後刪除測試的東西,我把redis都裝在根目錄下建立的一個目錄裡了。

下載redis-3.2.8.tar.gz,由於不能直接下載,我到官網下載的,放在這個目錄下。然後分出三個目錄,redis1、redis2、redis3

cd /crmtestXieHao
tar -zxvf redis-3.2.8.tar.gz  
mv redis-3.2.8 /crmtestXieHao/redis1
這樣就把一個redis解壓到了redis1目錄下。如法炮製,依次解壓了放到redis2、redis3下面。這樣就有了三臺redis的未編譯版本。

下面開始挨個編譯安裝,以redis1為例:

cd /crmtestXieHao/redis1/redis-3.2.8
make && make install && make test
上面這個命令在redis2、redis3目錄下的redis解壓目錄裡各執行一遍,編譯安裝redis就完畢了。其實不用make test也一樣,不過對我這樣一個強迫症患者來說,一定要搞好每一步。但是make test命令需要依賴一個tcl8.6.1-src.tar.gz的玩意兒,下載了安裝就行了,不費事兒。

另外,需要在redis1、redis2、redis3下各新建一個data目錄、temp目錄,分別用來作為redis的資料目錄和sentinel的目錄。

步驟二:配置redis.conf

安裝完畢就要開始配置了。由於是一主多從的架子,所以我選擇redis1為主,redis2、redis3為從。在每個redis解壓目錄下都有一個redis.conf,先修改主redis的配置。

bind 192.168.5.17
protected-mode no
port 6379
daemonize yes
pidfile "/var/run/redis_6379.pid"
dir "/crmtestXieHao/redis1/data"
slave-priority 100
appendonly yes
appendfsync everysec
從節點redis2的redis.conf配置
bind 192.168.5.17
protected-mode no
port 6380
daemonize yes
pidfile "/var/run/redis_6380.pid"
dir "/crmtestXieHao/redis2/data"
slaveof 192.168.5.17 6379
slave-read-only yes
slave-priority 90
appendonly yes
appendfsync everysec
從節點redis3的redis.conf配置
bind 192.168.5.17
protected-mode no
port 6381
daemonize yes
pidfile "/var/run/redis_6381.pid"
dir "/crmtestXieHao/redis3/data"
slaveof 192.168.5.17 6379
slave-read-only yes
slave-priority 80
appendonly yes
appendfsync everysec
步驟三:配置sentinel.conf

在每個redis的目錄下,與redis.conf並列的各有一個sentinel.conf檔案,這就是哨兵的配置。每個redis都有一個哨兵,其配置基本相同。分別羅列如下:

redis1下的sentinel.conf

protected-mode no
port 26379
dir "/crmtestXieHao/redis1/temp"
sentinel monitor redis1 192.168.5.17 6379 2
sentinel down-after-milliseconds redis1 10000
sentinel failover-timeout redis1 60000

redis2下的sentinel.conf

protected-mode no
port 26380
dir "/crmtestXieHao/redis2/temp"
sentinel monitor redis1 192.168.5.17 6379 2
sentinel down-after-milliseconds redis1 10000
sentinel failover-timeout redis1 60000

redis3下的sentinel.conf

protected-mode no
port 26381
dir "/crmtestXieHao/redis3/temp"
sentinel monitor redis1 192.168.5.17 6379 2
sentinel down-after-milliseconds redis1 10000
sentinel failover-timeout redis1 60000
步驟四:啟動redis和sentinel

依次啟動redis1、redis2、redis3

cd /crmtestXieHao/redis1/redis-3.2.8/src
./redis-server /crmtestXieHao/redis1/redis-3.2.8/redis.conf &
cd /crmtestXieHao/redis2/redis-3.2.8/src
./redis-server /crmtestXieHao/redis2/redis-3.2.8/redis.conf &
cd /crmtestXieHao/redis3/redis-3.2.8/src
./redis-server /crmtestXieHao/redis3/redis-3.2.8/redis.conf &
依次啟動每臺redis的哨兵
cd /crmtestXieHao/redis1/redis-3.2.8/src
./redis-sentinel /crmtestXieHao/redis1/redis-3.2.8/sentinel.conf &
cd /crmtestXieHao/redis2/redis-3.2.8/src
./redis-sentinel /crmtestXieHao/redis2/redis-3.2.8/sentinel.conf &
cd /crmtestXieHao/redis3/redis-3.2.8/src
./redis-sentinel /crmtestXieHao/redis3/redis-3.2.8/sentinel.conf &

步驟五:各個redis狀態檢視

redis1、redis2、redis3狀態檢視命令
cd /crmtestXieHao/redis1/redis-3.2.8/src
./redis-cli -h 192.168.5.17 -p 6379 info Replication
./redis-cli -h 192.168.5.17 -p 6380 info Replication
./redis-cli -h 192.168.5.17 -p 6381 info Replication
由於主redis是可讀可寫的,從redis是隻讀的,所以可以進入client往主redis裡塞入資料檢視
cd /crmtestXieHao/redis1/redis-3.2.8/src
./redis-cli -h 192.168.5.17 -p 6379
192.168.5.17:6379> set name xiehao
OK
192.168.5.17:6379> get name
"xiehao"
從redis測試:
./redis-cli -h 192.168.5.17 -p 6380
192.168.5.17:6380> set aa  test
(error) READONLY You can't write against a read only slave.  
192.168.5.17:6380> get name
"xiehao"
步驟六:failover測試

將master主redis關閉以模擬掛機
./redis-cli -h 192.168.5.17 -p 6379
192.168.5.17:6379> PING
PONG
192.168.5.17:6379> SHUTDOWN
not connected>
[[email protected] src]# 23841:X 05 May 07:55:45.653 # +sdown master redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.679 # +sdown master redis1 192.168.5.17 6379
23827:X 05 May 07:55:45.708 # +sdown master redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.750 # +odown master redis1 192.168.5.17 6379 #quorum 2/2
23833:X 05 May 07:55:45.750 # +new-epoch 1
23833:X 05 May 07:55:45.750 # +try-failover master redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.766 # +vote-for-leader bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 1
23841:X 05 May 07:55:45.783 # +new-epoch 1
23827:X 05 May 07:55:45.783 # +new-epoch 1
23827:X 05 May 07:55:45.799 # +vote-for-leader bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 1
23841:X 05 May 07:55:45.799 # +vote-for-leader bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 1
23827:X 05 May 07:55:45.799 # +odown master redis1 192.168.5.17 6379 #quorum 3/2
23827:X 05 May 07:55:45.799 # Next failover delay: I will not start a failover before Fri May  5 07:57:46 2017
23833:X 05 May 07:55:45.799 # b570d53fe425a4bc6bcdd1a882c4e8a0a4cf0402 voted for bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 1
23833:X 05 May 07:55:45.799 # c0771e8b12ec534794e9e384ff99c787526d79ea voted for bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 1
23833:X 05 May 07:55:45.818 # +elected-leader master redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.818 # +failover-state-select-slave master redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.885 # +selected-slave slave 192.168.5.17:6381 192.168.5.17 6381 @ redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.885 * +failover-state-send-slaveof-noone slave 192.168.5.17:6381 192.168.5.17 6381 @ redis1 192.168.5.17 6379
23833:X 05 May 07:55:45.940 * +failover-state-wait-promotion slave 192.168.5.17:6381 192.168.5.17 6381 @ redis1 192.168.5.17 6379
23841:X 05 May 07:55:46.755 # +odown master redis1 192.168.5.17 6379 #quorum 3/2
23841:X 05 May 07:55:46.756 # Next failover delay: I will not start a failover before Fri May  5 07:57:46 2017
23833:X 05 May 07:55:46.887 # +promoted-slave slave 192.168.5.17:6381 192.168.5.17 6381 @ redis1 192.168.5.17 6379
23833:X 05 May 07:55:46.887 # +failover-state-reconf-slaves master redis1 192.168.5.17 6379
23833:X 05 May 07:55:46.957 * +slave-reconf-sent slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6379
23841:X 05 May 07:55:46.958 # +config-update-from sentinel bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 192.168.5.17 26380 @ redis1 192.168.5.17 6379
23841:X 05 May 07:55:46.958 # +switch-master redis1 192.168.5.17 6379 192.168.5.17 6381
23827:X 05 May 07:55:46.958 # +config-update-from sentinel bc2ff5fd48c6b477f2174127f9dd0f23fcef94cc 192.168.5.17 26380 @ redis1 192.168.5.17 6379
23827:X 05 May 07:55:46.958 # +switch-master redis1 192.168.5.17 6379 192.168.5.17 6381
23841:X 05 May 07:55:46.958 * +slave slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6381
23841:X 05 May 07:55:46.958 * +slave slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23827:X 05 May 07:55:46.958 * +slave slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6381
23827:X 05 May 07:55:46.958 * +slave slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23833:X 05 May 07:55:47.909 # -odown master redis1 192.168.5.17 6379
23833:X 05 May 07:55:47.910 * +slave-reconf-inprog slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6379
23833:X 05 May 07:55:47.910 * +slave-reconf-done slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6379
23833:X 05 May 07:55:47.967 # +failover-end master redis1 192.168.5.17 6379
23833:X 05 May 07:55:47.967 # +switch-master redis1 192.168.5.17 6379 192.168.5.17 6381
23833:X 05 May 07:55:47.967 * +slave slave 192.168.5.17:6380 192.168.5.17 6380 @ redis1 192.168.5.17 6381
23833:X 05 May 07:55:47.967 * +slave slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23827:X 05 May 07:55:56.999 # +sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23841:X 05 May 07:55:57.012 # +sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23833:X 05 May 07:55:57.993 # +sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
可以看到日誌
23833:X 05 May 07:55:47.967 # +switch-master redis1 192.168.5.17 6379 192.168.5.17 6381
哨兵將掛機的6379主redis切換成6381的redis節點。哨兵模式下,系統會根據我們配置在redis.conf中的slave-priority,選出slave-priority值最小的推舉成新的master主節點。如果之前的主節點再次啟動,將會以從節點的形式掛到主節點下,我們啟動試試
cd /crmtestXieHao/redis1/redis-3.2.8/src
./redis-server /crmtestXieHao/redis1/redis-3.2.8/redis.conf &
[4] 23854
[[email protected] src]# 23827:X 05 May 07:57:30.679 # -sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23841:X 05 May 07:57:30.711 # -sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23833:X 05 May 07:57:30.787 # -sdown slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
23827:X 05 May 07:57:40.655 * +convert-to-slave slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
^C
[4]+  Done                    ./redis-server /crmtestXieHao/redis1/redis-3.2.8/redis.conf
可以看到log資訊
 +convert-to-slave slave 192.168.5.17:6379 192.168.5.17 6379 @ redis1 192.168.5.17 6381
之前的主節點重啟之後成為了從節點。我們可以從客戶端看看狀態
./redis-cli -h 192.168.5.17 -p 6379 info Replication
# Replication
role:slave
master_host:192.168.5.17
master_port:6381
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:27780
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
嘗試從客戶端放入資料看看:
./redis-cli -h 192.168.5.17 -p 6379
192.168.5.17:6379> set aa test
(error) READONLY You can't write against a read only slave.
192.168.5.17:6379> get name
"xiehao"
192.168.5.17:6379>
 經過以上步驟,基本的sentinel下的高可用一主多從redis就配置完成了。
不過說起來,Redis這貨越來越不盡如人意了,在叢集越來越被重視的今天,不能迅速地跟從潮流就意味著死亡。但差了這麼多資料,越來越覺得redis這種記憶體資料庫的出現極有可能是由於硬體發展跟不上潮流導致的,資料庫的瓶頸也是一個很重要的推手,畢竟高頻資料的大量操作很多都卡在資料庫上,才產生了這種玩意兒,如果硬體的發展能夠跟上需求的話,記憶體資料庫有可能會消失的。
啥時候有時間,看看redis的原始碼,研究研究。