redis集羣(redis多機功能篇)

Redis 的集羣

在前面的課程中,我們陸續學習了 Redis 的複製特性,以及 Redis Sentinel 和 twemproxy 這兩個程序,其中:

  • 複製特性可以創建指定服務器的複製品,這些複製品可以用於擴展系統處理讀請求的能力。
  • Redis Sentinel 可以在複製特性的基礎上,通過監視主從服務器並在主服務器故障時執行自動故 障轉移來保證系統的可用性。
  • twemproxy 使用分片策略來將數據 庫劃分到多個不同的服務器,以此來擴展系統儲存的數據量,並通過將命令請求分散給不同的服務器來處理,以此來擴展系統處理命令請求的能力。

以上這些特性或程序都是獨立的,如果我 們需要一個完整地包含複製、高可用和分片特性的 Redis 服務器羣,那麼就需要用到 Redis 的集羣(cluster)特性。

集羣

Redis 的分佈式數據庫實現

分佈式

Redis 集羣是一個由多個 Redis 服務器組成的分佈式網絡服務器羣,集羣中的各個服 務器被稱爲節點(node),這些節點會相互連接並進行通信。

分佈式的 Redis 集羣沒有中心節點,所以用戶不必擔心某個節點會成爲整個集羣的性能瓶頸。
在這裏插入圖片描述
集羣中的三個節點互相連接。

複製

Redis 集羣的每個節點都有兩種角色可選,一個是主節點(master node),另一個是從節點(slave node):其中主節點用於儲存數據,而從節點則是某個主節點的複製品。

當用戶需要處理更多讀請求的時候,添加從節點可以擴展系統的讀性能。因爲 Redis 集羣重用了單機 Redis 複製特性的代碼,所以集羣的複製行爲和我們之前介紹的單機複製特性的行爲是完全一樣的。
在這裏插入圖片描述
爲三個主節點分別添加一個從節點。

節點故障檢測和自動故障轉移

Redis 集羣的主節點內置了類似 Redis Sentinel 的節點故障檢測和自動故障轉移功能,當集羣中的某個主節點下線時,集羣中的其他在線主節點會注意到這一點,並對已下線的主節點進行故障轉移。

集羣進行故障轉移的方法和 Redis Sentinel 進行故障轉移的方法基本一樣,不同的是,在集羣裏面,故障轉移是由集羣中其他在線的主節點負責進行的,所以集羣不必另外使用 Redis Sentinel 。

當 7000 下線時,7001 和 7002 會察覺到這一點,並對 7000 進行故障轉移。
在這裏插入圖片描述

分片

集羣使用分片來擴展數據庫的容量,並將命令請求的負載交給不同的節點來分擔。

集羣將整個數據庫分爲 16384 個槽(slot),所有鍵都屬於這 16384 個槽的其中一個,計算鍵 key 屬於哪個槽的公式爲 slot_number = crc16(key) % 16384 ,其中 crc16 爲 16 位的循環冗餘校驗和函數。

集羣中的每個主節點都可以處理 0 個至 16384 個槽,當 16384 個槽都有某個節點在負責處理時,集羣進入上線狀態,並開始處理客戶端發送的數據命令請求。

比如說,如果我們有三個主節點 7000 、 7001 和 7002 ,那麼我們可以:

  • 將槽 0 至 5460 指派給節點 7000 負責處理;
  • 將槽 5461 至 10922 指派給節點 7001 負責處理;
  • 將槽 10923 至 16383 指派給節點 7002 負責處理;

這樣就可以將 16384 個槽平均地指派給三個節點負責處理。

轉向

對於一個被指派了槽的主 節點來說,這個主節點只會處理屬於指派給自己的槽的命令請求。

如果一個節點接收到了和自己處理的槽無關的命令請求,那麼節點會向客戶端返回一個轉向錯誤(redirection error),告訴客戶端,哪個節點纔是負責處理這條命令的,之後客戶端需要根據錯誤中包含的地址和端口號重新向正確的 節點發送命令請求。
在這裏插入圖片描述

集羣搭建

設置和建立一個集羣的方法

集羣搭建步驟

搭建一個 Redis 集羣需要執行以下步驟:

  1. 創建多個節點。
  2. 爲每個節點指派槽,並將多個節點連接起來,組成一個集羣。
  3. 當集羣數據庫的 16384 個槽都有節點在處理時,集羣進入上線狀態。

接下來,就讓我們來搭建一個包含六個節點的 Redis 集羣,其中三個節點爲主節點,而另外三個節點 爲從節點,每個主節點都有一個從節點。

注意,在極端情況下,如果將 16384 個槽都指派給一個主節點,那麼只有一個主節點也可以讓集羣進入上線狀態,但是要讓集羣的故障轉移特性生效,最起碼要有三個主節點;而要讓故障轉移真正有意義,最少要爲三個主節點分別設置一個從節點,這也是我們使用六個節點作爲例子的原因。

創建節點

集羣中的節點就是運行在集羣模式下的 Redis 服務器,爲了構建一個集羣,我們需要一一創建集羣中的每個節點。

爲了讓 Redis 服務器以集羣模式運行,我 們需要在啓動服務器時,打開服務器的集羣模式選項:
cluster-enabled yes
另外,如果有多個節點運行在同一臺機器裏面,那麼我 們還需要爲每個節點指定不同的端口號:
port 7000
我們可以將這兩個配置值寫入到 redis.conf 文件裏面,然後執行以下命令來啓動一個節點:
$ redis-server redis.conf

節點運行示例

在這裏插入圖片描述

節點創建示例

爲了在同一臺機器上構建一個包含六個 節點的集羣,其中三個主 節點分別運行在機器的 7000 、 7001 和 7002 端口,而三個從節點則分別運行在機器的 7003 、 7004 和 7005 端口,我們可以先創建一個 rediscluster 文件夾,然後分別創建 7000 至 7005 這六個文件夾,每個文件夾都包含一個 redis.conf 文件,它的內容爲:
port
cluster-enabled yes
然後只要分別執行:
~/rediscluster/7000$ redis-server redis.conf

~/rediscluster/7005$ redis-server redis.conf

就可以創建出六個節點了(節點啓動時默認爲主節點,之後要將其中三個 節點轉爲從節點)。

創建集羣

在創建出六個節點之後,我們需要讓這六個節點互相連接以構成一個集羣,然後爲三個主節點指派槽,併爲這三個主節點分別設置一個從節點。

創建集羣的操作可以通過使用位於 Redis 安裝文件夾內的 redis-trib.rb 程序來完成,這是一個使用 Ruby 編寫的 Redis 集羣管理程序,它具有創建集羣、檢查集羣的上線情況和槽指派情況、對集羣進行重新分片、向集羣添加新節點或者從集羣中移除節點等功能。

不帶任何參數地執行 redis-trib.rb 可以看到它的各項用法:
在這裏插入圖片描述

redis-trib.rb 的 create 方法

爲了創建一個包含三個主節點和三個從節點的集羣,我們需要執行以下命令:
$ ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

其中,create 方法表示我們要創建一個集羣,而之後的 --replicas 1 則表示讓 redis-trib.rb 爲集羣中的每個主節點設置一個從節點,再之後輸入的是各個節點的 IP 地址和端口號。

在輸入該命令之後, redis-trib 會爲各個節點指派槽以及角色,並 詢問用戶是否接受這種節點配置。

節點配置

redis-trib.rb 首先嚐試連接給定的六個節點,檢查它們是否存在。

在確定這些節點都是可連接之後,redistrib.rb 再將 7000 、 7001 和 7002 設 置爲主節點,而 7003 、 7004 和 7005 則分別被設置爲三個主節點的從節點。

對於三個主節點,redis-trib.rb 會分別爲它們指派 5461 、 5462 和 5461 個槽(默認情況下使用平均分配)。

如果覺得這個配置沒問題的話,就可以鍵 入 yes 並按下回車。
在這裏插入圖片描述

連接各個節點

在這裏插入圖片描述
在鍵入 yes 之後, redis-trib.rb 就會向各個節點發送指令,首先將它們連接爲一個集羣,然後再爲它們指派槽和設置角色。

進行測試

在這裏插入圖片描述
之後, redis-trib.rb 會對集羣進行測試,檢查是否每個節點都按照原先展示的配置 設置好了。

如果整個集羣數據庫的 16384 個槽都有節點在處理,那麼集羣就會進入上線狀態,之後用戶就可以開始向集羣發送命令請求了。

訪問集羣

使用集羣客戶端向集羣發送命令請求

集羣客戶端

因爲集羣功能比起單機功能要複雜得多,所以不同語言的 Redis 客戶端通常需要爲集羣添加特別的支持,或者專門開發一個集羣客戶端。

目前主要的 Redis 集羣客戶端(或者說,支持集羣功能的 Redis 客戶端)有以下這些:

  • redis-rb-cluster:antirez 使用 Ruby 編寫的 Redis 集羣客戶端,集羣客戶端的官方實現。 - predis:Redis 的 PHP 客戶端,支持集羣功能。
  • jedis:Redis 的 JAVA 客戶端,支持集羣功能。
  • StackExchange.Redis:Redis 的 C# 客戶端,支持集羣功能。
  • 內置的 redis-cli :在啓動時給定 -c 參數即可進入集羣模式,支持部分集羣功能。

爲了讓示例保持簡單,我們這裏使用集羣模式的 redis-cli 來進行演示,需要更完整功能的 話,大家可以選擇上面列舉的其他客戶端。

連接節點並執行命令
$ redis-cli -p 7000 -c
127.0.0.1:7000> SET date 2014-10-10 # 鍵 date 所在的槽位於節點 7000 ,節點直接執行命令
OK
127.0.0.1:7000> SET msg "hello world" # 鍵 msg 所在的槽位於節點 7001
-> Redirected to slot [6257] located at 127.0.0.1:7001 # 客戶端從 7000 轉向至 7001
OK
127.0.0.1:7001> SADD fruits “apple” “banana” “cherry” # 鍵 fruits 所在的槽位於節點 7002
-> Redirected to slot [14943] located at 127.0.0.1:7002 # 客戶端從 7001 轉向至 7002
(integer) 2
127.0.0.1:7002> # 轉向是自動完成的,無需任何用戶操作

複習

本節重點

Redis 集羣是一個由多個節點組成的分佈式服務器羣,它具有複製、高可用和分片特性。

Redis 的集羣沒有中心節點,並且帶有複製和故障轉移特性,這可以避免單個節點成爲性能瓶頸,或者因爲某個節點下線而導致整個集羣下線。

集羣中的主節點負責處理槽(儲存數據),而從節點則是主節點的複製品。

Redis 集羣將整個數據庫分爲 16384 個槽,數據庫中的每個鍵都屬於 16384 個槽中的其中一個。

集羣中的每個主節點都可以負責 0 個至 16384 個槽,當 16384 個槽都有節點在負責時,集羣進入 上線狀態,可以執行客戶端發送的數據命令。

主節點只會執行和自己負責的槽有關的命令,當節點接收到不屬於自己處理的槽的命令時,它會將處理指定槽的節點的地址返回給客戶端,而客戶端會向正確的節點重新發送命令,這個過程稱爲“轉向”。

集羣和 twemproxy 的區別

在這裏插入圖片描述
結論:如果需要完整的分片、複製和高可用特性,並且要避免使用代理 帶來的性能瓶頸和資源消耗,那麼可以選擇使用 Redis 集羣;如果只需要一部分特性(比如只需要分片,但不需要複製和高可用, 諸如此類),那麼可以單獨選擇 twemproxy 、Redis 複製和 Redis Sentinel 中的一個或多個。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章