日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

深入剖析Redis系列(三) - Redis集群模式搭建与原理详解

發(fā)布時(shí)間:2025/7/25 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在 Redis 3.0 之前,使用 哨兵(sentinel)機(jī)制來(lái)監(jiān)控各個(gè)節(jié)點(diǎn)之間的狀態(tài)。Redis Cluster 是 Redis 的 分布式解決方案,在 3.0 版本正式推出,有效地解決了 Redis 在 分布式 方面的需求。當(dāng)遇到 單機(jī)內(nèi)存、并發(fā)流量 等瓶頸時(shí),可以采用 Cluster 架構(gòu)方案達(dá)到 負(fù)載均衡 的目的。

本文將從 集群方案、數(shù)據(jù)分布、搭建集群、節(jié)點(diǎn)通信集群伸縮、請(qǐng)求路由故障轉(zhuǎn)移、集群運(yùn)維 等幾個(gè)方面介紹 Redis Cluster。

其他文章

  • 深入剖析Redis系列(一) - Redis入門(mén)簡(jiǎn)介與主從搭建

  • 深入剖析Redis系列(二) - Redis哨兵模式與高可用集群

  • 深入剖析Redis系列(三) - Redis集群模式搭建與原理詳解

  • 深入剖析Redis系列(四) - Redis數(shù)據(jù)結(jié)構(gòu)與全局命令概述

  • 深入剖析Redis系列(五) - Redis數(shù)據(jù)結(jié)構(gòu)之字符串

  • 深入剖析Redis系列(六) - Redis數(shù)據(jù)結(jié)構(gòu)之哈希

  • 深入剖析Redis系列(七) - Redis數(shù)據(jù)結(jié)構(gòu)之列表

  • 深入剖析Redis系列(八) - Redis數(shù)據(jù)結(jié)構(gòu)之集合

正文

1. Redis集群方案

Redis Cluster 集群模式通常具有 高可用可擴(kuò)展性、分布式、容錯(cuò) 等特性。Redis 分布式方案一般有兩種:

1.1 客戶端分區(qū)方案

客戶端 就已經(jīng)決定數(shù)據(jù)會(huì)被 存儲(chǔ) 到哪個(gè) redis 節(jié)點(diǎn)或者從哪個(gè) redis 節(jié)點(diǎn) 讀取數(shù)據(jù)。其主要思想是采用 哈希算法 將 Redis 數(shù)據(jù)的 key 進(jìn)行散列,通過(guò) hash 函數(shù),特定的 key會(huì) 映射 到特定的 Redis 節(jié)點(diǎn)上。

客戶端分區(qū)方案 的代表為 Redis Sharding,Redis Sharding 是 Redis Cluster 出來(lái)之前,業(yè)界普遍使用的 Redis 多實(shí)例集群 方法。Java 的 Redis 客戶端驅(qū)動(dòng)庫(kù) Jedis,支持 Redis Sharding 功能,即 ShardedJedis 以及 結(jié)合緩存池 的 ShardedJedisPool。

  • 優(yōu)點(diǎn)

不使用 第三方中間件分區(qū)邏輯 可控,配置 簡(jiǎn)單,節(jié)點(diǎn)之間無(wú)關(guān)聯(lián),容易 線性擴(kuò)展,靈活性強(qiáng)。

  • 缺點(diǎn)

客戶端 無(wú)法 動(dòng)態(tài)增刪 服務(wù)節(jié)點(diǎn),客戶端需要自行維護(hù) 分發(fā)邏輯,客戶端之間 無(wú)連接共享,會(huì)造成 連接浪費(fèi)

1.2. 代理分區(qū)方案

客戶端 發(fā)送請(qǐng)求到一個(gè) 代理組件代理 解析 客戶端 的數(shù)據(jù),并將請(qǐng)求轉(zhuǎn)發(fā)至正確的節(jié)點(diǎn),最后將結(jié)果回復(fù)給客戶端。

  • 優(yōu)點(diǎn):簡(jiǎn)化 客戶端 的分布式邏輯,客戶端 透明接入,切換成本低,代理的 轉(zhuǎn)發(fā)存儲(chǔ) 分離。

  • 缺點(diǎn):多了一層 代理層,加重了 架構(gòu)部署復(fù)雜度性能損耗。

代理分區(qū) 主流實(shí)現(xiàn)的有方案有 Twemproxy 和 Codis。

1.2.1. Twemproxy

Twemproxy 也叫 nutcraker,是 twitter 開(kāi)源的一個(gè) redis 和 memcache 的 中間代理服務(wù)器 程序。Twemproxy 作為 代理,可接受來(lái)自多個(gè)程序的訪問(wèn),按照 路由規(guī)則,轉(zhuǎn)發(fā)給后臺(tái)的各個(gè) Redis 服務(wù)器,再原路返回。Twemproxy 存在 單點(diǎn)故障 問(wèn)題,需要結(jié)合 Lvs 和 Keepalived 做 高可用方案。

  • 優(yōu)點(diǎn):應(yīng)用范圍廣,穩(wěn)定性較高,中間代理層 高可用

  • 缺點(diǎn):無(wú)法平滑地 水平擴(kuò)容/縮容,無(wú) 可視化管理界面,運(yùn)維不友好,出現(xiàn)故障,不能 自動(dòng)轉(zhuǎn)移。

1.2.2. Codis

Codis 是一個(gè) 分布式 Redis 解決方案,對(duì)于上層應(yīng)用來(lái)說(shuō),連接 Codis-Proxy 和直接連接 原生的 Redis-Server 沒(méi)有的區(qū)別。Codis 底層會(huì) 處理請(qǐng)求的轉(zhuǎn)發(fā),不停機(jī)的進(jìn)行 數(shù)據(jù)遷移 等工作。Codis 采用了無(wú)狀態(tài)的 代理層,對(duì)于 客戶端 來(lái)說(shuō),一切都是透明的。

  • 優(yōu)點(diǎn)

實(shí)現(xiàn)了上層 Proxy 和底層 Redis 的 高可用數(shù)據(jù)分片自動(dòng)平衡,提供 命令行接口 和 RESTful API,提供 監(jiān)控管理 界面,可以動(dòng)態(tài) 添加刪除 Redis 節(jié)點(diǎn)。

  • 缺點(diǎn)

部署架構(gòu)配置 復(fù)雜,不支持 跨機(jī)房多租戶,不支持 鑒權(quán)管理

1.3. 查詢路由方案

客戶端隨機(jī)地 請(qǐng)求任意一個(gè) Redis 實(shí)例,然后由 Redis 將請(qǐng)求 轉(zhuǎn)發(fā)正確 的 Redis 節(jié)點(diǎn)。Redis Cluster 實(shí)現(xiàn)了一種 混合形式查詢路由,但并不是 直接 將請(qǐng)求從一個(gè) Redis 節(jié)點(diǎn) 轉(zhuǎn)發(fā) 到另一個(gè) Redis 節(jié)點(diǎn),而是在 客戶端 的幫助下直接 重定向( redirected)到正確的 Redis 節(jié)點(diǎn)。

  • 優(yōu)點(diǎn)

無(wú)中心節(jié)點(diǎn),數(shù)據(jù)按照 存儲(chǔ)分布在多個(gè) Redis 實(shí)例上,可以平滑的進(jìn)行節(jié)點(diǎn) 擴(kuò)容/縮容,支持 高可用自動(dòng)故障轉(zhuǎn)移,運(yùn)維成本低。

  • 缺點(diǎn)

嚴(yán)重依賴 Redis-trib 工具,缺乏 監(jiān)控管理,需要依賴 Smart Client (維護(hù)連接緩存路由表,MultiOp 和 Pipeline 支持)。Failover 節(jié)點(diǎn)的 檢測(cè)過(guò)慢,不如 中心節(jié)點(diǎn) ZooKeeper 及時(shí)。Gossip 消息具有一定開(kāi)銷。無(wú)法根據(jù)統(tǒng)計(jì)區(qū)分 冷熱數(shù)據(jù)。

2. 數(shù)據(jù)分布

2.1. 數(shù)據(jù)分布理論

分布式數(shù)據(jù)庫(kù) 首先要解決把 整個(gè)數(shù)據(jù)集 按照 分區(qū)規(guī)則 映射到 多個(gè)節(jié)點(diǎn) 的問(wèn)題,即把 數(shù)據(jù)集 劃分到 多個(gè)節(jié)點(diǎn) 上,每個(gè)節(jié)點(diǎn)負(fù)責(zé) 整體數(shù)據(jù) 的一個(gè) 子集。

數(shù)據(jù)分布通常有 哈希分區(qū)順序分區(qū) 兩種方式,對(duì)比如下:

分區(qū)方式特點(diǎn)相關(guān)產(chǎn)品
哈希分區(qū)離散程度好,數(shù)據(jù)分布與業(yè)務(wù)無(wú)關(guān),無(wú)法順序訪問(wèn)Redis Cluster,Cassandra,Dynamo
順序分區(qū)離散程度易傾斜,數(shù)據(jù)分布與業(yè)務(wù)相關(guān),可以順序訪問(wèn)BigTable,HBase,Hypertable

由于 Redis Cluster 采用 哈希分區(qū)規(guī)則,這里重點(diǎn)討論 哈希分區(qū)。常見(jiàn)的 哈希分區(qū) 規(guī)則有幾種,下面分別介紹:

2.1.1. 節(jié)點(diǎn)取余分區(qū)

使用特定的數(shù)據(jù),如 Redis 的 用戶 ID,再根據(jù) 節(jié)點(diǎn)數(shù)量 N 使用公式:hash(key)% N 計(jì)算出 哈希值,用來(lái)決定數(shù)據(jù) 映射 到哪一個(gè)節(jié)點(diǎn)上。

  • 優(yōu)點(diǎn)

這種方式的突出優(yōu)點(diǎn)是 簡(jiǎn)單性,常用于 數(shù)據(jù)庫(kù)分庫(kù)分表規(guī)則。一般采用 預(yù)分區(qū) 的方式,提前根據(jù) 數(shù)據(jù)量 規(guī)劃好 分區(qū)數(shù),比如劃分為 512 或 1024 張表,保證可支撐未來(lái)一段時(shí)間的 數(shù)據(jù)容量,再根據(jù) 負(fù)載情況 遷移到其他 數(shù)據(jù)庫(kù) 中。擴(kuò)容時(shí)通常采用 翻倍擴(kuò)容,避免 數(shù)據(jù)映射 全部被 打亂,導(dǎo)致 全量遷移 的情況。

  • 缺點(diǎn)

當(dāng) 節(jié)點(diǎn)數(shù)量 變化時(shí),如 擴(kuò)容收縮 節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn) 映射關(guān)系 需要重新計(jì)算,會(huì)導(dǎo)致數(shù)據(jù)的 重新遷移

2.1.2. 一致性哈希分區(qū)

一致性哈希 可以很好的解決 穩(wěn)定性問(wèn)題,可以將所有的 存儲(chǔ)節(jié)點(diǎn) 排列在 收尾相接 的 Hash 環(huán)上,每個(gè) key 在計(jì)算 Hash 后會(huì) 順時(shí)針 找到 臨接存儲(chǔ)節(jié)點(diǎn) 存放。而當(dāng)有節(jié)點(diǎn) 加入退出 時(shí),僅影響該節(jié)點(diǎn)在 Hash 環(huán)上 順時(shí)針相鄰后續(xù)節(jié)點(diǎn)

  • 優(yōu)點(diǎn)

加入刪除 節(jié)點(diǎn)只影響 哈希環(huán)順時(shí)針?lè)较?/strong> 的 相鄰的節(jié)點(diǎn),對(duì)其他節(jié)點(diǎn)無(wú)影響。

  • 缺點(diǎn)

加減節(jié)點(diǎn) 會(huì)造成 哈希環(huán) 中部分?jǐn)?shù)據(jù) 無(wú)法命中。當(dāng)使用 少量節(jié)點(diǎn) 時(shí),節(jié)點(diǎn)變化 將大范圍影響 哈希環(huán)數(shù)據(jù)映射,不適合 少量數(shù)據(jù)節(jié)點(diǎn) 的分布式方案。普通一致性哈希分區(qū) 在增減節(jié)點(diǎn)時(shí)需要 增加一倍減去一半 節(jié)點(diǎn)才能保證 數(shù)據(jù)負(fù)載的均衡

注意:因?yàn)?一致性哈希分區(qū) 的這些缺點(diǎn),一些分布式系統(tǒng)采用 虛擬槽 對(duì) 一致性哈希 進(jìn)行改進(jìn),比如 Dynamo 系統(tǒng)。

2.1.3. 虛擬槽分區(qū)

虛擬槽分區(qū) 巧妙地使用了 哈??臻g,使用 分散度良好哈希函數(shù) 把所有數(shù)據(jù) 映射 到一個(gè) 固定范圍整數(shù)集合 中,整數(shù)定義為 (slot)。這個(gè)范圍一般 遠(yuǎn)遠(yuǎn)大于 節(jié)點(diǎn)數(shù),比如 Redis Cluster 槽范圍是 0 ~ 16383。 是集群內(nèi) 數(shù)據(jù)管理遷移基本單位。采用 大范圍槽 的主要目的是為了方便 數(shù)據(jù)拆分集群擴(kuò)展。每個(gè)節(jié)點(diǎn)會(huì)負(fù)責(zé) 一定數(shù)量的槽,如圖所示:

當(dāng)前集群有 5 個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)平均大約負(fù)責(zé) 3276 個(gè) 。由于采用 高質(zhì)量哈希算法,每個(gè)槽所映射的數(shù)據(jù)通常比較 均勻,將數(shù)據(jù)平均劃分到 5 個(gè)節(jié)點(diǎn)進(jìn)行 數(shù)據(jù)分區(qū)。Redis Cluster 就是采用 虛擬槽分區(qū)。

  • 節(jié)點(diǎn)1: 包含 0 到 3276 號(hào)哈希槽。
  • 節(jié)點(diǎn)2:包含 3277 到 6553 號(hào)哈希槽。
  • 節(jié)點(diǎn)3:包含 6554 到 9830 號(hào)哈希槽。
  • 節(jié)點(diǎn)4:包含 9831 到 13107 號(hào)哈希槽。
  • 節(jié)點(diǎn)5:包含 13108 到 16383 號(hào)哈希槽。

這種結(jié)構(gòu)很容易 添加 或者 刪除 節(jié)點(diǎn)。如果 增加 一個(gè)節(jié)點(diǎn) 6,就需要從節(jié)點(diǎn) 1 ~ 5 獲得部分 分配到節(jié)點(diǎn) 6 上。如果想 移除 節(jié)點(diǎn) 1,需要將節(jié)點(diǎn) 1 中的 移到節(jié)點(diǎn) 2 ~ 5 上,然后將 沒(méi)有任何槽 的節(jié)點(diǎn) 1 從集群中 移除 即可。

由于從一個(gè)節(jié)點(diǎn)將 哈希槽 移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì) 停止服務(wù),所以無(wú)論 添加刪除 或者 改變 某個(gè)節(jié)點(diǎn)的 哈希槽的數(shù)量 都不會(huì)造成 集群不可用 的狀態(tài).

2.2. Redis的數(shù)據(jù)分區(qū)

Redis Cluster 采用 虛擬槽分區(qū),所有的 根據(jù) 哈希函數(shù) 映射到 0~16383 整數(shù)槽內(nèi),計(jì)算公式:slot = CRC16(key)& 16383。每個(gè)節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的 鍵值數(shù)據(jù),如圖所示:

2.2.1. Redis虛擬槽分區(qū)的特點(diǎn)

  • 解耦 數(shù)據(jù)節(jié)點(diǎn) 之間的關(guān)系,簡(jiǎn)化了節(jié)點(diǎn) 擴(kuò)容收縮 難度。

  • 節(jié)點(diǎn)自身 維護(hù)槽的 映射關(guān)系,不需要 客戶端 或者 代理服務(wù) 維護(hù) 槽分區(qū)元數(shù)據(jù)

  • 支持 節(jié)點(diǎn)、、 之間的 映射查詢,用于 數(shù)據(jù)路由、在線伸縮 等場(chǎng)景。

2.3. Redis集群的功能限制

Redis 集群相對(duì) 單機(jī) 在功能上存在一些限制,需要 開(kāi)發(fā)人員 提前了解,在使用時(shí)做好規(guī)避。

  • key 批量操作 支持有限。

類似 mset、mget 操作,目前只支持對(duì)具有相同 slot 值的 key 執(zhí)行 批量操作。對(duì)于 映射為不同 slot 值的 key 由于執(zhí)行 mget、mget 等操作可能存在于多個(gè)節(jié)點(diǎn)上,因此不被支持。

  • key 事務(wù)操作 支持有限。

只支持 key 在 同一節(jié)點(diǎn)上事務(wù)操作,當(dāng)多個(gè) key 分布在 不同 的節(jié)點(diǎn)上時(shí) 無(wú)法 使用事務(wù)功能。

  • key 作為 數(shù)據(jù)分區(qū) 的最小粒度

不能將一個(gè) 大的鍵值 對(duì)象如 hash、list 等映射到 不同的節(jié)點(diǎn)。

  • 不支持 多數(shù)據(jù)庫(kù)空間

單機(jī) 下的 Redis 可以支持 16 個(gè)數(shù)據(jù)庫(kù)(db0 ~ db15),集群模式 下只能使用 一個(gè) 數(shù)據(jù)庫(kù)空間,即 db0。

  • 復(fù)制結(jié)構(gòu) 只支持一層

從節(jié)點(diǎn) 只能復(fù)制 主節(jié)點(diǎn),不支持 嵌套樹(shù)狀復(fù)制 結(jié)構(gòu)。

3. Redis集群搭建

Redis-Cluster 是 Redis 官方的一個(gè) 高可用 解決方案,Cluster 中的 Redis 共有 2^14(16384) 個(gè) slot 。創(chuàng)建 Cluster 后, 會(huì) 平均分配 到每個(gè) Redis 節(jié)點(diǎn)上。

下面介紹一下本機(jī)啟動(dòng) 6 個(gè) Redis 的 集群服務(wù),并使用 redis-trib.rb 創(chuàng)建 3主3從集群。搭建集群工作需要以下三個(gè)步驟:

3.1. 準(zhǔn)備節(jié)點(diǎn)

Redis 集群一般由 多個(gè)節(jié)點(diǎn) 組成,節(jié)點(diǎn)數(shù)量至少為 6 個(gè),才能保證組成 完整高可用 的集群。每個(gè)節(jié)點(diǎn)需要 開(kāi)啟配置 cluster-enabled yes,讓 Redis 運(yùn)行在 集群模式 下。

Redis 集群的節(jié)點(diǎn)規(guī)劃如下:

節(jié)點(diǎn)名稱端口號(hào)是主是從所屬主節(jié)點(diǎn)
redis-63796379主節(jié)點(diǎn)---
redis-63896389從節(jié)點(diǎn)redis-6379
redis-63806380主節(jié)點(diǎn)---
redis-63906390從節(jié)點(diǎn)redis-6380
redis-63816381主節(jié)點(diǎn)---
redis-63916391從節(jié)點(diǎn)redis-6381

注意:建議為集群內(nèi) 所有節(jié)點(diǎn) 統(tǒng)一目錄,一般劃分三個(gè)目錄:conf、data、log,分別存放 配置、數(shù)據(jù)日志 相關(guān)文件。把 6 個(gè)節(jié)點(diǎn)配置統(tǒng)一放在 conf 目錄下。

3.1.1. 創(chuàng)建redis各實(shí)例目錄

$ sudo mkdir -p /usr/local/redis-cluster $ cd /usr/local/redis-cluster $ sudo mkdir conf data log $ sudo mkdir -p data/redis-6379 data/redis-6389 data/redis-6380 data/redis-6390 data/redis-6381 data/redis-6391 復(fù)制代碼

3.1.2. redis配置文件管理

根據(jù)以下 模板 配置各個(gè)實(shí)例的 redis.conf,以下只是搭建集群需要的 基本配置,可能需要根據(jù)實(shí)際情況做修改。

# redis后臺(tái)運(yùn)行 daemonize yes # 綁定的主機(jī)端口 bind 127.0.0.1 # 數(shù)據(jù)存放目錄 dir /usr/local/redis-cluster/data/redis-6379 # 進(jìn)程文件 pidfile /var/run/redis-cluster/${自定義}.pid # 日志文件 logfile /usr/local/redis-cluster/log/${自定義}.log # 端口號(hào) port 6379 # 開(kāi)啟集群模式,把注釋#去掉 cluster-enabled yes # 集群的配置,配置文件首次啟動(dòng)自動(dòng)生成 cluster-config-file /usr/local/redis-cluster/conf/${自定義}.conf # 請(qǐng)求超時(shí),設(shè)置10秒 cluster-node-timeout 10000 # aof日志開(kāi)啟,有需要就開(kāi)啟,它會(huì)每次寫(xiě)操作都記錄一條日志 appendonly yes 復(fù)制代碼
  • redis-6379.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6379 pidfile /var/run/redis-cluster/redis-6379.pid logfile /usr/local/redis-cluster/log/redis-6379.log port 6379 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6379.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼
  • redis-6389.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6389 pidfile /var/run/redis-cluster/redis-6389.pid logfile /usr/local/redis-cluster/log/redis-6389.log port 6389 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6389.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼
  • redis-6380.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6380 pidfile /var/run/redis-cluster/redis-6380.pid logfile /usr/local/redis-cluster/log/redis-6380.log port 6380 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6380.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼
  • redis-6390.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6390 pidfile /var/run/redis-cluster/redis-6390.pid logfile /usr/local/redis-cluster/log/redis-6390.log port 6390 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6390.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼
  • redis-6381.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6381 pidfile /var/run/redis-cluster/redis-6381.pid logfile /usr/local/redis-cluster/log/redis-6381.log port 6381 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6381.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼
  • redis-6391.conf
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6391 pidfile /var/run/redis-cluster/redis-6391.pid logfile /usr/local/redis-cluster/log/redis-6391.log port 6391 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6391.conf cluster-node-timeout 10000 appendonly yes 復(fù)制代碼

3.2. 環(huán)境準(zhǔn)備

3.2.1. 安裝Ruby環(huán)境

$ sudo brew install ruby 復(fù)制代碼

3.2.2. 準(zhǔn)備rubygem redis依賴

$ sudo gem install redis Password: Fetching: redis-4.0.2.gem (100%) Successfully installed redis-4.0.2 Parsing documentation for redis-4.0.2 Installing ri documentation for redis-4.0.2 Done installing documentation for redis after 1 seconds 1 gem installed 復(fù)制代碼

3.2.3. 拷貝redis-trib.rb到集群根目錄

redis-trib.rb 是 redis 官方推出的管理 redis 集群 的工具,集成在 redis 的源碼 src 目錄下,將基于 redis 提供的 集群命令 封裝成 簡(jiǎn)單、便捷、實(shí)用操作工具

$ sudo cp /usr/local/redis-4.0.11/src/redis-trib.rb /usr/local/redis-cluster 復(fù)制代碼

查看 redis-trib.rb 命令環(huán)境是否正確,輸出如下:

$ ./redis-trib.rb Usage: redis-trib <command> <options> <arguments ...>create host1:port1 ... hostN:portN--replicas <arg>check host:portinfo host:portfix host:port--timeout <arg>reshard host:port--from <arg>--to <arg>--slots <arg>--yes--timeout <arg>--pipeline <arg>rebalance host:port--weight <arg>--auto-weights--use-empty-masters--timeout <arg>--simulate--pipeline <arg>--threshold <arg>add-node new_host:new_port existing_host:existing_port--slave--master-id <arg>del-node host:port node_idset-timeout host:port millisecondscall host:port command arg arg .. argimport host:port--from <arg>--copy--replacehelp (show this help)For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster. 復(fù)制代碼

redis-trib.rb 是 redis 作者用 ruby 完成的。redis-trib.rb 命令行工具 的具體功能如下:

命令作用
create創(chuàng)建集群
check檢查集群
info查看集群信息
fix修復(fù)集群
reshard在線遷移slot
rebalance平衡集群節(jié)點(diǎn)slot數(shù)量
add-node將新節(jié)點(diǎn)加入集群
del-node從集群中刪除節(jié)點(diǎn)
set-timeout設(shè)置集群節(jié)點(diǎn)間心跳連接的超時(shí)時(shí)間
call在集群全部節(jié)點(diǎn)上執(zhí)行命令
import將外部redis數(shù)據(jù)導(dǎo)入集群

3.3. 安裝集群

3.3.1. 啟動(dòng)redis服務(wù)節(jié)點(diǎn)

運(yùn)行如下命令啟動(dòng) 6 臺(tái) redis 節(jié)點(diǎn):

sudo redis-server conf/redis-6379.conf sudo redis-server conf/redis-6389.conf sudo redis-server conf/redis-6380.conf sudo redis-server conf/redis-6390.conf sudo redis-server conf/redis-6381.conf sudo redis-server conf/redis-6391.conf 復(fù)制代碼

啟動(dòng)完成后,redis 以集群模式啟動(dòng),查看各個(gè) redis 節(jié)點(diǎn)的進(jìn)程狀態(tài):

$ ps -ef | grep redis-server0 1908 1 0 4:59下午 ?? 0:00.01 redis-server *:6379 [cluster] 0 1911 1 0 4:59下午 ?? 0:00.01 redis-server *:6389 [cluster] 0 1914 1 0 4:59下午 ?? 0:00.01 redis-server *:6380 [cluster] 0 1917 1 0 4:59下午 ?? 0:00.01 redis-server *:6390 [cluster] 0 1920 1 0 4:59下午 ?? 0:00.01 redis-server *:6381 [cluster] 0 1923 1 0 4:59下午 ?? 0:00.01 redis-server *:6391 [cluster] 復(fù)制代碼

在每個(gè) redis 節(jié)點(diǎn)的 redis.conf 文件中,我們都配置了 cluster-config-file 的文件路徑,集群?jiǎn)?dòng)時(shí),conf 目錄會(huì)新生成 集群 節(jié)點(diǎn)配置文件。查看文件列表如下:

$ tree -L 3 . . ├── appendonly.aof ├── conf │ ├── node-6379.conf │ ├── node-6380.conf │ ├── node-6381.conf │ ├── node-6389.conf │ ├── node-6390.conf │ ├── node-6391.conf │ ├── redis-6379.conf │ ├── redis-6380.conf │ ├── redis-6381.conf │ ├── redis-6389.conf │ ├── redis-6390.conf │ └── redis-6391.conf ├── data │ ├── redis-6379 │ ├── redis-6380 │ ├── redis-6381 │ ├── redis-6389 │ ├── redis-6390 │ └── redis-6391 ├── log │ ├── redis-6379.log │ ├── redis-6380.log │ ├── redis-6381.log │ ├── redis-6389.log │ ├── redis-6390.log │ └── redis-6391.log └── redis-trib.rb9 directories, 20 files 復(fù)制代碼

3.3.2. redis-trib關(guān)聯(lián)集群節(jié)點(diǎn)

按照 從主到從 的方式 從左到右 依次排列 6 個(gè) redis 節(jié)點(diǎn)。

$ sudo ./redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391 復(fù)制代碼

集群創(chuàng)建后,redis-trib 會(huì)先將 16384 個(gè) 哈希槽 分配到 3 個(gè) 主節(jié)點(diǎn),即 redis-6379,redis-6380 和 redis-6381。然后將各個(gè) 從節(jié)點(diǎn) 指向 主節(jié)點(diǎn),進(jìn)行 數(shù)據(jù)同步

>>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 Adding replica 127.0.0.1:6390 to 127.0.0.1:6379 Adding replica 127.0.0.1:6391 to 127.0.0.1:6380 Adding replica 127.0.0.1:6389 to 127.0.0.1:6381 >>> Trying to optimize slaves allocation for anti-affinity [WARNING] Some slaves are in the same host as their master M: ad4b9ffceba062492ed67ab336657426f55874b7 127.0.0.1:6379slots:0-5460 (5461 slots) master M: df23c6cad0654ba83f0422e352a81ecee822702e 127.0.0.1:6380slots:5461-10922 (5462 slots) master M: ab9da92d37125f24fe60f1f33688b4f8644612ee 127.0.0.1:6381slots:10923-16383 (5461 slots) master S: 25cfa11a2b4666021da5380ff332b80dbda97208 127.0.0.1:6389replicates ad4b9ffceba062492ed67ab336657426f55874b7 S: 48e0a4b539867e01c66172415d94d748933be173 127.0.0.1:6390replicates df23c6cad0654ba83f0422e352a81ecee822702e S: d881142a8307f89ba51835734b27cb309a0fe855 127.0.0.1:6391replicates ab9da92d37125f24fe60f1f33688b4f8644612ee 復(fù)制代碼

然后輸入 yes,redis-trib.rb 開(kāi)始執(zhí)行 節(jié)點(diǎn)握手槽分配 操作,輸出如下:

Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.... >>> Performing Cluster Check (using node 127.0.0.1:6379) M: ad4b9ffceba062492ed67ab336657426f55874b7 127.0.0.1:6379slots:0-5460 (5461 slots) master1 additional replica(s) M: ab9da92d37125f24fe60f1f33688b4f8644612ee 127.0.0.1:6381slots:10923-16383 (5461 slots) master1 additional replica(s) S: 48e0a4b539867e01c66172415d94d748933be173 127.0.0.1:6390slots: (0 slots) slavereplicates df23c6cad0654ba83f0422e352a81ecee822702e S: d881142a8307f89ba51835734b27cb309a0fe855 127.0.0.1:6391slots: (0 slots) slavereplicates ab9da92d37125f24fe60f1f33688b4f8644612ee M: df23c6cad0654ba83f0422e352a81ecee822702e 127.0.0.1:6380slots:5461-10922 (5462 slots) master1 additional replica(s) S: 25cfa11a2b4666021da5380ff332b80dbda97208 127.0.0.1:6389slots: (0 slots) slavereplicates ad4b9ffceba062492ed67ab336657426f55874b7 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. 復(fù)制代碼

執(zhí)行 集群檢查,檢查各個(gè) redis 節(jié)點(diǎn)占用的 哈希槽(slot)的個(gè)數(shù)以及 slot 覆蓋率。16384 個(gè)槽位中,主節(jié)點(diǎn) redis-6379、redis-6380 和 redis-6381 分別占用了 5461、5461 和 5462 個(gè)槽位。

3.3.3. redis主節(jié)點(diǎn)的日志

可以發(fā)現(xiàn),通過(guò) BGSAVE 命令,從節(jié)點(diǎn) redis-6389 在 后臺(tái) 異步地從 主節(jié)點(diǎn) redis-6379 同步數(shù)據(jù)。

$ cat log/redis-6379.log 1907:C 05 Sep 16:59:52.960 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 1907:C 05 Sep 16:59:52.961 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=1907, just started 1907:C 05 Sep 16:59:52.961 # Configuration loaded 1908:M 05 Sep 16:59:52.964 * Increased maximum number of open files to 10032 (it was originally set to 256). 1908:M 05 Sep 16:59:52.965 * No cluster configuration found, I'm ad4b9ffceba062492ed67ab336657426f55874b7 1908:M 05 Sep 16:59:52.967 * Running mode=cluster, port=6379. 1908:M 05 Sep 16:59:52.967 # Server initialized 1908:M 05 Sep 16:59:52.967 * Ready to accept connections 1908:M 05 Sep 17:01:17.782 # configEpoch set to 1 via CLUSTER SET-CONFIG-EPOCH 1908:M 05 Sep 17:01:17.812 # IP address for this node updated to 127.0.0.1 1908:M 05 Sep 17:01:22.740 # Cluster state changed: ok 1908:M 05 Sep 17:01:23.681 * Slave 127.0.0.1:6389 asks for synchronization 1908:M 05 Sep 17:01:23.681 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for '4c5afe96cac51cde56039f96383ea7217ef2af41', my replication IDs are '037b661bf48c80c577d1fa937ba55367a3692921' and '0000000000000000000000000000000000000000') 1908:M 05 Sep 17:01:23.681 * Starting BGSAVE for SYNC with target: disk 1908:M 05 Sep 17:01:23.682 * Background saving started by pid 1952 1952:C 05 Sep 17:01:23.683 * DB saved on disk 1908:M 05 Sep 17:01:23.749 * Background saving terminated with success 1908:M 05 Sep 17:01:23.752 * Synchronization with slave 127.0.0.1:6389 succeeded 復(fù)制代碼

3.3.4. redis集群完整性檢測(cè)

使用 redis-trib.rb check 命令檢測(cè)之前創(chuàng)建的 兩個(gè)集群 是否成功,check 命令只需要給出集群中 任意一個(gè)節(jié)點(diǎn)地址 就可以完成 整個(gè)集群檢查工作,命令如下:

$ ./redis-trib.rb check 127.0.0.1:6379 復(fù)制代碼

當(dāng)最后輸出如下信息,提示集群 所有的槽 都已分配到節(jié)點(diǎn):

[OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. 復(fù)制代碼

小結(jié)

本文介紹了 Redis 集群解決方案數(shù)據(jù)分布集群搭建。集群方案包括 客戶端分區(qū) 方案,代理分區(qū) 方案 和 查詢路由 方案。數(shù)據(jù)分布 部分簡(jiǎn)單地對(duì) 節(jié)點(diǎn)取余 分區(qū),一致性哈希 分區(qū)以及 虛擬槽 分區(qū)進(jìn)行了闡述和對(duì)比。最后對(duì)使用 Redis-trib 搭建了一個(gè) 三主三從虛擬槽 集群示例。

參考

《Redis 開(kāi)發(fā)與運(yùn)維》


歡迎關(guān)注技術(shù)公眾號(hào): 零壹技術(shù)棧

本帳號(hào)將持續(xù)分享后端技術(shù)干貨,包括虛擬機(jī)基礎(chǔ),多線程編程,高性能框架,異步、緩存和消息中間件,分布式和微服務(wù),架構(gòu)學(xué)習(xí)和進(jìn)階等學(xué)習(xí)資料和文章。

總結(jié)

以上是生活随笔為你收集整理的深入剖析Redis系列(三) - Redis集群模式搭建与原理详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。