詳解三分鐘快速搭建分布式高可用的Redis集群

2021-10-19 05:23:38 字數 3996 閱讀 1385

這裡的redis集群指的是redis cluster,它是redis在3.0版本正式推出的專用集群方案,有效地解決了redis分布式方面的需求。當單機記憶體、併發、流量等遇到瓶頸的時候,可以採用這種redis cluster方案進行解決。

分割槽規則

redis cluster採用虛擬槽(slot)進行資料分割槽,即使用分散度良好的雜湊函式把所有鍵對映到乙個固定範圍的整數集合裡,這裡的整數就是槽(slot)。redis cluster槽的範圍是0~16383,計算公式:slot=crc16(key) & 16383。

白嫖小貼士:crc16是一種高質量的雜湊演算法,可以使每個槽所對映的鍵通常比較均勻。

當集群中有3個節點時,每個節點平均大概負責5461個槽以及槽所對映的鍵值資料。這樣一來,可以解耦資料與節點之間的關係,簡化節點擴容和縮容的難度。節點自身維護槽的對映關係,不需要客戶端或**服務維護分割槽資訊。

不過,redis cluster相對於單機還是存在一些限制的,比如:

批量操作鍵支援有限,僅支援具有相同槽的鍵進行批量操作。

事務操作鍵支援有限,僅支援在同乙個節點上多個鍵的事務操作。

不支援多個資料空間。單機redis可以支援16個資料庫,而cluster模式下只能使用乙個資料庫空間。

扯了這麼多redis cluster的分割槽規則,下面我們開始步入正題。

手動搭建

把redis cluster搭建起來總共幾步?答:三步!第一步把冰箱門開啟。第二步把大象關進去。第三步把冰箱門帶上。不好意思,段子暴露年齡了。集群搭建需要以下三個步驟:

準備節點。

節點握手。

分配槽。

redis cluster由多個節點組成,節點數量至少有6個才能組成乙個完整高可用的集群,其中有3個主節點和3個從節點,我們就以此為例搭建乙個redis cluster。

準備節點

首先,為6個節點(同一臺機器上的6380、6381、6382、6383、6384、6385埠)分別建立配置檔案,以6380埠的節點為例:12

3456

78# 節點埠

port 6380

#日誌檔案

logfile "log/redis-6380.log"

# 開啟集群模式

cluster-enabled yes

# 集群配置檔案

cluster-config-file "data/nodes-6380.conf"

保持檔名為redis-6380.conf,其他節點的配置檔案替換成各自的埠。準備好配置檔案後啟動所有節點,命令如下:12

3456

src/redis-server conf/redis-6380.conf &

src/redis-server conf/redis-6381.conf &

src/redis-server conf/redis-6382.conf &

src/redis-server conf/redis-6383.conf &

src/redis-server conf/redis-6384.conf &

src/redis-server conf/redis-6385.conf &

檢測日誌是否正確,以下是6380埠的節點的日誌:12

345# oo0ooo0ooo0oo redis is starting oo0ooo0ooo0oo

# redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=3031, just started

# configuration loaded

* no cluster configuration found, i'm df1ac987f47dea35f1d0a83c3b405f0ef86892ab

* running mode=cluster, port=6380.

6380埠的節點啟動成功,第一次啟動時如果沒有集群配置檔案,redis會自動建立乙個。6380埠的節點建立的集群配置檔案如下:12

df1ac987f47dea35f1d0a83c3b405f0ef86892ab :0@0 myself,master - 0 0 0 connected

vars currentepoch 0 lastvoteepoch 0

集群檔案中記錄的集群的狀態,這裡最重要的是節點id,它是乙個40位的16進製制字串,用於唯一標識集群中的這個節點。同樣,也可以通過cluster nodes命令檢視集群節點狀態。比如在6380埠的節點上執行命令:12

127.0.0.1:6380> cluster nodes

df1ac987f47dea35f1d0a83c3b405f0ef86892ab :6380@16380 myself,master - 0 0 0 connected

目前,我們已經成功啟動了6個節點,但是它們只能識別自己的節點資訊,互相之間並不認識。下面我們通過節點握手讓這6個節點互相之間建立聯絡從而組成乙個集群。

節點握手

節點握手是一些執行在集群模式下的節點通過gossip協議互相通訊,達到感知彼此的過程。

白嫖小貼士:gossip協議是基於流行病傳播方式的節點或者程序之間資訊交換的協議,在分布式系統中被廣泛使用。

節點握手通過客戶端執行cluster meet命令實現,它是乙個非同步命令,執行之後立刻返回,在redis內部非同步發起與目標節點的握手通訊,該命令的語法如下:

1cluster meet 目標節點ip 目標節點埠

把6個節點加到乙個集群中:12

3456

78910

127.0.0.1:6380> cluster meet 127.0.0.1 6381

ok127.0.0.1:6380> cluster meet 127.0.0.1 6382

ok127.0.0.1:6380> cluster meet 127.0.0.1 6383

ok127.0.0.1:6380> cluster meet 127.0.0.1 6384

ok127.0.0.1:6380> cluster meet 127.0.0.1 6385

ok只需要在集群中任意節點上執行cluster meet命令加入新的節點,握手狀態會通過訊息在集群中傳播,其他節點也會自動發現新節點並與之發起握手流程。

我們再執行一下cluster nodes命令,檢查一下6個節點是否已經組成集群:12

3456

7127.0.0.1:6380> cluster nodes

1e1f45677d7b9b0130d03193f0bcec34578ac47d 127.0.0.1:6385@16385 master - 0 1586617919021 5 connected

df1ac987f47dea35f1d0a83c3b405f0ef86892ab 127.0.0.1:6380@16380 myself,master - 0 1586617916000 2 connected

5846b66ebe4fb4a5dcfd035652cc471f7e412752 127.0.0.1:6381@16381 master - 0 1586617917005 1 connected

a435cf98c3444b0b110a224401e397a107c453ef 127.0.0.1:6384@16384 master - 0 1586617914988 4 connected

71e0e9e9a6f0c7c85dbe0d396846a9072625c5e8 127.0.0.1:6383@16383 master - 0 1586617918013 3 connected

e25590603c7a254cce43aa8437861c5c425d753d 127.0.0.1:6382@16382 master - 0 1586617916000 0 connected

可以看到,6個節點都在集群中了。不過,此時因為還沒有為集群中的節點分配槽,集群還處於下線狀態,所有的資料讀寫都是被禁止的。比如:12

127.0.0.1:6380> set onemore study

(error) clusterdown hash slot not served

接下來,我們為集群中的節點分配槽。

三分鐘快速了解typeScript 類

類描述了所建立的物件共同的屬性和方法。類的定義 繼承類裡面的修飾符 靜態屬性 靜態方法 抽象類 繼承 多型 類的定義class person run void var p newperson fur console.log p.name fur p.run fur在跑步繼承 run方法說明 子類繼承...

jQuery三分鐘輕鬆快速入門

某個東東無論多麼好,自己想用時再學才是最好的。下面跟著學習jquery這個很強的js庫的使用 1 引用google 3 接下來要選擇document中的某個id,類似以前我們經常用的 document.getelementbyid id name 而在jquery中可以這樣方便選擇 內容.這樣就可以...

三分鐘快速了解模組和命名空間

模組的的概念 外部模組 現在則簡稱為 模組 模組在其自身的作用域裡執行,而不是在全域性作用域裡 內部模組 現在稱做 命名空間 這意味著定義在乙個模組裡的變數,函式,類等等在模組外部是不可見的,除非你明確地使用export形式之一匯出它們。相反,如果想使用其它模組匯出的變數,函式,類,介面等的時候,你...