欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis分片集群的實現(xiàn)方法

 更新時間:2025年08月04日 11:29:01   作者:碼熔burning  
Redis Cluster是Redis官方提供的分布式解決方案,它不是像哨兵那樣只負(fù)責(zé)高可用切換,而是同時解決了數(shù)據(jù)分片和高可用兩個問題,感興趣的可以了解一下

一、 為什么需要 Redis 分片集群? ??

想象一下,你開了一家生意爆火的小賣部 (單個 Redis 實例) ??。

  • 問題一:地方不夠大 (內(nèi)存瓶頸) ??:顧客越來越多,貨架 (內(nèi)存) 都堆滿了,新商品放不下了。單個 Redis 服務(wù)器的內(nèi)存是有限的,當(dāng)數(shù)據(jù)量超過這臺服務(wù)器的內(nèi)存容量時,就存不下了。
  • 問題二:老板忙不過來 (CPU/網(wǎng)絡(luò)瓶頸) ??‍♂???:顧客排長隊結(jié)賬,老板一個人收錢、打包、找零,忙得團(tuán)團(tuán)轉(zhuǎn) (CPU 達(dá)到極限)。同時,店門口的路太窄 (網(wǎng)絡(luò)帶寬),進(jìn)出的人太多,堵車了 ??????。單個 Redis 服務(wù)器的 CPU 處理能力和網(wǎng)絡(luò)帶寬也是有限的,當(dāng)請求量非常大時,它會成為性能瓶頸,響應(yīng)變慢。
  • 問題三:老板病了就關(guān)門 (可用性問題) ??:萬一老板生病了或者店里停電了 (服務(wù)器宕機(jī)),整個小賣部就得關(guān)門歇業(yè),顧客買不到東西。單個 Redis 實例存在單點(diǎn)故障風(fēng)險,一旦它掛了,整個服務(wù)就不可用了。

分片集群就是為了解決這些問題! ??

它的思路是:既然一個小賣部不夠用,那就開連鎖超市!??????

  • 解決內(nèi)存瓶頸 ??:開多家分店 (多個 Redis 節(jié)點(diǎn)),把商品 (數(shù)據(jù)) 分散到不同的店里。這樣總的存儲空間就大大增加了。
  • 解決 CPU/網(wǎng)絡(luò)瓶頸 ??:顧客可以去不同的分店結(jié)賬,每個店的老板 (CPU) 壓力都小了,店門口的路 (網(wǎng)絡(luò)) 也不會那么擁擠了。請求被分散到多個節(jié)點(diǎn)處理,提高了整體的吞吐量。
  • 解決可用性問題 ??:每個分店都配個副店長 (主從復(fù)制) ??。萬一某個店長病了 (主節(jié)點(diǎn)宕機(jī)),副店長立刻頂上 (從節(jié)點(diǎn)自動切換為主節(jié)點(diǎn)),超市還能繼續(xù)營業(yè)。提供了高可用性。

所以,Redis 分片集群的核心思想就是:

  1. 分片 (Sharding) ??:把數(shù)據(jù)“切”成很多片,分散存儲在多個 Redis 實例(主節(jié)點(diǎn))上。
  2. 復(fù)制 (Replication) ??:給每個存儲數(shù)據(jù)的實例(主節(jié)點(diǎn))配備一個或多個備份實例(從節(jié)點(diǎn)),保證高可用。

二、 Redis 分片集群是什么? ??

Redis Cluster 是 Redis 官方提供的分布式解決方案。它不是像哨兵(Sentinel)那樣只負(fù)責(zé)高可用切換,而是同時解決了數(shù)據(jù)分片高可用兩個問題。?

它是一個去中心化的架構(gòu),這意味著沒有一個“中央調(diào)度員”或者“代理服務(wù)器”來指揮所有請求。集群中的每個節(jié)點(diǎn)都知道其他節(jié)點(diǎn)的存在,也知道哪些數(shù)據(jù)(通過后面會講的 Slot)應(yīng)該由哪個節(jié)點(diǎn)負(fù)責(zé)。客戶端可以直接連接到集群中的任意一個節(jié)點(diǎn)發(fā)起請求,如果這個節(jié)點(diǎn)恰好負(fù)責(zé)處理這個請求的數(shù)據(jù),就直接處理;如果不是,它會告訴客戶端“喂,你應(yīng)該去找 XXX 節(jié)點(diǎn) ??”,然后客戶端再去連接正確的節(jié)點(diǎn)。

三、 散列插槽 (Slot) 是什么? (數(shù)據(jù)怎么分?) ??

前面說到要把數(shù)據(jù)“切片”分散到不同的店(主節(jié)點(diǎn))。那具體怎么切?怎么知道哪個數(shù)據(jù)該去哪個店呢? 這就是散列插槽 (Hash Slot) 的作用。

  • 想象一個大郵局有 16384 個信箱 (Slot) ??:Redis Cluster 預(yù)設(shè)了 16384 個 Slot (編號 0 到 16383)。這個數(shù)字是固定的。
  • 每封信 (Key) 都有個目標(biāo)信箱 ??:當(dāng)你存一個鍵值對 (比如 set mykey myvalue) 時,Redis Cluster 會對這個 key (也就是 “mykey”) 做一個特殊的計算 (CRC16 算法),然后用計算結(jié)果對 16384 取模。HASH_SLOT = CRC16(key) % 16384。這個結(jié)果就是一個 0 到 16383 之間的數(shù)字,決定了這個 key 屬于哪個 Slot。
  • 每個郵遞員 (Master Node) 負(fù)責(zé)一部分信箱 ??‍??:在集群初始化的時候,這 16384 個 Slot 會被平均分配給所有的主節(jié)點(diǎn)。比如你有 3 個主節(jié)點(diǎn),那么:
    • 節(jié)點(diǎn) A 可能負(fù)責(zé) Slot 0 到 5460
    • 節(jié)點(diǎn) B 可能負(fù)責(zé) Slot 5461 到 10922
    • 節(jié)點(diǎn) C 可能負(fù)責(zé) Slot 10923 到 16383
  • 找對郵遞員 ??:當(dāng)客戶端要操作一個 key 時,它會先計算這個 key 屬于哪個 Slot,然后根據(jù)自己緩存的“Slot 分配表”,找到負(fù)責(zé)這個 Slot 的主節(jié)點(diǎn),再把請求發(fā)給那個主節(jié)點(diǎn)。

為什么是 16384? Redis 作者認(rèn)為這個數(shù)字:

  1. 足夠分散數(shù)據(jù)到最多 1000 個主節(jié)點(diǎn)(實踐中很少有這么大規(guī)模的集群 ??)。
  2. 節(jié)點(diǎn)間傳輸 Slot 配置信息時,用 16384 個 Slot(即 16384 bit = 2KB)的位圖 (bitmap) 來表示,這個大小比較合適,不會太大導(dǎo)致網(wǎng)絡(luò)開銷過高。??

如何查看某個 Key 屬于哪個 Slot?
可以使用命令:CLUSTER KEYSLOT {key},例如 CLUSTER KEYSLOT mykey。

四、 如何搭建三主六從的 Redis 分片集群? ????

這里我們用 Docker Compose 來模擬 9 個 Redis 實例,組成一個 3 主 6 從(每個主節(jié)點(diǎn)帶 2 個從節(jié)點(diǎn))的集群。

前提條件:

  • 你的 Linux 系統(tǒng)安裝了 Docker。
  • 你的 Linux 系統(tǒng)安裝了 Docker Compose。

步驟:

創(chuàng)建工作目錄: ??

mkdir redis-cluster-demo
cd redis-cluster-demo

創(chuàng)建 docker-compose.yml 文件: ??

services:
  # 定義 9 個 Redis 節(jié)點(diǎn)服務(wù) (這里只展示 node-1 和 node-4 作為例子, 其他類似)
  redis-node-1: # Master 1 Candidate
    image: redis:latest # 或者更新的版本
    container_name: redis-node-1
    # 注意:推薦將 nodes.conf 放在持久化數(shù)據(jù)目錄中
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7001:6379"     # 客戶端端口映射
      - "17001:16379"   # 集群總線端口映射
    volumes:
      - ./node-1/data:/data # 只映射數(shù)據(jù)目錄
    networks:
      - redis-cluster-net

  redis-node-2: # Master 2 Candidate
    image: redis:latest 
    container_name: redis-node-2
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7002:6379"
      - "17002:16379"
    volumes:
      - ./node-2/data:/data
    networks:
      - redis-cluster-net

  redis-node-3: # Master 3 Candidate
    image: redis:latest 
    container_name: redis-node-3
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7003:6379"
      - "17003:16379"
    volumes:
      - ./node-3/data:/data
    networks:
      - redis-cluster-net

  redis-node-4: # Slave Candidate 1
    image: redis:latest 
    container_name: redis-node-4
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7004:6379"
      - "17004:16379"
    volumes:
      - ./node-4/data:/data
    networks:
      - redis-cluster-net

  # ... (省略 redis-node-5 到 redis-node-9 的定義,與 node-4 類似,只需修改名稱、端口映射和卷映射目錄即可) ...
  # 例如 redis-node-5: ports: ["7005:6379", "17005:16379"], volumes: ["./node-5/data:/data"]
  # 例如 redis-node-9: ports: ["7009:6379", "17009:16379"], volumes: ["./node-9/data:/data"]

  redis-node-5:
    image: redis:latest 
    container_name: redis-node-5
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7005:6379"
      - "17005:16379"
    volumes:
      - ./node-5/data:/data
    networks:
      - redis-cluster-net

  redis-node-6:
    image: redis:latest 
    container_name: redis-node-6
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7006:6379"
      - "17006:16379"
    volumes:
      - ./node-6/data:/data
    networks:
      - redis-cluster-net

  redis-node-7:
    image: redis:latest 
    container_name: redis-node-7
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7007:6379"
      - "17007:16379"
    volumes:
      - ./node-7/data:/data
    networks:
      - redis-cluster-net

  redis-node-8:
    image: redis:latest 
    container_name: redis-node-8
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7008:6379"
      - "17008:16379"
    volumes:
      - ./node-8/data:/data
    networks:
      - redis-cluster-net

  redis-node-9:
    image: redis:latest 
    container_name: redis-node-9
    command: redis-server --port 6379 --cluster-enabled yes --cluster-config-file /data/nodes.conf --cluster-node-timeout 5000 --appendonly yes --bind 0.0.0.0
    ports:
      - "7009:6379"
      - "17009:16379"
    volumes:
      - ./node-9/data:/data
    networks:
      - redis-cluster-net


networks:
  redis-cluster-net:
    driver: bridge # 或者其他網(wǎng)絡(luò)驅(qū)動

說明:

  • command: 啟動 Redis 并開啟集群模式,指定配置文件在 /data 目錄下。推薦這種方式,讓 Redis 自己管理 nodes.conf。
  • ports: 映射客戶端端口 (6379 -> 700x) 和集群總線端口 (16379 -> 1700x)。總線端口必須能互通! ??
  • volumes: 將數(shù)據(jù)目錄掛載出來,保證持久化。
  • networks: 所有節(jié)點(diǎn)在一個共享網(wǎng)絡(luò)里。

創(chuàng)建必要的目錄: ???

for i in {1..9}; do mkdir -p ./node-$i/data; done

啟動所有 Redis 容器: ??

docker compose up -d

等待所有容器啟動完成。可以用 docker ps 查看狀態(tài)。

創(chuàng)建集群: ? 關(guān)鍵一步 ?
這一步需要使用 redis-cli 工具來告訴這些獨(dú)立的 Redis 節(jié)點(diǎn):“嘿,你們現(xiàn)在組成一個大家庭了!”

找到你的宿主機(jī) IP 地址: 不能用 127.0.0.1localhost。用 ip addrifconfig 查找。假設(shè)你的 IP 是 172.29.0.10 (請?zhí)鎿Q成你自己的!)。可以使用 docker inspect redis-node-1 | grep '"IPAddress":' 命令查看:

執(zhí)行集群創(chuàng)建命令:

# 獲取任一節(jié)點(diǎn)的 redis-cli (用 node-1 舉例)
docker exec -it redis-node-1 redis-cli --cluster create \
172.28.120.43:7001 172.28.120.43:7002 172.28.120.43:7003 \
172.28.120.43:7004 172.28.120.43:7005 172.28.120.43:7006 \
172.28.120.43:7007 172.28.120.43:7008 172.28.120.43:7009 \
--cluster-replicas 2

解釋:

  • docker exec -it redis-node-1 redis-cli: 進(jìn)入 redis-node-1 容器執(zhí)行命令。
  • --cluster create: 創(chuàng)建集群。
  • 后面是一長串 IP:PORT 列表 (用宿主機(jī) IP 和映射的客戶端端口)。
  • --cluster-replicas 2: 核心參數(shù)!告訴工具,給每個主節(jié)點(diǎn)配 2 個從節(jié)點(diǎn)。它會自動算:9 個節(jié)點(diǎn) / (1主 + 2從) = 3 個主節(jié)點(diǎn)。所以,它會把前 3 個 (7001, 7002, 7003) 當(dāng)作主,后 6 個 (7004-7009) 當(dāng)作從,并自動分配。 magically! ?
  • 確認(rèn)創(chuàng)建: redis-cli 會打印出計劃的配置方案,問你 Can I set the cluster configuration? (type 'yes' to accept):。輸入 yes 并回車。

驗證集群狀態(tài): ?
連接到任意一個節(jié)點(diǎn)(使用映射的端口),查看集群信息。

# 連接到 7001 節(jié)點(diǎn) (在容器內(nèi))
docker exec -it redis-node-1 redis-cli -p 6379 cluster info
# 或者從宿主機(jī)連接 (需要安裝 redis-cli, -c 表示啟用集群模式)
# redis-cli -c -h 172.29.0.10 -p 7001 cluster info

你應(yīng)該看到 cluster_state:ok。

查看節(jié)點(diǎn)信息:

docker exec -it redis-node-1 redis-cli -p 6379 cluster nodes
# 或者從宿主機(jī)連接
# redis-cli -c -h 172.29.0.10 -p 7001 cluster nodes

你會看到 9 個節(jié)點(diǎn)的信息,包括角色 (master/slave)、負(fù)責(zé)的 Slot 等。你會發(fā)現(xiàn) 3 個 master 和 6 個 slave,關(guān)系明確。

?? 恭喜!你的 3 主 6 從 Redis 集群現(xiàn)在跑起來了!

五、 分片集群的集群伸縮是什么? ??

集群搭好了,但業(yè)務(wù)發(fā)展太快 ??,3 家分店又不夠用了,或者某個區(qū)域顧客少了 ??,想關(guān)掉一家店。這就是集群伸縮。

  • 伸:擴(kuò)容 (Scale Out) - 增加新的 Redis 節(jié)點(diǎn)。

    1. 開新店 (添加節(jié)點(diǎn)) ??:先按照上面的方法啟動一個新的 Redis 實例(比如 redis-node-10,映射端口 701017010),讓它也運(yùn)行在集群模式下,但它剛開始是“孤單”的。
    2. 把它拉進(jìn)連鎖體系 (加入集群) ??:使用 redis-cli --cluster add-node 命令,告訴集群里的某個老節(jié)點(diǎn),把這個新家伙拉進(jìn)來。
      # 新節(jié)點(diǎn) 172.29.0.10:7010, 加入到現(xiàn)有集群 (通過 7001 節(jié)點(diǎn)操作)
      docker exec -it redis-node-1 redis-cli --cluster add-node 172.29.0.10:7010 172.29.0.10:7001
      
      默認(rèn)加進(jìn)來是作為 主節(jié)點(diǎn),但它還沒分到活兒 (Slot)。如果要加從節(jié)點(diǎn),用 --cluster-slave--cluster-master-id <主節(jié)點(diǎn)ID>。
    3. 分配工作 (遷移 Slot) ??:新來的主節(jié)點(diǎn)不能閑著,需要從老主節(jié)點(diǎn)那里“勻”一些 Slot (和對應(yīng)的數(shù)據(jù)) 過來。這叫 Resharding (重新分片)。使用 redis-cli --cluster reshard 命令,它會像個向?qū)б粯訂柲悖?ul>
    4. 要搬多少個 Slot 呀?
    5. 搬給誰呢 (輸入新節(jié)點(diǎn)的 Node ID)?
    6. 從哪里搬 (可以輸入 all 讓大家分?jǐn)?,或者指定某些?jié)點(diǎn))?
# 連接到任一節(jié)點(diǎn)發(fā)起 reshard (例如 7001)
docker exec -it redis-node-1 redis-cli --cluster reshard 172.29.0.10:7001
# ... 根據(jù)提示一步步操作 ...
這個過程 Redis 會在后臺默默進(jìn)行,服務(wù)基本不受影響 (可能有短暫抖動)。
  • 縮:縮容 (Scale In) - 移除 Redis 節(jié)點(diǎn)。

    1. 交接工作 (遷移 Slot) ??:如果要移除的是一個 主節(jié)點(diǎn),必須先把它的 Slot 全部遷走,交給其他主節(jié)點(diǎn)。還是用 redis-cli --cluster reshard,這次把要移除節(jié)點(diǎn)的所有 Slot 作為“源”,分配給別人。確保它手里的 Slot 清零! 如果移除的是 從節(jié)點(diǎn),就不用操心 Slot 了,直接下一步。
    2. 辦理離職手續(xù) (移除節(jié)點(diǎn)) ??:使用 redis-cli --cluster del-node 命令,告訴集群,把這個節(jié)點(diǎn)“開除”掉。
      # 假設(shè)要移除 7003 節(jié)點(diǎn),其 Node ID 是 <node-3-id> (用 cluster nodes 查)
      # 通過 7001 節(jié)點(diǎn)操作
      docker exec -it redis-node-1 redis-cli --cluster del-node 172.29.0.10:7001 <node-3-id>
      
    3. 關(guān)店 (關(guān)閉實例) :最后,把被移除節(jié)點(diǎn)的 Redis 進(jìn)程或 Docker 容器停掉。
      docker-compose stop redis-node-3 # 如果用 docker-compose 管理
      # 或者 docker stop redis-node-3
      
  • 伸縮操作都需要時間讓集群狀態(tài)同步和數(shù)據(jù)遷移。耐心點(diǎn)哦!?

    六、 如何使用 RedisTemplate 訪問分片集群???

    在 Java 應(yīng)用中(特別是 Spring Boot / Spring Data Redis),訪問 Redis Cluster 很方便。配置好后,用 RedisTemplate 就行,跟用單實例差不多。

    1. 添加依賴: (pom.xml / build.gradle)
      確保有 spring-boot-starter-data-redis。它通常默認(rèn)使用 Lettuce 客戶端,Lettuce 對 Cluster 支持很好。

      <!-- Maven 示例 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      <!-- 一般不需要額外添加 Lettuce 或 Jedis,除非你想強(qiáng)制用 Jedis -->
      
    2. 配置 application.propertiesapplication.yml:
      告訴 Spring Data Redis 你的集群在哪兒。不需要寫全所有節(jié)點(diǎn),寫幾個就行,客戶端會自動發(fā)現(xiàn)其他的。??
      application.properties 示例:

      # Redis Cluster 節(jié)點(diǎn)列表 (逗號分隔 host:port)
      spring.redis.cluster.nodes=172.29.0.10:7001,172.29.0.10:7002,172.29.0.10:7003
      # 如果有密碼
      # spring.redis.password=yourpassword
      # 連接池配置 (可選, Lettuce)
      spring.redis.lettuce.pool.max-active=8
      spring.redis.lettuce.pool.max-idle=8
      

      application.yml 示例:

      spring:
        redis:
          cluster:
            nodes:
              - 172.29.0.10:7001
              - 172.29.0.10:7002
              - 172.29.0.10:7003
          # password: yourpassword # 可選
          lettuce: # 可選連接池
            pool:
              max-active: 8
              max-idle: 8
      
    3. 在代碼中使用 RedisTemplate:
      注入 RedisTemplateStringRedisTemplate,然后就像操作普通 Redis 一樣用。

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.data.redis.core.StringRedisTemplate;
      import org.springframework.stereotype.Service;
      
      @Service
      public class MyRedisService {
      
          @Autowired
          private StringRedisTemplate stringRedisTemplate; // 或者 RedisTemplate<String, Object>
      
          public void setValue(String key, String value) {
              // 直接用!它會自動找到正確的節(jié)點(diǎn)去執(zhí)行 set 命令
              stringRedisTemplate.opsForValue().set(key, value);
              System.out.println("設(shè)置 Key: " + key + " 到集群! ??");
          }
      
          public String getValue(String key) {
              // 同樣,自動路由到持有這個 key 的節(jié)點(diǎn)去 get
              String value = stringRedisTemplate.opsForValue().get(key);
              System.out.println("從集群獲取 Key: " + key + ", Value: " + value + " ??");
              return value;
          }
      
          // 其他操作 hash, list, set, zset 都類似!
      }
      

    關(guān)鍵點(diǎn):

    • 無感操作: 大部分單 Key 操作,你感覺不到集群的存在。??
    • 自動尋址: 客戶端庫內(nèi)部維護(hù) Slot -> 節(jié)點(diǎn)映射,自動把命令發(fā)給對的節(jié)點(diǎn)。
    • 聰明糾錯: 如果映射過時 (比如剛發(fā)生了故障轉(zhuǎn)移),節(jié)點(diǎn)會返回 MOVEDASK 錯誤??蛻舳藥焓盏胶髸?strong>自動更新映射,然后重試命令,對你的程序來說幾乎是透明的。??
    • 多 Key 操作要注意! ??:像 MSET, MGET, 事務(wù) (MULTI/EXEC) 這類涉及多個 Key 的,默認(rèn)必須保證所有 Key 都在同一個 Slot 里。怎么保證?用 Hash Tags! Key 里用 {} 包起來的部分才參與 Slot 計算。例如 user:{1000}:nameuser:{1000}:profile 就會落到同一個 Slot,因為都看 {1000}。 如果 Key 不在同個 Slot,執(zhí)行這些命令會報錯哦!??

    七、 分片集群的原理是什么? ????

    Redis Cluster 的魔法主要靠這幾招:

    1. 節(jié)點(diǎn)間八卦 (Gossip 協(xié)議):

      深入了解Gossip協(xié)議請看:Gossip協(xié)議:分布式系統(tǒng)中的“八卦”傳播藝術(shù)

      • 每個節(jié)點(diǎn)心里都有本賬(集群狀態(tài):誰活著,誰管哪些 Slot,主從關(guān)系等)。
      • 節(jié)點(diǎn)之間通過 集群總線端口 (客戶端端口+10000那個) 定期互相 PING/PONG,順便交換自己知道的“八卦消息”(集群狀態(tài)信息)。?????
      • 這種方式沒有中心老大,大家互相通氣,最終信息會傳遍整個集群,達(dá)成一致(雖然可能有點(diǎn)延遲,叫最終一致性)。
    2. Slot 地盤劃分與同步:

      • 每個主節(jié)點(diǎn)“認(rèn)領(lǐng)”自己負(fù)責(zé)的 Slot。
      • 認(rèn)領(lǐng)信息通過 Gossip 協(xié)議告訴所有人。
      • 客戶端連上任何一個節(jié)點(diǎn),都能拿到最新的“地盤劃分圖”(Slot -> 節(jié)點(diǎn)映射)。???
    3. 心跳檢測與“懷疑人生”(PFAIL & FAIL):

      • 節(jié)點(diǎn)間互相 PING,如果 A 在 cluster-node-timeout 內(nèi)沒收到 B 的 PONG 回復(fù),A 就開始“懷疑” B 是不是掛了,標(biāo)記為 PFAIL (Possible Fail - 可能掛了)。這只是 A 的個人看法。??
      • A 會把這個“懷疑”通過 Gossip 告訴其他主節(jié)點(diǎn)。
      • 如果超過一半的主節(jié)點(diǎn)都覺得“嗯,我也聯(lián)系不上 B 了”,大家就達(dá)成共識:B 確實掛了!狀態(tài)升級為 FAIL。這個“噩耗”會廣播給所有人。??
    4. 小弟上位記 (自動故障轉(zhuǎn)移 Failover):

      • 一旦某個主節(jié)點(diǎn)被確認(rèn) FAIL 了,它的從節(jié)點(diǎn)們就開始騷動了:“大哥倒了,機(jī)會來了!” ??
      • 誰能上位?得看:確認(rèn)大哥真掛了,并且自己數(shù)據(jù)跟大哥差別不大(同步延遲?。?。
      • 選舉流程:
        • 想上位的從節(jié)點(diǎn),先給自己“資歷”加一分 (currentEpoch++), 然后廣發(fā)英雄帖給所有主節(jié)點(diǎn):“選我!選我!” ???
        • 還活著的主節(jié)點(diǎn)收到帖子,如果在這個“任期”(epoch) 內(nèi)還沒投過票,就給第一個發(fā)帖的從節(jié)點(diǎn)投一票。
        • 哪個從節(jié)點(diǎn)最先拿到超過半數(shù)主節(jié)點(diǎn)的投票,就成功當(dāng)選新大哥!??
      • 走馬上任:新大哥(原從節(jié)點(diǎn))立馬:
        • 宣布自己是主節(jié)點(diǎn)了。
        • 接管原來大哥的所有 Slot 地盤。
        • 通過 Gossip 昭告天下:“從今天起,這些 Slot 歸我管了!”??
      • 服務(wù)恢復(fù):整個過程是自動的,客戶端在短暫的切換后就能找到新大哥繼續(xù)工作。注意??:如果某個主節(jié)點(diǎn)和它的所有從節(jié)點(diǎn)同時掛掉,那它負(fù)責(zé)的 Slot 就真的服務(wù)不了了,需要人工介入。另外,如果超過半數(shù)的主節(jié)點(diǎn)都掛了,為了防止數(shù)據(jù)錯亂,整個集群會停止服務(wù)!??
    5. 客戶端導(dǎo)航 (MOVED & ASK):

      • MOVED (搬家了,去那邊!) ??:客戶端可能拿著舊地圖(過時的 Slot 映射)找錯了節(jié)點(diǎn)。這個節(jié)點(diǎn)會說:“兄弟,這個 Slot 不歸我管了,已經(jīng)搬到 ip:port 那家去了,你去那邊吧!” 并返回 MOVED <slot> <correct_ip>:<correct_port>。客戶端收到后,會更新地圖,然后乖乖去新地址重新請求。
      • ASK (稍等,問問那邊) ??:在 Slot 遷移過程中,比如 Slot X 正從 A 往 B 搬。客戶端還是找舊主 A 問 Slot X 里的某個 key:
        • 如果 key 還在 A 這,A 就處理了。
        • 如果 key 已經(jīng)搬到 B 那了,A 會說:“這個 key 可能在 B 那了,你去問問 B 試試?” 并返回 ASK <slot> <destination_ip>:<destination_port>。
        • 客戶端收到 ASK不會更新地圖(因為搬家還沒徹底完成)。它會先去 B 那邊敲門說 ASKING(表明我是被 A 指過來的),然后再發(fā)真正的命令。B 收到 ASKING 就知道怎么回事了,即使 Slot X 還沒完全歸它管,也會臨時處理這條命令。ASK 只管用一次。

    八、 分片集群的優(yōu)缺點(diǎn)是什么?

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

    1. 能屈能伸 (Scalability) ?:加機(jī)器就能加容量、加性能,理論上可以搞很大規(guī)模。就像開連鎖店,想開多少開多少。
    2. 打不死的小強(qiáng) (High Availability) ?:主從熱備 + 自動切換,掛掉一兩個節(jié)點(diǎn)服務(wù)基本不受影響(只要不是主從一起掛,或掛掉太多主)。
    3. 跑得快 (Performance) ?:請求分散到多個節(jié)點(diǎn),大家分擔(dān)壓力,整體響應(yīng)快。
    4. 親兒子待遇 (Official Solution) ?:Redis 官方出品,穩(wěn)定性和兼容性有保障,社區(qū)活躍。
    5. 群龍無首也行 (Decentralized) ?:沒有中央控制節(jié)點(diǎn),避免了單點(diǎn)瓶頸和故障。

    缺點(diǎn):

    1. 多 Key 操作有點(diǎn)瘸 (Multi-key Operations Limitation) ??:像 MSET、事務(wù)等,默認(rèn)要求 Key 在同一個 Slot,否則報錯。需要開發(fā)者注意,或者用 Hash Tags 繞一下。跨 Slot 的復(fù)雜操作比較麻煩。
    2. 有點(diǎn)復(fù)雜 (Complexity) ??:配置、管理、排錯比單機(jī)或哨兵模式復(fù)雜,需要懂 Slot、Gossip 這些概念。運(yùn)維成本高點(diǎn)。
    3. 話癆費(fèi)網(wǎng) (Network Overhead) ??:節(jié)點(diǎn)間需要不停地 Gossip 來同步狀態(tài),會消耗一些網(wǎng)絡(luò)帶寬和 CPU。
    4. 客戶端要配套 (Client Compatibility) ??:必須用支持 Redis Cluster 的客戶端庫(新版的 Lettuce、Jedis 都支持)。
    5. 可能偏心 (Data Skew) ??:如果 Key 設(shè)計不好(比如 Hash Tag 用得太集中,或有超級熱點(diǎn) Key),可能導(dǎo)致數(shù)據(jù)和流量集中在少數(shù)節(jié)點(diǎn),失去均衡效果。??‍♀?
    6. 批量活兒效率可能不高 (Batch Efficiency) ??:如果要操作一大堆分布在不同 Slot 的 Key,客戶端得跟多個節(jié)點(diǎn)打交道,可能不如單實例高效。
    7. 團(tuán)結(jié)就是力量(但散了就…) (Cluster Integrity Requirement) ??:集群的正常運(yùn)行和故障轉(zhuǎn)移依賴于“少數(shù)服從多數(shù)”原則。如果掛掉的主節(jié)點(diǎn)太多(超過半數(shù)),整個集群就“癱瘓”了,拒絕服務(wù)以保護(hù)數(shù)據(jù)。

    到此這篇關(guān)于Redis分片集群的實現(xiàn)方法的文章就介紹到這了,更多相關(guān)Redis分片集群內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

    相關(guān)文章

    • Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí)

      Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí)

      這篇文章主要為大家介紹了Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
      2023-07-07
    • Redis源碼解析:集群手動故障轉(zhuǎn)移、從節(jié)點(diǎn)遷移詳解

      Redis源碼解析:集群手動故障轉(zhuǎn)移、從節(jié)點(diǎn)遷移詳解

      這篇文章主要介紹了Redis源碼解析:集群手動故障轉(zhuǎn)移、從節(jié)點(diǎn)遷移的相關(guān)內(nèi)容,涉及通過集群定時器函數(shù)clusterCron實現(xiàn)從節(jié)點(diǎn)遷移等知識,具有一定參考價值,需要的朋友可以了解。
      2017-10-10
    • Redis 實現(xiàn)好友關(guān)注和關(guān)注推送的示例代碼

      Redis 實現(xiàn)好友關(guān)注和關(guān)注推送的示例代碼

      本文介紹了使用Redis實現(xiàn)好友關(guān)注和關(guān)注推送功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
      2025-03-03
    • 利用Supervisor管理Redis進(jìn)程的方法教程

      利用Supervisor管理Redis進(jìn)程的方法教程

      Supervisor 是可以在類 UNIX 系統(tǒng)中進(jìn)行管理和監(jiān)控各種進(jìn)程的小型系統(tǒng)。它自帶了客戶端和服務(wù)端工具,下面這篇文章主要給大家介紹了關(guān)于利用Supervisor管理Redis進(jìn)程的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
      2017-08-08
    • Redis的9種數(shù)據(jù)類型用法解讀

      Redis的9種數(shù)據(jù)類型用法解讀

      這篇文章主要介紹了Redis的9種數(shù)據(jù)類型用法及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
      2023-02-02
    • Redis+Caffeine兩級緩存的實現(xiàn)

      Redis+Caffeine兩級緩存的實現(xiàn)

      本文主要介紹了Redis+Caffeine兩級緩存的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
      2022-06-06
    • Redis作為分布式鎖的使用詳解

      Redis作為分布式鎖的使用詳解

      這篇文章主要介紹了Redis作為分布式鎖的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
      2025-05-05
    • 基于?Spring?Aop?環(huán)繞通知實現(xiàn)?Redis?緩存雙刪功能(示例代碼)

      基于?Spring?Aop?環(huán)繞通知實現(xiàn)?Redis?緩存雙刪功能(示例代碼)

      基于 spring aop 常規(guī)應(yīng)用場景多是用于日志記錄以及實現(xiàn) redis 分布式鎖,在 github 中也有項目是把它拿來當(dāng)作緩存的異常捕捉,這篇文章主要介紹了基于?Spring?Aop?環(huán)繞通知實現(xiàn)?Redis?緩存雙刪,需要的朋友可以參考下
      2022-08-08
    • 一文弄懂Redis 線程模型

      一文弄懂Redis 線程模型

      使用Redis 時,幾乎不存在 CPU 成為瓶頸的情況, Redis 主要受限于內(nèi)存和網(wǎng)絡(luò) 使用了單線程后,可維護(hù)性高,感興趣的可以了解一下
      2024-02-02
    • 一文詳解Redis的主從同步原理

      一文詳解Redis的主從同步原理

      Redis為了保證服務(wù)高可用,其中一種實現(xiàn)就是主從模式,本篇文章將對主從模式中為了保證主節(jié)點(diǎn)和從節(jié)點(diǎn)數(shù)據(jù)一致而實現(xiàn)的主從同步機(jī)制進(jìn)行學(xué)習(xí),感興趣的同學(xué)可以參考閱讀下
      2023-07-07

    最新評論