上篇說到了Redis安裝、運行。今天來看一看Redis的主從複製、Sentinel;java
在Master
上修改redis.conf
nginx
// 不想用密碼,因此把保護模式設置爲no protected-mode no // 其實master上不須要配置什麼,這裏只是取消了保護模式
在Slave1
和Slave2
上修改redis.conf
redis
// 一樣關閉保護模式 protected-mode no // 設置本機是誰的slave slaveof master的ip 6379 // 當配置了slaveof後,下面這條控制本機只能讀 slave-read-only yes
// 簡單設置3個鏈接池 private static final JedisPool masterPool; private static final JedisPool slavePool1; private static final JedisPool slavePool2; static { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最多能夠有10個鏈接 jedisPoolConfig.setMaxTotal(10); jedisPoolConfig.setMaxIdle(5); jedisPoolConfig.setMinIdle(5); masterPool = new JedisPool(jedisPoolConfig, "111.111.111.111"); slavePool1 = new JedisPool(jedisPoolConfig, "111.111.111.112"); slavePool2 = new JedisPool(jedisPoolConfig, "111.111.111.113"); } public static void main(String[] args) throws Exception { // 簡單使用,經過try-with-resource try (Jedis jedis = masterPool.getResource()) { jedis.get("key1"); } catch (Exception e) { e.printStackTrace(); } }
Redis須要讀寫分離嗎?
可能你們會思考過這樣一個問題,在MySQL中經常使用的讀寫分離,在Redis這種內存DB中是否還會須要?shell
反對者的觀點是:Redis是內存存儲,讀寫都很是快,若是將讀且分離到Master
和Slaves
上不只可能形成主從不一樣步的麻煩,甚至不見得會提高整個DB的處理能力和速度。ruby
同意者的觀點是:Redis提供的Master
和Slave
複製功能;官網中的介紹服務器
Replication can be used both for scalability, in order to have multiple slaves for read-only queries (for example, slow O(N) operations can be offloaded to slaves), or simply for data redundancy.markdown
甚至配置文件中的參數slave-read-only yes
都在提示着使用者,Redis給你提供了讀寫分離的功能。因此,爲何不要用呢?tcp
通過思考事後,我以爲:分佈式
1 若是使用者的業務數據量不大,則徹底沒必要作讀寫分離,讀寫均在
Master
上作便可。可是主從複製仍是須要的,可將Slave
做爲簡單的數據轉儲。
2 若是使用者的業務數據量比較大,只用一個物理機Master
承擔讀寫已不能知足業務或性能的需求,那麼則能夠作讀且分離。即,在項目代碼中封裝一下對Redis的操做(如封裝Jedis操做),將寫操做映射給Master
,將讀操做按照你本身定義的分配策略,映射給某個Slave
。性能
一個企業級系統最重要的指標就是「可用性」和「高性能」。
顯然,上面的主從複製、讀寫分離可以簡單的提供「高性能」,但也只是提高了「讀」的性能,並不能擴展「寫」。(寫的擴展這裏暫且不表)
另外一方面,「可用性」也是極其重要的。如上結構可用性並不高,一旦Master
宕機則Redis將當即不可寫,Slave
將只剩下舊數據,系統隨即不可用。
必然的,Redis提供了高可用(High Availability)方案,其中之一就是Sentinel-哨兵。
見名知意,它是Redis提供的哨兵程序,它是分佈式程序,能夠這樣描述它們:
哨兵通常是好幾個一塊兒站崗,他們共同監視一個
Master
以及其Slaves
。當哨兵看到Master
掛掉了,他們就會互相確認有沒有看走眼,一旦多數哨兵都說它掛了,那麼他們就能得出結論:Master
掛了。
此時第一個發現的Sentinel會負責進行自動故障遷移,它會當即在Slaves
中選出一個擔任Master
,全部Slaves
從屬於新Master
,全部客戶端對Master
的操做轉而到這臺新Master
上。
Sentinel的主要工做以下:
監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運做正常。
提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 能夠經過 API 向管理員或者其餘應用程序發送通知。
自動故障遷移(Automatic failover): 當一個主服務器不能正常工做時, Sentinel 會開始一次自動故障遷移操做, 它會將失效主服務器的其中一個從服務器升級爲新的主服務器, 並讓失效主服務器的其餘從服務器改成複製新的主服務器; 當客戶端試圖鏈接失效的主服務器時, 集羣也會向客戶端返回新主服務器的地址, 使得集羣可使用新主服務器代替失效服務器。
哨兵應該被放在獨立的服務器上,最好最少應該有3個哨兵(3臺服務器)。
配置文件sentinel.conf
// 26379模式是sentinel的運行端口,6379是redis-server的 port 26379 // 做爲守護進程 daemonize yes // 工做目錄,設置到你統一規劃的地方 dir /tmp // log文件 dir /.... // protected-mode必需要設置的,不設置不行 protected-mode no // 配置監視的Master,注意無需配置其Slave,Sentinel會本身去詢問Master // sentinel monitor master-name ip redis-port quorum // quorum 哨兵們認爲master客觀死亡(Objectively Down)所須要的法定人。不管是否設置這個值,想要啓動failover都必須有多數哨兵贊成 sentinel monitor yewu01 127.0.0.1 6379 2 // 若是30000 ms後master仍是不迴應,就說明Master處於主觀死亡(Subjectively Down) sentinel down-after-milliseconds yewu01 30000 // 當發生failover的同時,1個slave開始與新master進行同步。意思是:此slave開始接收master的RDB文件而不能對外提供服務了,而其它slave還能對外服務(具體可否對外服務看第二個//),因此越少意味着redis能越快恢復對外服務 // 同時還要搭配配置slave的redis.conf中的 slave-serve-stale-data參數,指定是否可用過時數據 sentinel parallel-syncs yewu01 1 // 執行failover多久算failover超時 sentinel failover-timeout yewu01 180000
運行sentinel
雖然 Redis Sentinel 釋出爲一個單獨的可執行文件 redis-sentinel
, 但實際上它只是一個運行在特殊模式下的 Redis 服務器, 你能夠在啓動一個普通 Redis 服務器時經過給定 --sentinel
選項來啓動 Redis Sentinel 。
// 1. 用redis-server加參數 --sentinel的方式啓動 redis-server /path/to/sentinel.conf --sentinel // 2. 用redis-sentinel 方式啓動 redis-sentinel /path/to/sentinel.conf //注意!注意!注意!不要忘記在防火牆添加端口,個人是CentOS7,因此以下 firewall-cmd --zone=public --add-port=26379/tcp --permanent
查看狀態
用redis-cli -h <hostname> -p 26379
登陸到Sentinel;
Sentinel 可接受的命令(官網頁面搜索Sentinel API):
PING
:返回 PONG 。SENTINEL masters
:列出全部被監視的主服務器,以及這些主服務器的當前狀態。SENTINEL master <master name>
:特定主服務器的當前狀態。SENTINEL slaves <master name>
:列出給定主服務器的全部從服務器,以及這些從服務器的當前狀態。SENTINEL sentinels <master name>
Show a list of sentinel instances for this master, and their state.SENTINEL get-master-addr-by-name <master name>
: 返回給定名字的主服務器的 IP 地址和端口號。 若是這個主服務器正在執行故障轉移操做, 或者針對這個主服務器的故障轉移操做已經完成, 那麼這個命令返回新的主服務器的 IP 地址和端口號。SENTINEL reset <pattern>
: 重置全部名字和給定模式 pattern 相匹配的主服務器。 pattern 參數是一個 Glob 風格的模式。 重置操做清楚主服務器目前的全部狀態, 包括正在執行中的故障轉移, 並移除目前已經發現和關聯的, 主服務器的全部從服務器和 Sentinel 。SENTINEL failover
: 當主服務器失效時, 在不詢問其餘 Sentinel 意見的狀況下, 強制開始一次自動故障遷移 (不過發起故障轉移的 Sentinel 會向其餘 Sentinel 發送一個新的配置,其餘 Sentinel 會根據這個配置進行相應的更新)。sentinel.conf
配置被改變
每當一個Sentinel啓動後,它就會修改並通知其它Sentinel同時修改自身的sentinel.conf
文件,例如:
生成一個myid
sentinel myid 0f9bd55b18aa54a5f5efc6fb7b3371da56d48d4a
文件最後會加上以下:
# Generated by CONFIG REWRITE sentinel known-sentinel yewu01 192.168.0.1 26379 58a141a0f97669925bcc84e3a3b3dbc8602dea99 sentinel known-sentinel yewu01 192.168.0.2 26379 a0fbf10df21374f8b5cac1f410d9df3b26618575 sentinel current-epoch 0
執行pkill redis-sever
關掉Master
觀察Sentinel日誌以下:
這是一個被選爲failover
執行者的sentinel的日誌,英文挺清晰明瞭的就不翻譯了:
6480:X 14 Feb 19:46:54.746 # +sdown master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:54.798 # +odown master yewu01 10.173.244.98 6379 #quorum 3/2 6480:X 14 Feb 19:46:54.798 # +new-epoch 1 6480:X 14 Feb 19:46:54.798 # +try-failover master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:54.807 # +vote-for-leader 214bd3df8363327488cd8c430166cf48cd2ab33a 1 6480:X 14 Feb 19:46:54.819 # f7462491e6881da2c1efbfd6465ece6380c653cf voted for 214bd3df8363327488cd8c430166cf48cd2ab33a 1 6480:X 14 Feb 19:46:54.823 # 6c95942bbcc39a0703ec5d54a76d6a696a500a17 voted for 214bd3df8363327488cd8c430166cf48cd2ab33a 1 6480:X 14 Feb 19:46:54.907 # +elected-leader master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:54.907 # +failover-state-select-slave master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:54.974 # +selected-slave slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:54.974 * +failover-state-send-slaveof-noone slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:55.057 * +failover-state-wait-promotion slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:55.534 # +promoted-slave slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:55.534 # +failover-state-reconf-slaves master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:55.581 * +slave-reconf-sent slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:55.957 # -odown master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:56.041 * +slave-reconf-inprog slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:56.042 * +slave-reconf-done slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:56.096 # +failover-end master yewu01 10.173.244.98 6379 6480:X 14 Feb 19:46:56.096 # +switch-master yewu01 10.173.244.98 6379 10.174.249.145 6379