Redis集群

單機/單點

  1. 單點故障/瓶頸:多個節點負載:面向數據:
    1. 一變多(一致性<弱一致,最終一致性>)》可用性
    2. 最終一致性:一部分角色確認 》 網絡分區(腦裂)》過半機制

鏡像:數據容量不變
切片:橫向擴展

集群分類

  1. 主從復制 Replication:鏡像:增刪改(主<退化到單節點>)查詢負載到從節點
    高可用 Sentinel
  2. 分布式 twemproxy:切片
    集群 Cluster

Redis主從復制

主從復制 Replication

  1. 一個Redis服務可以有多個該服務的復制品,這個Redis服務稱為Master,其他復制品稱為Slaves
  2. 只要網絡連接正常,Master會一直將自己的數據更新同步給Slaves,保持主從同步
  3. 只有Master可以執行寫命令,Slaves只能執行讀命令
image.png
image.png
  1. 從服務器執行客戶端發送的讀命令,比如GET、LRANGE、SMEMMBERS、HGET、ZRANGE等等
  2. 客戶端可以連接Slaves執行讀請求,來降低Master的讀壓力
image.png
image.png

主從復制創建

  1. redis-server --slaveof <master-ip> <master-port>,配置當前服務稱為某Redis服務的Slave
    1. redis-server --port 6380 --slaveof 127.0.0.1 6379
  2. SLAVEOF host port命令,將當前服務器狀態從Master修改為別的服務器的Slave
    1. redis > SLAVEOF 192.168.1.1 6379,將服務器轉換為Slave
    2. redis > SLAVEOF NO ONE ,將服務器重新恢復到Master,不會丟棄已同步數據
  3. 配置方式:啟動時,服務器讀取配置文件,并自動成為指定服務器的從服務器
    1. slaveof <masterip> <masterport>
    2. slaveof 127.0.0.1 6379

主從復制演示

  1. redis-server --slaveof <master-ip> <master-port>
    redis-server --port 6380 --slaveof 127.0.0.1 6379
    redis-cli -p 6380 -n 0
    測試Master和Slave的讀寫

  2. SLAVEOF 命令
    從服務器連接到192.168.56.201的6379端口
    redis > SLAVEOF 192.168.56.201 6379
    redis > SLAVEOF NO ONE ,將服務器重新恢復到Master,不會丟棄已同步數據
    redis > SET n2key 5
    redis > get n2key
    redis > keys *
    redis > SLAVEOF 192.168.56.201 6379
    redis > keys *

  3. 配置方式
    在node2節點安裝配置redis服務,修改配置文件
    slaveof 192.168.56.201 6379
    啟動服務,觀察和node1的同步
    redis > SLAVEOF NO ONE,觀察是否可寫set、keys *

主從復制問題

  1. 一個Master可以有多個Slaves
  2. Slave下線,只是讀請求的處理性能下降
  3. Master下線,寫請求無法執行
  4. 其中一臺Slave使用SLAVEOF no one命令成為Master,其它Slaves執行SLAVEOF命令指向這個新的Master,從它這里同步數據

以上過程是手動的,能夠實現自動,這就需要Sentinel哨兵,實現故障轉移Failover操作

Redis哨兵

高可用 Sentinel

  1. 官方提供的高可用方案,可以用它管理多個Redis服務實例
  2. 編譯后產生redis-sentinel程序文件
  3. Redis Sentinel是一個分布式系統,可以在一個架構中運行多個Sentinel進程

啟動 Sentinel

  1. 將src目錄下產生redis-sentinel程序文件復制到$REDIS_HOME/bin
  2. 啟動一個運行在Sentinel模式下的Redis服務實例
    1. redis-sentinel
    2. redis-server /path/to/sentinel.conf --sentinel
  3. Redis Sentinel是一個分布式系統,可以在一個架構中運行多個Sentinel進程

監控 Monitoring

  1. Sentinel會不斷檢查Master和Slaves是否正常
  2. 每一個Sentinel可以監控任意多個Master和該Master下的Slaves
image.png

Sentinel網絡

監控同一個Master的Sentinel會自動連接,組成一個分布式的Sentinel網絡,互相通信并交換彼此關于被監視服務器的信息。

下圖中3個Sentinel監控著S1和它的2個Slave:

image.png

服務器下線

  1. 當一個sentinel認為被監視的服務器已經下線時,它會向網絡中的其他Sentinel進行確認,判斷該服務器是否真的已經下線
  2. 如果下線的服務器為主服務器,那么sentinel網絡將對下線主服務器進行自動故障轉移,通過將下線主服務器的某個從服務器提升為新的主服務器,并讓其從服務器轉為復制新的主服務器,以此來讓系統重新回到上線的狀態
image.png
image.png

服務器下線后重新上線

image.png

Sentinel 配置文件

  1. 至少包含一個監控配置選項,用于指定被監控Master的相關信息
  2. Sentinel monitor<name><ip><port><quorum>,
    例如 sentinel monitor mymaster 127.0.0.1 6379 2
    監視mymaster的主服務器,服務器ip和端口,將這個主服務器判斷為下線失效至少需要2個Sentinel同意,如果多數Sentinel同意才會執行故障轉移
  3. Sentinel會根據Master的配置自動發現Master的Slaves
  4. Sentinel默認端口號為26379

Sentinel 配置舉例

  1. 執行以下兩條命令,將創建兩個監視主服務器s1的sentinel實例:
    $redis-sentinel sentinel1.conf
    $redis-sentinel sentinel2.conf
  2. 其中sentinel1.conf的內容為:
    port 26379
    Sentinel monitor s1 127.0.0.1 6380 1
  3. sentinel2.conf的內容為:
    Port 26380
    Sentinel monitor s1 127.0.0.1 6379 2
image.png

Sentinel 實驗

image.png

Sentinel 總結

  1. 主從復制,解決了讀請求的分擔,從節點下線,會使得讀請求能力有所下降;
  2. Master只有一個,寫請求單點問題;
  3. Sentinel會在Master下線后自動執行Failover操作,提升一臺Slave為Master,并讓其他Slaves重新成為新Master的Slaves;
  4. 主從復制+哨兵Sentinel只解決了讀性能和高可用問題,但是沒有解決寫性能問題。

問題引出

  1. 主從對寫壓力沒有分擔
  2. 解決思路就是,使用多個節點分擔,將寫請求分散到不同節點處理
  3. 分片Sharding:多節點分擔的思路就是關系型數據庫處理大表的水平切分思路
image.png

Redis Twemproxy

Twemproxy

  1. Twitter開發,代理用戶的讀寫請求
image.png
  1. Twitter開發的代理服務器,他兼容Redis和Memcached,允許用戶將多個redis服務器添加到一個服務器池(pool)里面,并通過用戶選擇的散列函數和分布函數,將來自客戶端的命令請求分發給服務器池中的各個服務器
  2. 通過使用twemproxy我們可以將數據庫分片到多臺redis服務器上面,并使用這些服務器來分擔系統壓力以及數據庫容量:在服務器硬件條件相同的情況下,對于一個包含N臺redis服務器的池來說,池中每臺平均1/N的客戶端命令請求
  3. 向池里添加更多服務器可以線性的擴展系統處理命令請求的能力,以及系統能夠保存的數據量

Twemproxy配置

sxt:
  listen: 192.168.56.201:22121
  hash: fnv1a_64
  distribution: ketama
  auto_eject_hosts: true
  redis: true
  server_retry_timeout: 2000
  server_failure_limit: 3
  servers:
   - 192.168.56.201:6379:1
   - 192.168.56.202:6379:1
   - 192.168.56.203:6379:1

Twemproxy配置說明

sxt,服務器池的名字,支持創建多個服務器池
listen: 192.168.56.201:22121,這個服務器池的監聽地址和端口號
hash: fnv1a_64,鍵散列算法,用于將鍵映射為一個散列值
distribution: ketama,鍵分布算法,決定鍵被分布到哪個服務器
redis: true,代理redis命令請求,不給定時默認代理memcached請求
servers,池中各個服務器的地址和端口號及權重
auto_eject_hosts、
server_failure_limit: twemproxy連續3次向同一個服務器發送命令請求都遇到錯誤時,twemproxy就會將該服務器標記為下線,并交由池中其他在線服務器處理
問題:如何監聽本地所有地址的某個端口

Twemproxy運行

nutcracker -d -c /opt/sxt/twemproxy/conf/nutcracker.sxt.yml
redis-cli -p 22121 -h 192.168.56.201

節點下線

經過重試次數后,將Redis置為下線

127.0.0.1:22121> get mykey
"123"
127.0.0.1:22121> get mykey
(error) ERR Connection refused
127.0.0.1:22121> get mykey
(error) ERR Connection refused
127.0.0.1:22121> get mykey
(nil)

error到nil的變化,說明代理之前是把key的訪問執行原來的服務器,置為下線后,將key的訪問交給了其它服務器處理.

節點上線

經過重試次數后,將Redis置為下線

127.0.0.1:22121> get mykey
"123"
127.0.0.1:22121> get mykey
(error) ERR Connection refused
127.0.0.1:22121> get mykey
(nil)

error到nil的變化,說明代理之前是把key的訪問執行原來的服務器,置為下線后,將key的訪問交給了其它服務器處理.
Redis服務恢復后,原來這個key的值可以再次取到

重試超時配置

server_retry_timeout <time>選項

當一個服務器被twemproxy判斷為下線之后,在time毫秒之內,twemproxy不會再嘗試向下線的服務器發送命令請求,但是在time毫秒之后,服務器會嘗試重新向下線的服務器發送命令請求

如果命令請求能夠正常執行,那么twemproxy就會撤銷對該服務器的下線判斷,并再次將鍵交給那個服務器來處理

但如果服務器還是不能正常處理命令請求,那么twemproxy就會繼續將原本應該交給下線服務器的鍵轉交給其他服務器來處理,并等待下一次重試的來臨

image.png
image.png

總結

  1. 前端使用 Twemproxy 做代理,后端的 Redis 數據能基本上根據 key 來進行比較均衡的分布
  2. 后端一臺 Redis 掛掉后,Twemproxy 能夠自動摘除。恢復后,Twemproxy 能夠自動識別、恢復并重新加入到 Redis 組中重新使用
  3. Redis 掛掉后,后端數據是否丟失依據 Redis 本身的持久化策略配置,與 Twemproxy 基本無關
  4. 如果要新增加一臺 Redis,Twemproxy 需要重啟才能生效;并且數據不會自動重新 Reblance,需要人工單獨寫腳本來實現
  5. 如原來已經有 2 個節點 Redis,后續有增加 2 個 Redis,則數據分布計算與原來的 Redis 分布無關,現有數據如果需要分布均勻的話,需要人工單獨處理
  6. 如果 Twemproxy 的后端節點數量發生變化,Twemproxy 相同算法的前提下,原來的數據必須重新處理分布,否則會存在找不到key值的情況
  7. 不管 Twemproxy 后端有幾臺 Redis,前端的單個 Twemproxy 的性能最大也只能和單臺 Redis 性能差不多
  8. 如同時部署多臺 Twemproxy 配置一樣,客戶端分別連接多臺 Twemproxy可以在一定條件下提高性能

整合方案

  1. redis-mgr
  2. 整合了通過整合復制、Sentinel以及twemproxy等組件,提供了一站式的Redis服務器部署、監控、遷移功能,網址https://github.com/changyibiao/redis-mgr

Redis集群

Redis集群

  1. 3.0支持
  2. 由多個Redis服務器組成的分布式網絡服務集群
  3. 每一個Redis服務器稱為節點Node,節點之間會互相通信。兩兩相連
  4. Redis集群無中心節點
集群

Redis集群節點復制

  1. Redis集群的每個節點都有兩種角色可選:主節點master node、從節點slave node。其中主節點用于存儲數據,而從節點則是某個主節點的復制品
  2. 當用戶需要處理更多讀請求的時候,添加從節點可以擴展系統的讀性能,因為Redis集群重用了單機Redis復制特性的代碼,所以集群的復制行為和我們之前介紹的單機復制特性的行為是完全一樣的
主從節點

Redis集群故障轉移

  1. Redis集群的主節點內置了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當集群中的某個主節點下線時,集群中的其他在線主節點會注意到這一點,并對已下線的主節點進行故障轉移
  2. 集群進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在集群里面,故障轉移是由集群中其他在線的主節點負責進行的,所以集群不必另外使用Redis Sentinel
image.png
image.png

Redis集群分片

  1. 集群將整個數據庫分為16384個槽位slot,所有key都數據這些slot中的一個,key的槽位計算公式為slot_number=crc16(key)%16384,其中crc16為16位的循環冗余校驗和函數
  2. 集群中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,集群進入上線狀態,并開始處理客戶端發送的數據命令請求

舉例
三個主節點7000、7001、7002平均分片16384個slot槽位
節點7000指派的槽位為0到5060
節點7001指派的槽位為5461到10022
節點7002指派的槽位為10923到16383
節點7003指派的槽位為5061到5460,10023-10922

Redis集群Redirect轉向

  1. 由于Redis集群無中心節點,請求會發給任意主節點
  2. 主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會返回客戶端一個轉向錯誤
  3. 客戶端根據錯誤中包含的地址和端口重新向正確的負責的主節點發起命令請求
image.png
image.png

Redis集群搭建

  1. 創建多個主節點
  2. 為每一個節點指派slot,將多個節點連接起來,組成一個集群
  3. 槽位分片完成后,集群進入上線狀態
  4. 6個節點:3個主節點,每一個主節點有一個從節點

Redis集群總結

  1. Redis集群是一個由多個節點組成的分布式服務集群,它具有復制、高可用和分片特性
  2. Redis的集群沒有中心節點,并且帶有復制和故障轉移特性,這可用避免單個節點成為性能瓶頸,或者因為某個節點下線而導致整個集群下線
  3. 集群中的主節點負責處理槽(儲存數據),而從節點則是主節點的復制品
  4. Redis集群將整個數據庫分為16384個槽,數據庫中的每個鍵都屬于16384個槽中的其中一個
  5. 集群中的每個主節點都可以負責0個至16384個槽,當16384個槽都有節點在負責時,集群進入上線狀態,可以執行客戶端發送的數據命令
  6. 主節點只會執行和自己負責的槽有關的命令,當節點接收到不屬于自己處理的槽的命令時,它將會處理指定槽的節點的地址返回給客戶端,而客戶端會向正確的節點重新發送
  7. 如果需要完整地分片、復制和高可用特性,并且要避免使用代理帶來的性能瓶頸和資源消耗,那么可以選擇使用Redis集群;如果只需要一部分特性(比如只需要分片,但不需要復制和高可用等),那么單獨選用twemproxy、Redis的復制和Redis Sentinel中的一個或多個
image.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容