redis cluster是redis提供的集羣模式。java
①能夠有多個master node,每一個master node 均可以掛載多個slave node。node
②讀寫分離的架構,對應每一個master node來講,寫就寫到master node,讀就從master node對應的slave node去讀。redis
③高可用。每一個master node都有多個 slave node,若是master node掛了,redis cluster機制就會自動將某個slave node切換成 master node。算法
因此redis cluster是 多master + 讀寫分離 + 高可用 的。只要基於edis cluster去搭建集羣,就能夠達到搭建 replication複製+主從架構+讀寫分離+哨兵集羣+高可用的 集羣架構。
api
①輸入數據量不多,主要是承載高併發的場景,單機就能夠了。緩存
②replication只有一個master node節點,多個slave node節點,全部節點上面的數據是同樣的,全部它能夠提升讀請求的吞吐量,而後能夠搭建一個Sentinal集羣去保證高可用,可是他沒法去擴容數據的存儲量。網絡
③redis cluster,能夠有多個master node去存儲不一樣的數據,全部他適合數據量特別大的場景,並且它能夠不用Sentinal集羣就能夠保證高可用。架構
①自動將數據分片,每一個master node上面存放一部分數據。併發
②提供內置的高可用支持,部分master node不可用時,仍是能夠工做的。負載均衡
③在redis cluster架構中,每一個redis要開發兩個端口,好比一個是6379,那麼另外一個就是加10000以後的端口號,好比16379。16379端口是用來進行節點間通訊的,也就是cluster bus集羣總線,cluster bus的通訊用來進行故障檢測、配置更新、故障轉移受權等操做。
④cluster bus用來一種二進制的協議,主要用於節點間進行高效的數據交換,佔用更少的網絡帶寬和處理時間。
####(2)最古老的hash算法
原理 :來了一個key以後,計算hash值,而後對master node節點數量取模,將數據哈希到不一樣的節點。
存在問題 :會致使大量緩存重建的問題。這種狀況下,一旦一個master宕機了,全部的請求過來以後,就會對新的節點數量(原節點數量-1)去取模,而後去相應的node取數據,這樣會致使請求走不到本來路由到的實例上面去,致使大量的key瞬間所有失效。
原理 :將全部master node落在一個圓環上面,而後,有一個key過來以後。一樣就是hash值,而後會用hash值在圓環對應的各個點上(每一個點都有一個hash值)去對比,看hash值落在那個位置,落在圓環上面之後,就會順時針旋轉去尋找距離本身最近的一個節點,數據的存儲於讀取都在該節點進行。
優點 :保證了任何一個master宕機,只會影響以前在那個master上面的數據,由於照着順時針走,所有在以前的master上面找不到了,master也宕機了,就會繼續順着順時針走到下一個master節點去。這樣就只會有一部分數據丟失。
存在問題 :假若有3個master,那麼就會丟失1/3的數據,這也是不少的。還會存在 緩存熱點的問題。 緩存熱點問題 :可能在某個hash區間內存在大值特別多,那麼就會致使大量的數據進入同一個master,形成該master出現瓶頸。
爲了解決上面的問題,在一致性哈希的基礎上增長了虛擬節點方案來處理。
原理 :給每一個master都作了一部分的虛擬節點,這部分虛擬節點也分佈在這個圓環上面,那麼在每一個區間內,大量的數據就會均勻的分佈在不一樣節點上。
原理 :①redis cluster有固定的16384個hash slot,每一個key計算CRC16值,而後多 16384取模,能夠獲取key對應的hash slot。
②redis cluster中每一個master節點都會持有一部分hash slot。
③增長一個master,就講其餘master的hash slot移動一部分給新加入的master。
④減小一個master,就將他的hash slot移動到其餘master上面去。
⑤移動hash slot的成本是很是低的。
⑥客戶端的api是能夠指定hash tag來讓數據走同一個hash slot的。
1.基礎通訊原理
①redis cluster節點間採起gossip協議進行通訊。
跟集中式不一樣,不是將集羣元數據(節點信息、故障等等)集中存儲在某個節點上,而是相互之間不斷通訊,保持整個集羣全部節點的數據是完整的。
②維護集羣的元數據的兩種方式對比
A.集中式
優勢 :元數據的更新和讀取,時效性很是好,一旦元數據出現了變動,當即就更新到集中式的存儲中。
缺點 :全部的元數據的更新壓力所有集中在一個地方,可能致使元數據的存儲有壓力。
B.gossip
優勢 :元數據的更新比較分散,不是集中在同一個地方,更新請求會陸陸續續到達全部節點上去更新,有必定的延時,下降了壓力。
缺點 :元數據更新有延時,可能會致使集羣的一些操做會有一些滯後。
③10000端口
每一個節點都有一個專門用於節點間通訊的端口號,就是本身提供服務的端口號+10000。每一個節點每隔一段時間都會往另外幾個節點發送ping消息,同時其餘節點接收到ping以後會返回pong消息。
④節點間交換的信息
包含故障信息,節點的增長和移除,hash slot信息等等。
2.gossip協議
gossip協議,即流言協議。gossip協議包含多種消息,包括ping,pong,meet,fail等等。
①ping: 每一個節點都會頻繁的給其餘節點發送ping,其中包括本身的狀態還有本身維護的集羣元數據,互相經過ping交換元數據。
②meet:某個節點發送meet給新加入的節點,讓其加入進羣中,而後新節點就會開始與其餘節點進行通訊。
③pong:做爲ping和meet的響應,包含本身的狀態和其餘信息,也能夠用於信息廣播和更新。
④fail:某個節點判斷另外一個節點fail以後,就會發送fail消息給其餘節點,通知其餘節點,指定的節點宕機了。
3.深刻ping消息
①ping很頻繁,並且要攜帶一些元數據,因此會加劇網絡負擔。
②每一個節點每秒會執行10次ping,每次會選擇5個最久沒有通訊的其餘節點去通訊。
③如何發現某個節點通訊時延達到了 cluster_node_timeout/2,那麼當即發送ping,避免數據交換延時太長,落戶的時間太多。
④能夠調節 cluster_node_timeout的值,若是調節比較大。就會下降ping發送的機率。
⑤每次ping都會帶上本身的信息。還要帶上1/10其餘節點的信息,發送出去進行交換。
⑥至少包含3個其餘節點的信息,最多包含總節點-2個其餘節點的信息。
1.基於重定向的客戶端
redis-cli c,自動重定向
①請求重定向
客戶端可能會挑選任意一個redis實例去發送命令,每一個redis實例接收到命令以後,都會接受key對應的hash slot,若是在本地就在本地處理,不然返回moved給客戶端,讓客戶端進行重定向。
cluster keyslot mykey ,能夠查看一個key對應的hash slot是什麼。
用redis-cli的時候,能夠加入-c參數,支持自動的請求重定向,redis-cli接收到moved以後,會自動重定向到對應的節點執行命令。
②計算hash slot
計算hash slot的算法,就是根據key計算CRC16值,而後對16384取模,拿到對應的hash slot。
用hash tag能夠手動指定key對應的slot,同一個hash tag下的key,都會在一個hash slot中,好比set mykey1:{100}和set mykey2:{100}。
③hash slot查找
節點間經過gossip協議進行數據交換,就知道每一個hash slot在那個節點上面了
2.smart jedis
①什麼是smart jedis:
基於重定向的客戶端,很消耗網絡IO,由於大部分狀況下,可能都會出現一次請求重定向,才能找到正確的節點。
因此大部分的客戶端,好比java redis客戶端,就是jedis,都是smart的。
本地維護一份hashslot -> node的映射表,緩存,大部分狀況下,直接走本地緩存就能夠找到hashslot -> node,不須要經過節點進行moved重定向。
②JedisCluster的工做原理
A:在JedisCluster初始化的時候,就會隨機選擇一個node,初始化hash slot到node的映射表,同時爲每一個節點建立一個JedisPool鏈接池。
B:每次基於JedisCluster執行操做,首先會在本地計算key的hash slot,而後在本地映射表中找到節點。
C:若是那個node真好仍是持有那個hash slot,那麼就OK。
D:若是JedisCluster API返回的是moved,那麼利用該節點的數據,更新本地的hash slot 和node的映射表。
E:重複上面的步驟,知道找到對應的節點,若是重試超過5次,就會報錯,拋出JedisClusterMaxRedirectionException異常。
jedis老版本,可能會出如今集羣某個節點故障還沒完成自動切換恢復時,頻繁更新hash slot,頻繁ping節點檢查活躍,致使大量網絡IO開銷。
jedis最新版本,對於這些過分的hash slot更新和ping,都進行了優化,避免了相似問題。
③hash slot遷移和ask重定向
A:若是hash slot正在進行遷移,那麼會返回ask重定向給jedis,
B:jedis接收到ask重定向以後,會從新定位到目標節點去執行。
C:可是由於ask發生在hash slot遷移過程當中,因此收到ask是不會更新hash slot本地緩存。
D:已經能夠肯定說hash slot已經遷移完了,moved是會更新本地hash slot到node的映射緩存的。
redis cluster的高可用原理,幾乎和哨兵時相似的。
1.判斷節點宕機
①若是一個節點認爲另外一個節點道濟,那麼就是pfail,主觀宕機。
②若是多個節點都認爲另一個 節點宕機了,那就是fail,客觀宕機。
③在cluster-node-timeout內,某個幾點一直沒有返回pong,那麼就認爲pfail。
④若是一個節點認爲某個節點pfail了,那麼會在gossip ping消息中,發送給其餘節點,若是超過半數的節點都認爲pfail了,那就好變成fail。
2.從節點過濾
①對宕機的master node,從其全部的slave node中,選擇一個切換成master node。
②檢查每一個slave node與master node斷開鏈接的時機,若是超過了cluster-node-timeout * cluster-slave-validity-factor,那麼這個節點就沒有資格切換成 master node,直接被過濾。
3.從節點選舉
①每一個從幾點,都根據本身對master複製數據的offset,來設置一個選舉時間,offset越大的從節點,選舉時間越靠前,優先進行選舉。
②全部的master node開始slave選舉投票,給要進行選舉的slave進行投票,若是大部分master node(N/2 + 1)都投票給了某個從節點,那麼選舉經過,那個從節點能夠切換成master node。
③從節點執行主備切換,從節點切換爲主節點。
4.與哨兵進行比較 整個流程跟哨兵相比,很是相似,因此說,redis cluster功能強大,直接集成了replication和sentinal的功能