主從復制
master-slave(replication)
從節點上只能讀數據,不能寫入數據,只能在主節點寫入數據。主節點的數據會自動同步到從節點。
復制原理:
- 從節點第一次加入后和主節點建立連接
- 建立連接后主節點通過bgsave生成RDB文件,再將文件發送到從節點(假如超時則會重發)
- 新來的指令主節點保存在緩沖區中,然后再發送給從節點
- 從節點基於rdb做一次數據載入
- 后續通過命令傳播到從節點保持數據一致
- 假如從節點斷開一段時間重新加入,會丟失斷開時間的數據,會基於偏移量增量復制。
解決的問題:
- 數據備份
- 讀寫分離(不是很有必要,redis本身的性能已經夠高了)
存在的問題:
主從會有延遲。
主掛了,主從不會自動切換,需要手動重啟主節點。
高可用(Sentinel機制)
sentinel是特殊的redis-server節點,一般會建造多個sentinel節點互相監控,sentinel之間地位平等,沒有主從之分。
sentinel會監控真正redis-server節點:
- 當主節點超時未與sentinel節點連接時,會先將主節點標記下線(主觀下線)
- 該sentinel節點會詢問其他的節點,假如超過半數(奇數個sentinel)認為主節點下線,此時為真正下線(客觀下線)
- 此時需要failover(故障轉移):奇數個哨兵會通過Raft算法選舉leader,leader的sentinel節點會發送兩條指令讓某一個從節點成為主節點
- 舊的主節點重啟后會變成新的主節點的從節點
解決的問題:
- 高可用
存在的問題:
- 切換過程中可能會出現短暫數據丟失
- 沒有解決水平擴容問題
redis客戶端會從sentinel拿到主節點的地址,再去根據地址進行真正地連接及操作。
Raft算法(分布式一致性算法的一種)
1、先到先得
2、少數服從多數
選舉的超時時間是一個隨機數,最先超時的會變成一個candidate,然后發起投票,並且給自己投一票,假如超過半數投票自己(平票則需要再投一次),自己成為了leader以后,會定期給從節點發送心跳包,重置從節點的選舉超時時間。
可拓展
為了解決水平擴容的問題,我們可以在客戶端做分片,也可以用代理分片服務,另外Redis本身提供Cluter模式,進行水平擴容
客戶端:jedis
實現了分片到不同redis服務的功能,代碼的拓展性有限,不能實現平滑擴容
代理proxy
Twenproxy,Codis:需要考慮proxy單點問題;不能實現平滑擴容
服務端實現:Redis-Cluster(重點)
架構:多主多從
數據分布:CRC16算法對16384取模,按哈希槽分配(一共有16384個槽),將一些槽分配到對應的節點上。
HashTag:在key中加{xxx},會用xxx取模分配槽,假如xxx一樣則會分配在同一個節點上。
主節點掛了:
- slave發現master宕機,廣播通知
- 其他master發送ACK
- slave變成新的master,廣播通知
客戶端連接到任意一個節點都可以實現一樣的效果,去中心化。