Redis主從模式配置:
Redis的主從模式配置是非常簡單的,首先我們需要有2個可運行的redis環境:
master node : 192.168.56.101 8887
slave node: 192.168.56.102 7777
我們只要在slave 節點的配置文件中,找到 slaveof開頭
然后修改為:(master的ip與端口)
slaveof 192.168.56.101 8777
這樣就可以了,下面我們來驗證一下,首先啟用master和slave的redis服務,然后登錄redis-cli,輸入info
然后看下192.168.56.101:8887的信息,紅色的地方,表示當前節點為master節點,有幾個從節點和從節點的信息
192.168.56.101:8887> info
# Replication role:master connected_slaves:1 slave0:ip=192.168.56.102,port=7777,state=online,offset=568,lag=1 master_repl_offset:568 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:567
在看192.168.56.102:7777的信息
192.168.56.102:7777> info
# Replication role:slave master_host:192.168.56.101 master_port:8887 master_link_status:up master_last_io_seconds_ago:10 master_sync_in_progress:0 slave_repl_offset:918 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
在master,創建一個key-value:
192.168.56.101:8887> set aa aa OK
在slave節點
192.168.56.102:7777> get aa "aa"
因為默認的設置從節點是不能寫只能讀的,所以如果要在從節點寫東西是報錯的,如下:
192.168.56.102:7777> set aa 2a (error) READONLY You can't write against a read only slave.
這樣一來主從模式就好了,如果要有多個從節點,只要改變他們的slaveof的配置就行了。
當然如果只這樣配置,在生產上面是沒有多大用處的,因為如果無論master節點還是slave節點掛了,我們都要手動啟動來讓他繼續恢復工作,那么能不能讓他自動恢復呢?比如master掛掉了,在slave節點中選一個節點自動更換成master。根據這個需求,redis在2.4之后出現了sentinel,其目的就是監控主從節點的健壯性,然后自動選舉master節點下面就來看看如何配置sentinel。
Redis 的 Sentinel配置
一、Sentinel介紹
Sentinel是Redis的高可用性(HA)解決方案,由一個或多個Sentinel實例組成的Sentinel系統可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,並在被監視的主服務器進行下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器,然后由新的主服務器代替已下線的主服務器繼續處理命令請求。Redis提供的sentinel(哨兵)機制,通過sentinel模式啟動redis后,自動監控master/slave的運行狀態,基本原理是:心跳機制+投票裁決
- 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
- 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
- 自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 並讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器
二、Sentinel的主從原理
三、Redis Sentinel配置
這里采用了一個master 一個slave 一個sentinel
master 的redis.conf配置,找到下面的並修改:
port 8887 bind 192.168.56.101
slave 的redis.conf配置,找到下面的並修改,如果master節點設置了密碼,下面紅色部分要加上
port 7777 bind 192.168.56.102 slaveof 192.168.56.101 8887
masterauth master的密碼
sentinel的sentinel.conf 配置
port 9999 protected-mode yes bind 192.168.56.101 dir /tmp sentinel monitor mymaster 192.168.56.101 8887 1 sentinel down-after-milliseconds mymaster 5000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 15000
tips:
如果停掉master 后,sentinel 顯示足夠數量的 sdown 后,沒有出現odown或try-failover,則檢查密碼等配置是否正確
如果停掉master后,試圖切換的時候出現 failover-abort-not-elected
1)如果redis實例沒有配置
protected-mode yes
bind 192.168.56.101
則在sentinel 配置文件加上
protected-mode no
2)如果redis實例有配置
protected-mode yes
bind 192.168.56.101
則在sentinel 配置文件加上
protected-mode yes
bind 192.168.56.101
上面的配置都弄好之后,分別啟動master、slave、sentinel(前面2個是redis-service 啟動,后面是redis-sentinel)服務,然后我們可以redis-cli查看對於的info信息(跟上面主從操作是一樣的)
master節點
[root@localhost 8887]# ./redis-cli -h 192.168.56.101 -p 8887 192.168.56.101:8887> info …… # Replication role:master connected_slaves:1 slave0:ip=192.168.56.102,port=7777,state=online,offset=6503,lag=1 master_repl_offset:6647 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:6646 ……
slave節點
[root@localhost 7777]# ./redis-cli -h 192.168.56.102 -p 7777 192.168.56.102:7777> info …… # Replication role:slave master_host:192.168.56.101 master_port:8887 master_link_status:up master_last_io_seconds_ago:10 master_sync_in_progress:0 slave_repl_offset:918 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 ……
sentinel節點信息
[root@localhost 8887]# ./redis-cli -h 192.168.56.101 -p 9999 192.168.56.101:9999> info …… # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=192.168.56.101:8887,slaves=1,sentinels=1 ……
下面我們把master節點給干掉,
192.168.56.101:8887> SHUTDOWN not connected>
這個時候,在sentinel界面會輸出下面的信息:
4338:X 05 Jun 14:57:27.313 # +sdown master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.313 # +odown master mymaster 192.168.56.101 8887 #quorum 1/1 4338:X 05 Jun 14:57:27.313 # +new-epoch 17 4338:X 05 Jun 14:57:27.313 # +try-failover master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.317 # +vote-for-leader 9354edabc95f19b3d99991f0877d0e66ada04e5b 17 4338:X 05 Jun 14:57:27.317 # +elected-leader master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.317 # +failover-state-select-slave master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.384 # +selected-slave slave 192.168.56.102:7777 192.168.56.102 7777 @ mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.384 * +failover-state-send-slaveof-noone slave 192.168.56.102:7777 192.168.56.102 7777 @ mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:27.450 * +failover-state-wait-promotion slave 192.168.56.102:7777 192.168.56.102 7777 @ mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:28.255 # +promoted-slave slave 192.168.56.102:7777 192.168.56.102 7777 @ mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:28.255 # +failover-state-reconf-slaves master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:28.317 # +failover-end master mymaster 192.168.56.101 8887 4338:X 05 Jun 14:57:28.317 # +switch-master mymaster 192.168.56.101 8887 192.168.56.102 7777 4338:X 05 Jun 14:57:28.318 * +slave slave 192.168.56.101:8887 192.168.56.101 8887 @ mymaster 192.168.56.102 7777
現在我們在查看以前的slave節點:
192.168.56.102:7777> info …… # Replication role:master 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 ……
這個時候以前的slave變成了master,所以現在沒有從節點了,所以 connected_slaves:0 ,下面我們把干掉的192.168.56.101 8887服務給啟用,然后在查看現在的master,
192.168.56.102:7777> info …… # Replication role:master connected_slaves:1 slave0:ip=192.168.56.101,port=8887,state=online,offset=1334,lag=0 master_repl_offset:1334 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:1333 ……
這個時候可以看到,多出了一個slave,即以前的master變成了從節點,我們再看以前的master節點信息:
192.168.56.101:8887> info …… # Replication role:slave master_host:192.168.56.102 master_port:7777 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:7364 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 ……
上面就是sentinel自動的對redis的主從切換的配置,以及信息的變化,下面來看在Spring中如何配置。
四、Spring中 Sentinel配置
pom.xml文件中添加依賴包
<!--redis 支持java的語言 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- spring data redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.1.RELEASE</version> </dependency>
spring-redis.xml的配置:
1 <!--redis哨兵 --> 2 <bean id="redisSentinelConfiguration" 3 class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> 4 <property name="master"> 5 <bean class="org.springframework.data.redis.connection.RedisNode"> 6 <property name="name" value="mymaster"/> 7 </bean> 8 </property> 9 <property name="sentinels"> 10 <set> 11 <bean class="org.springframework.data.redis.connection.RedisNode"> 12 <constructor-arg name="host" value="192.168.56.101"/> 13 <constructor-arg name="port" value="9999"/> 14 </bean> 15 </set> 16 </property> 17 </bean> 18 19 <bean id="jedisConnFactory" 20 class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 21 <!--<property name="hostName" value="${redis.host}"/>--> 22 <!--<property name="port" value="${redis.port}"/>--> 23 <!--<property name="password" value="${redis.password}"/>--> 24 <!--<property name="usePool" value="false"/>--> 25 <!--<property name="poolConfig" ref="poolConfig"/>--> 26 <constructor-arg name="sentinelConfig" ref="redisSentinelConfiguration"/> 27 </bean> 28 29 <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> 30 <property name="connectionFactory" ref="jedisConnFactory"/> 31 </bean>
tips:
第25行如果我們不配poolConfig的話,也不要把第24行的usePool改成false,如果把usePool改成false,那么上面的哨兵配置好像就無效了。
Sentinel模式下的幾個事件
- +reset-master :主服務器已被重置。
- +slave :一個新的從服務器已經被 Sentinel 識別並關聯。
- +failover-state-reconf-slaves :故障轉移狀態切換到了 reconf-slaves 狀態。
- +failover-detected :另一個 Sentinel 開始了一次故障轉移操作,或者一個從服務器轉換成了主服務器。
- +slave-reconf-sent :領頭(leader)的 Sentinel 向實例發送了 [SLAVEOF](/commands/slaveof.html) 命令,為實例設置新的主服務器。
- +slave-reconf-inprog :實例正在將自己設置為指定主服務器的從服務器,但相應的同步過程仍未完成。
- +slave-reconf-done :從服務器已經成功完成對新主服務器的同步。
- -dup-sentinel :對給定主服務器進行監視的一個或多個 Sentinel 已經因為重復出現而被移除 —— 當 Sentinel 實例重啟的時候,就會出現這種情況。
- +sentinel :一個監視給定主服務器的新 Sentinel 已經被識別並添加。
- +sdown :給定的實例現在處於主觀下線狀態。
- -sdown :給定的實例已經不再處於主觀下線狀態。
- +odown :給定的實例現在處於客觀下線狀態。
- -odown :給定的實例已經不再處於客觀下線狀態。
- +new-epoch :當前的紀元(epoch)已經被更新。
- +try-failover :一個新的故障遷移操作正在執行中,等待被大多數 Sentinel 選中(waiting to be elected by the majority)。
- +elected-leader :贏得指定紀元的選舉,可以進行故障遷移操作了。
- +failover-state-select-slave :故障轉移操作現在處於 select-slave 狀態 —— Sentinel 正在尋找可以升級為主服務器的從服務器。
- no-good-slave :Sentinel 操作未能找到適合進行升級的從服務器。Sentinel 會在一段時間之后再次嘗試尋找合適的從服務器來進行升級,又或者直接放棄執行故障轉移操作。
- selected-slave :Sentinel 順利找到適合進行升級的從服務器。
- failover-state-send-slaveof-noone :Sentinel 正在將指定的從服務器升級為主服務器,等待升級功能完成。
- failover-end-for-timeout :故障轉移因為超時而中止,不過最終所有從服務器都會開始復制新的主服務器(slaves will eventually be configured to replicate with the new master anyway)。
- failover-end :故障轉移操作順利完成。所有從服務器都開始復制新的主服務器了。
- +switch-master :配置變更,主服務器的 IP 和地址已經改變。 這是絕大多數外部用戶都關心的信息。
- +tilt :進入 tilt 模式。
- -tilt :退出 tilt 模式。
以上就是redis的主從及哨兵的配置,如果有錯,謝謝指出。
參考:http://wosyingjun.iteye.com/blog/2289593
http://www.cnblogs.com/yjmyzz/p/redis-sentinel-sample.html
http://blog.csdn.net/yypzye/article/details/52281282
本實項目下載:https://github.com/eoooxy/anhoo