Redis叢集操作配置(超詳細配圖,配截圖詳細說明)

1. 為什麼需要叢集-高可用性

為什麼需要叢集-高可用性:
  1. 生產環境的實際需求和問題:
    1. 容量不夠,redis 如何進行擴容。
    2. 併發寫操作,redis 如何分攤。
    3. 主從模式,薪火相傳模式,主機宕機,會導致 ip 地址發生變化,應用程式中配置需要修改對應的主機地址,埠等資訊。
  2. 傳統解決方案 代理主機來解決
上圖解圖:
  1. 客戶端請求先到代理伺服器
  2. 由代理伺服器進行請求轉發到對應的業務處理器
  3. 為了高可用,代理服務,A服務,B服務,C服務都需要搭建主從結構(至少是一主一從 這樣就需求搭建至少 8 臺伺服器)。
  4. 這種方案的缺點是:成本高,維護困難,如果是一主多從,成本就會更高。
redis3.0 提供解決方案 無中心化叢集配置:
  1. 各個 Redis 服務仍然採用主從結構。
  2. 各個 Redis 服務是連通的,任何一臺伺服器,都可以作為請求入口 。
  3. 各個 Redis 伺服器因為是連通的,可以進行請求轉發
  4. 這種方式,就無中心化 叢集配置,可以看到,只需要 6 臺伺服器即可搞定。
  5. 無中心化叢集配置 ,還會根據 key 值,計算 slot ,把資料分散到不同的主機,從而緩解單個主機的存取壓力
  6. Redis 推薦使用無中心化叢集配置。
  7. 在實際生成環境,各個 Redis 伺服器,應當部署到不同的機器(防止機器宕機,主從複製失效)。

2. 叢集概述(及其搭建)

  1. Redis 叢集實現了對 Redis 的水平擴容,即啟動 N 個 Redis 節點,將整個資料庫分佈儲存在這個 N 個節點中,每個節點儲存總數居的 1 / N
  2. Redis 叢集透過分割槽(partition) 來提供一定程度的可用性(availability) ,即使叢集中有一部分節點失效或者無法進行通訊,叢集也可以繼續處理命令請求。
Redis 叢集搭建:實操演示:
  1. redis.conf 配置修改
cluster-enabledyes 開啟叢集模式
cluster-config-filenodes-6379.conf 設定節點配置檔名
cluster-node-timeout15000 設定節點失聯時間,超過該時間(毫秒),叢集自動進行主 從切換
  1. vi /rainbowsea/redis6379.conf , 刪除不必要的內容 增加 cluster 配置, 檔案最後內容,如圖
include/rainbowsea/redis.conf
pidfile"/var/run/redis_6379.pid"
port6379
dbfilename"dump6379.rdb"
masterauthrainbowsea
cluster-enabledyes
cluster-config-filenodes-6379.conf
cluster-node-timeout15000

[root@localhost rainbowsea]

# cp redis6379.conf redis6380.conf

[root@localhost rainbowsea]

# cp redis6379.conf redis6381.conf

[root@localhost rainbowsea]

# cp redis6379.conf redis6389.conf

[root@localhost rainbowsea]

# cp redis6379.conf redis6390.conf

[root@localhost rainbowsea]

# cp redis6379.conf redis6391.conf

[root@localhost rainbowsea]

#

  1. 使用查詢替換修改另外 5 個檔案

換指令 :%s/6379/6380

其它幾個檔案以此操作即可, 操作的時候,一定要小心, 最後建議再檢查一下
所有的都要加上這個 masterauth rainbowsea 加上 Redis 的密碼,沒有設定密碼的則不用配置這個。
所有的都要加上這個 masterauth rainbowsea 加上 Redis 的密碼,沒有設定密碼的則不用配置這個。
所有的都要加上這個 masterauth rainbowsea 加上 Redis 的密碼,沒有設定密碼的則不用配置這個。
include/rainbowsea/redis.conf
pidfile"/var/run/redis_6379.pid"
port6379
dbfilename"dump6379.rdb"
masterauthrainbowsea
cluster-enabledyes
cluster-config-filenodes-6379.conf
cluster-node-timeout15000
  1. 啟動 6 個 Redis 服務

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6379.conf

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6380.conf

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6381.conf

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6389.conf

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6390.conf

[root@localhost rainbowsea]

# redis-server /rainbowsea/redis6391.conf

[root@localhost rainbowsea]

# ps -aux | grep redis

  1. 將六個節點合成一個叢集
進入到該路徑下後,將六個節點合成一個叢集的指令:
如下這個是 Redis 沒有配置密碼的,指令

redis-cli --cluster create --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391

如下這個是 Redis 配置了密碼的,指令

redis-cli --cluster create -a rainbowsea --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391

注意事項和細節:
  1. 組合之前,確保所有(你要使用上的埠的) Redis伺服器都是啟動的,同時在 root 目錄下(我這裡是 root 配置的) nodes-xxxx.conf 檔案都生成正常。
  2. 此時不可以用 127.0.0.1 ,需要使用真實的 IP地址(就是你連線 Linux 的地址,Linux 當中使用ifconfig 指令查詢到的地址),在真實生產環境 IP都是獨立的。
  3. replicas 1 採用最簡單的方式配置叢集,一臺主機,一臺從機,正好三組。
  4. 搭建加群如果沒有成功,把 sentinel 程序關閉掉,再試一下。
  5. 分許主從對應關係。
  • 分析主從對應關係:如下
  1. 叢集方式登入:
指令: redis-cli -c -p 6379
指令: cluster nodes 命令檢視叢集資訊, 主從的對應關係, 主要看這裡我標註的顏色

[root@localhost src]

# redis-cli -c -p 6379

127.0.0.1:6379> auth rainbowsea

127.0.0.1:6379> cluster nodes

注意事項和細節:

[root@localhost src]

# redis-cli -c -p 6379

  1. 一個叢集至少要有三個主節點。
  2. 選項 --cluster-replicas 1 表示我們希望為叢集中的每個主節點建立一個從節點。
  3. 分配原則: 儘量保證主伺服器和從伺服器各自執行在不同的 IP 地址(機器),防止機器故障導致主從機制失效,高可用性得不到保障。

3. Redis 叢集的使用

什麼是 slots:
Redis 叢集啟動後, 你會看到如下提示:

  1. 一個 Redis 叢集包含了 16384 個插槽(hash slot) ,編號從 0-16383 ,Redis 中的每個鍵都屬於這 16384 個插槽的其中一個。注意:這裡雖然只有 16384個插槽,但是並不是只能插入 16384個鍵,多個不同的鍵可以插入到同一個插槽的,並不是一個插槽一個鍵的 。
  2. 叢集使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽,其中 CRC16(key) 語句用於計算鍵 key 的 CRC16的校驗和
  1. 叢集中的每個節點負責處理一部分插槽。舉個例子:如果一個叢集可以有主節點,其中
  • 節點 A 負責處理 0號 ~ 5460號 插槽
  • 節點 B 負責處理 5461號 ~ 10922號 插槽
  • 節點 C 負責處理 10923號 ~ 16383號 插槽
在叢集中錄入值:
  1. 在 Redis 每次錄入,查詢鍵值,redis 都會計算出該 key 應該送往的插槽,如果不是該客戶端對應伺服器的插槽,redis 會告知前往的 Redis 例項地址和埠。
  2. Redis-cli 客戶端提供了 -c 引數實現自動重定向。
  3. 如 redis-cli -c -p 6379 登入後,再錄入,查詢鍵值對可以自動重定向
  • 不在一個 slot 下的鍵值,是不能使用 mget,mset 等多鍵操作

192.168.76.147:6381> mset k1

"v1"

k2

"v2"

k3

"v3"

  • 可以透過{}來定義組的概念,從而使 key 中{}內相同內容的鍵值對放到一個 slot 中去,就解決了上面 mget 分佈到不同 slot 而導致失敗的原因。

192.168.76.147:6381> mest k1{order}

"v1"

k2{order}

"v2"

k3{order}

"v3"

注意:你如果對鍵加上了{}組,那麼你想要獲取到該值的時候,也是要加上對應的{}組的,才能獲取到的。
查詢叢集中的值:
  1. 指令: CLUSTER KEYSLOT <key> 返回 key 對應的 slot 值

192.168.76.147:6381> cluster keyslot k1

192.168.76.147:6381> cluster keyslot k2{order}

可以看到歸屬於{}同一組的,Redis都是分配到了同一個 slot 插槽數值當中。
  1. 指令: CLUSTER COUNTKEYSINSLOT <slot> 返回 slot 有多少個 key

192.168.76.147:6381> cluster countkeysinslot 12706

(

integer

) 1

192.168.76.147:6381> cluster countkeysinslot 16025

(

integer

) 3

  1. 指令: CLUSTER GETKEYSINSLOT <slot><count>返回 count 個 slot 槽中的鍵

192.168.76.147:6381> cluster getkeysinslot 16025 1

1)

"k1{order}"

192.168.76.147:6381> cluster getkeysinslot 16025 2

1)

"k1{order}"

2)

"k2{order}"

192.168.76.147:6381> cluster getkeysinslot 16025 3

4. Redis 叢集故障恢復

  1. 如果主節點下線, 從節點會自動升為主節點(注意 15 秒超時, 再觀察比較準確)

[root@localhost ~]

# redis-cli -c -p 6380

這裡我們將 6380 主機關閉了。
  • 主節點恢復後,主節點回來變成從機
如果所有某一段插槽的主從節點都宕掉了 ,Redis 服務是否還能繼續,要根據不同的配置而言。
  1. 如果某一段插槽的主從 都宕機了,而在 redis.conf 配置檔案當中 cluster-require-full-coverage 為 yes ,那麼,整個叢集都會被宕掉,無法使用。
  2. 如果某一段插槽的主從 都宕機了,而在 redis.conf 配置檔案當中 cluster-require-full-coverage 為 no ,那麼,僅僅只是該段插槽的資料不能使用了,也無法儲存了,其他插槽的資料還可以繼續使用。
  3. redis.conf 檔案當中的引數 cluster-require-full-coverage

5. Redis 叢集的 Jedis 開發(使用Java程式連線 Redis 同時開啟叢集)

  1. 即使連線的不是主機,叢集會自動切換主機進行儲存,主機寫,從機讀 。
  2. 無中心化主從叢集,無論從哪臺主機寫的資料,其他主機上都能讀到資料。
  3. 注意:需要將 Redis 相關的埠都開啟 否則會報錯
配置防火牆將所有相關 Redis 的埠都開啟。

[root@localhost src]

# firewall-cmd --add-port=6379/tcp --permanent

Warning: ALREADY_ENABLED: 6379:tcp

success

[root@localhost src]

# firewall-cmd --add-port=6380/tcp --permanent

success

[root@localhost src]

# firewall-cmd --add-port=6381/tcp --permanent

success

[root@localhost src]

# firewall-cmd --add-port=6389/tcp --permanent

success

[root@localhost src]

# firewall-cmd --add-port=6390/tcp --permanent

success

[root@localhost src]

# firewall-cmd --add-port=6391/tcp --permanent

[root@localhost src]

# firewall-cmd --reload

[root@localhost src]

# firewall-cmd --list-all

在 pom.xml 當中引入 redis.clients 依賴。如下:
<!-- 引入 jedis 依賴-->

<

dependency

>

<

groupId

>redis.clients</

groupId

>

<

artifactId

>jedis</

artifactId

>

<

version

>3.2.0</

version

>

</

dependency

>

首先測試,是否可以連線到 Redis 伺服器。

package

com.rainbowsea.jedis;

import

org.junit.Test;

import

redis.clients.jedis.Jedis;

publicclassJedisCluster_

{

@Test
publicvoidcon

() {

// 使用 ip地址 + redis的埠的構造器方法
Jedisjedis=newJedis

(

"192.168.76.147"

,

6379

);

// 如果Redis 配置了密碼,則需要進行身份校驗

jedis.auth(

"rainbowsea"

);

Stringping=

jedis.ping();

System.out.println(

"連線成功 ping 返回的結果 = "

+ ping);
jedis.close();

// 關閉當前連線,注意並沒有關閉 Redis

}
}


import

org.junit.Test;

import

redis.clients.jedis.HostAndPort;

import

redis.clients.jedis.Jedis;

import

redis.clients.jedis.JedisCluster;

import

redis.clients.jedis.JedisPoolConfig;

import

java.util.HashSet;

import

java.util.Set;

publicclassJedisCluster_

{

publicstaticvoidmain

(String[] args) {

Set<HostAndPort> set =

newHashSet

<>();

set.add(

newHostAndPort

(

"192.168.76.147"

,

6379

));

JedisPoolConfigjedisPoolConfig=newJedisPoolConfig

();

// 對連線池進行配置

jedisPoolConfig.setMaxTotal(

200

);

jedisPoolConfig.setMaxIdle(

32

);

jedisPoolConfig.setMaxWaitMillis(

60

*

1000

);

// 單位是毫秒

jedisPoolConfig.setBlockWhenExhausted(

true

);

jedisPoolConfig.setTestOnBorrow(

true

);

JedisClusterjedisCluster=newJedisCluster

(set,

5000

,

5000

,

5

,

"rainbowsea"

,jedisPoolConfig );

jedisCluster.set(

"address"

,

"bj"

);

Stringaddress=

jedisCluster.get(

"address"

);

System.out.println(

"address=>"

+ address);

jedisCluster.close();
}

}

6. Redis 叢集的優缺點

優點:
  1. 實現擴容。
  2. 分攤壓力。
  3. 無中心配置相對簡單。
缺點:
  1. 多鍵操作是不被支援的。
  2. 多鍵的 Redis 事務是不被支援的。 lua 指令碼不被支援
  3. 由於叢集方案出現較晚,很多公司已經採用了其他的叢集方案,而其它方案想要遷移至 redis cluster ,需要整體遷移而不是逐步過渡,複雜度較大。

7. 補充:

將 root 目錄下的,rdb、aof 檔案都刪除掉

[root@localhost ~]

# rm -f dump*.rdb

8. 最後:

“在這個最後的篇章中,我要表達我對每一位讀者的感激之情。你們的關注和回覆是我創作的動力源泉,我從你們身上吸取了無盡的靈感與勇氣。我會將你們的鼓勵留在心底,繼續在其他的領域奮鬥。感謝你們,我們總會在某個時刻再次相遇。”
連結:https://www.cnblogs.com/TheMagicalRainbowSea/p/18703659
(版權歸原作者所有,侵刪)


相關文章