Redis實戰集羣機制

下面介紹Redis的集羣方案。前端

Replication(主從複製)

Redis的replication機制容許slave從master那裏經過網絡傳輸拷貝到完整的數據備份,從而達到主從機制。爲了實現主從複製,咱們準備三個redis服務,依次命名爲master,slave1,slave2。node

配置主服務器

爲了測試效果,咱們先修改主服務器的配置文件redis.conf的端口信息git

port 6300
複製代碼

配置從服務器

replication相關的配置比較簡單,只須要把下面一行加到slave的配置文件中。你只須要把ip地址和端口號改一下。github

slaveof 192.168.1.1 6379
複製代碼

咱們先修改從服務器1的配置文件redis.conf的端口信息和從服務器配置。redis

port 6301
slaveof 127.0.0.1 6300
複製代碼

咱們再修改從服務器2的配置文件redis.conf的端口信息和從服務器配置。後端

port 6302
slaveof 127.0.0.1 6300
複製代碼

值得注意的是,從redis2.6版本開始,slave支持只讀模式,並且是默認的。能夠經過配置項slave-read-only來進行配置。 此外,若是master經過requirepass配置項設置了密碼,slave每次同步操做都須要驗證密碼,能夠經過在slave的配置文件中添加如下配置項服務器

masterauth <password>
複製代碼

測試

分別啓動主服務器,從服務器,咱們來驗證下主從複製。咱們在主服務器寫入一條消息,而後再其餘從服務器查看是否成功複製了。網絡

Sentinel(哨兵)

主從機制,上面的方案中主服務器可能存在單點故障,萬一主服務器宕機,這是個麻煩事情,因此Redis提供了Redis-Sentinel,以此來實現主從切換的功能,相似與zookeeper。數據結構

Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis作master-slave的高可用方案時,假如master宕機了,Redis自己(包括它的不少客戶端)都沒有實現自動進行主備切換,而Redis-Sentinel自己也是一個獨立運行的進程,它能監控多個master-slave集羣,發現master宕機後能進行自動切換。app

它的主要功能有如下幾點

  • 監控(Monitoring):不斷地檢查redis的主服務器和從服務器是否運做正常。
  • 提醒(Notification):若是發現某個redis服務器運行出現情況,能夠經過 API 向管理員或者其餘應用程序發送通知。
  • 自動故障遷移(Automaticfailover):可以進行自動切換。當一個主服務器不能正常工做時,會將失效主服務器的其中一個從服務器升級爲新的主服務器,並讓失效主服務器的其餘從服務器改成複製新的主服務器; 當客戶端試圖鏈接失效的主服務器時, 集羣也會向客戶端返回新主服務器的地址, 使得集羣可使用新主服務器代替失效服務器。

Redis Sentinel 兼容 Redis 2.4.16 或以上版本, 推薦使用 Redis 2.8.0 或以上的版本。

配置Sentinel

必須指定一個sentinel的配置文件sentinel.conf,若是不指定將沒法啓動sentinel。首先,咱們先建立一個配置文件sentinel.conf

port 26379
sentinel monitor mymaster 127.0.0.1 6300 2
複製代碼

官方典型的配置以下

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
複製代碼

配置文件只須要配置master的信息就好啦,不用配置slave的信息,由於slave可以被自動檢測到(master節點會有關於slave的消息)。

須要注意的是,配置文件在sentinel運行期間是會被動態修改的,例如當發生主備切換時候,配置文件中的master會被修改成另一個slave。這樣,以後sentinel若是重啓時,就能夠根據這個配置來恢復其以前所監控的redis集羣的狀態。

接下來咱們將一行一行地解釋上面的配置項:

sentinel monitor mymaster 127.0.0.1 6379 2
複製代碼

這行配置指示 Sentinel 去監視一個名爲 mymaster 的主服務器, 這個主服務器的 IP 地址爲 127.0.0.1 , 端口號爲 6300, 而將這個主服務器判斷爲失效至少須要 2 個 Sentinel 贊成,只要贊成 Sentinel 的數量不達標,自動故障遷移就不會執行。

不過要注意, 不管你設置要多少個 Sentinel 贊成才能判斷一個服務器失效, 一個 Sentinel 都須要得到系統中多數(majority) Sentinel 的支持, 才能發起一次自動故障遷移, 並預留一個給定的配置紀元 (configuration Epoch ,一個配置紀元就是一個新主服務器配置的版本號)。換句話說, 在只有少數(minority) Sentinel 進程正常運做的狀況下, Sentinel 是不能執行自動故障遷移的。sentinel集羣中各個sentinel也有互相通訊,經過gossip協議。

除了第一行配置,咱們發現剩下的配置都有一個統一的格式:

sentinel <option_name> <master_name> <option_value>
複製代碼

接下來咱們根據上面格式中的option_name一個一個來解釋這些配置項:

  • down-after-milliseconds 選項指定了 Sentinel 認爲服務器已經斷線所需的毫秒數。
  • parallel-syncs 選項指定了在執行故障轉移時, 最多能夠有多少個從服務器同時對新的主服務器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。

啓動 Sentinel

對於 redis-sentinel 程序, 你能夠用如下命令來啓動 Sentinel 系統

redis-sentinel sentinel.conf
複製代碼

對於 redis-server 程序, 你能夠用如下命令來啓動一個運行在 Sentinel 模式下的 Redis 服務器

redis-server sentinel.conf --sentinel
複製代碼

以上兩種方式,都必須指定一個sentinel的配置文件sentinel.conf, 若是不指定將沒法啓動sentinel。sentinel默認監聽26379端口,因此運行前必須肯定該端口沒有被別的進程佔用。

測試

此時,咱們開啓兩個Sentinel,關閉主服務器,咱們來驗證下Sentinel。發現,服務器發生切換了。

當6300端口的這個服務重啓的時候,他會變成6301端口服務的slave。

Twemproxy

Twemproxy是由Twitter開源的Redis代理, Redis客戶端把請求發送到Twemproxy,Twemproxy根據路由規則發送到正確的Redis實例,最後Twemproxy把結果聚集返回給客戶端。

Twemproxy經過引入一個代理層,將多個Redis實例進行統一管理,使Redis客戶端只須要在Twemproxy上進行操做,而不須要關心後面有多少個Redis實例,從而實現了Redis集羣。

Twemproxy自己也是單點,須要用Keepalived作高可用方案。

這麼些年來,Twenproxy做爲應用範圍最廣、穩定性最高、最久經考驗的分佈式中間件,在業界普遍使用。

可是,Twemproxy存在諸多不方便之處,最主要的是,Twemproxy沒法平滑地增長Redis實例,業務量突增,需增長Redis服務器;業務量萎縮,須要減小Redis服務器。但對Twemproxy而言,基本上都很難操做。其次,沒有友好的監控管理後臺界面,不利於運維監控。

Codis

Codis解決了Twemproxy的這兩大痛點,由豌豆莢於2014年11月開源,基於Go和C開發、現已普遍用於豌豆莢的各類Redis業務場景。

Codis 3.x 由如下組件組成:

  • Codis Server:基於 redis-2.8.21 分支開發。增長了額外的數據結構,以支持 slot 有關的操做以及數據遷移指令。具體的修改能夠參考文檔 redis 的修改。
  • Codis Proxy:客戶端鏈接的 Redis 代理服務, 實現了 Redis 協議。 除部分命令不支持之外(不支持的命令列表),表現的和原生的 Redis 沒有區別(就像 Twemproxy)。對於同一個業務集羣而言,能夠同時部署多個 * codis-proxy 實例;不一樣 codis-proxy 之間由 codis-dashboard 保證狀態同步。
  • Codis Dashboard:集羣管理工具,支持 codis-proxy、codis-server 的添加、刪除,以及據遷移等操做。在集羣狀態發生改變時,codis-dashboard 維護集羣下全部 codis-proxy 的狀態的一致性。對於同一個業務集羣而言,同一個時刻 codis-dashboard 只能有 0個或者1個;全部對集羣的修改都必須經過 codis-dashboard 完成。 * Codis Admin:集羣管理的命令行工具。可用於控制codis-proxy、codis-dashboard 狀態以及訪問外部存儲。
  • Codis FE:集羣管理界面。多個集羣實例共享能夠共享同一個前端展現頁面;經過配置文件管理後端 codis-dashboard 列表,配置文件可自動更新。
  • Codis HA:爲集羣提供高可用。依賴 codis-dashboard 實例,自動抓取集羣各個組件的狀態;會根據當前集羣狀態自動生成主從切換策略,並在須要時經過 codis-dashboard 完成主從切換。
  • Storage:爲集羣狀態提供外部存儲。提供 Namespace 概念,不一樣集羣的會按照不一樣 product name 進行組織;目前僅提供了 Zookeeper 和 Etcd 兩種實現,可是提供了抽象的 interface 可自行擴展。

Codis引入了Group的概念,每一個Group包括1個Redis Master及一個或多個Redis Slave,這是和Twemproxy的區別之一,實現了Redis集羣的高可用。當1個Redis Master掛掉時,Codis不會自動把一個Slave提高爲Master,這涉及數據的一致性問題,Redis自己的數據同步是採用主從異步複製,當數據在Maste寫入成功時,Slave是否已讀入這個數據是無法保證的,須要管理員在管理界面上手動把Slave提高爲Master。

Codis使用,能夠參考官方文檔

Redis 3.0集羣

Redis 3.0集羣採用了P2P的模式,徹底去中心化。支持多節點數據集自動分片,提供必定程度的分區可用性,部分節點掛掉或者沒法鏈接其餘節點後,服務能夠正常運行。Redis 3.0集羣採用Hash Slot方案,而不是一致性哈希。Redis把全部的Key分紅了16384個slot,每一個Redis實例負責其中一部分slot。集羣中的全部信息(節點、端口、slot等),都經過節點之間按期的數據交換而更新。

Redis客戶端在任意一個Redis實例發出請求,若是所需數據不在該實例中,經過重定向命令引導客戶端訪問所需的實例。

Redis 3.0集羣,目前支持的cluster特性

  • 節點自動發現
  • slave->master 選舉,集羣容錯
  • Hot resharding:在線分片
  • 集羣管理:cluster xxx
  • 基於配置(nodes-port.conf)的集羣管理
  • ASK 轉向/MOVED 轉向機制

如上圖所示,全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。節點的fail是經過集羣中超過半數的節點檢測失效時才生效。客戶端與redis節點直連,不須要中間proxy層。客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。redis-cluster把全部的物理節點映射到[0-16383]slot上cluster負責維護node<->slot<->value。

選舉過程是集羣中全部master參與,若是半數以上master節點與master節點通訊超時,認爲當前master節點掛掉。

當集羣不可用時,全部對集羣的操做作都不可用,收到((error) CLUSTERDOWN The cluster is down)錯誤。若是集羣任意master掛掉,且當前master沒有slave,集羣進入fail狀態,也能夠理解成進羣的slot映射[0-16383]不完成時進入fail狀態。若是進羣超過半數以上master掛掉,不管是否有slave集羣進入fail狀態。

環境搭建

如今,咱們進行集羣環境搭建。集羣環境至少須要3個主服務器節點。本次測試,使用另外3個節點做爲從服務器的節點,即3個主服務器,3個從服務器。

修改配置文件,其它的保持默認便可。

#根據實際狀況修改
port 7000      

#容許redis支持集羣模式
cluster-enabled yes  

#節點配置文件,由redis自動維護
cluster-config-file nodes.conf   

#節點超時毫秒
cluster-node-timeout 5000     

# 開啓AOF同步模式
appendonly yes
複製代碼

建立集羣

目前這些實例雖然都開啓了cluster模式,可是彼此還不認識對方,接下來能夠經過Redis集羣的命令行工具redis-trib.rb來完成集羣建立。 首先,下載 raw.githubusercontent.com/antirez/red…

而後,搭建Redis 的 Ruby 支持環境。這裏,不進行擴展,參考相關文檔。

如今,接下來運行如下命令。這個命令在這裏用於建立一個新的集羣, 選項–replicas 1 表示咱們但願爲集羣中的每一個主節點建立一個從節點。

redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
複製代碼

5.三、測試

相關文章
相關標籤/搜索