Ubuntu 16.04下Redis Cluster集羣搭建(官方原始方案)

前提:先安裝好Redis,參考:http://www.cnblogs.com/EasonJim/p/7599941.htmlhtml

說明:Redis Cluster集羣模式能夠作到動態增長節點和下線節點,使用起來很是的方便。node

下面教程主要是經過官方提供的文檔進行搭建測試:mysql

https://redis.io/topics/cluster-tutorialredis

http://www.redis.cn/topics/cluster-tutorial.html算法

http://ifeve.com/redis-cluster-tutorial/sql

http://ifeve.com/redis-cluster-spec/(翻譯自官方高級使用教程)數據庫

上面中文教程均可以在官方提供的文檔中找到。vim

原理應該以下圖所示:ruby

注意:如下的搭建教程比較簡單,基於僞集羣的模式,若是是生產環境能夠每臺機部署一個實例。操做基本一致。bash

這篇教程是Redis集羣的簡要介紹,而非講解分佈式系統的複雜概念。它主要從一個使用者的角度介紹如何搭建、測試和使用Redis集羣,至於Redis集羣的詳細設計將在「Redis集羣規範」中進行描述。

本教程以redis使用者的角度,用簡單易懂的方式介紹Redis集羣的可用性和一致性。

注意: 本教程要求Redis3.0或以上的版本。

若是你打算部署Redis集羣,你能夠讀一些關於集羣的詳細設計,固然,這不是必須的。由這篇教程入門,先大概使用一下Redis的集羣,而後再讀Redis集羣的詳細設計,也是不錯的選擇。

Redis集羣 101

Redis集羣在啓動的時候就自動在多個節點間分好片。同時提供了分片之間的可用性:當一部分redis節點故障或網絡中斷,集羣也能繼續工做。可是,當大面積的節點故障或網絡中斷(好比大部分的主節點都不可用了),集羣就不能使用。

因此,從實用性的角度,Redis集羣提供如下功能:

  • 自動把數據切分到多個Redis節點中
  • 當一部分節點掛了或不可達,集羣依然能繼續工做

Redis集羣的TCP端口

Redis集羣中的每一個節點都須要創建2個TCP鏈接,監聽這2個端口:一個端口稱之爲「客戶端端口」,用於接受客戶端指令,與客戶端交互,好比6379;另外一個端口稱之爲「集羣總線端口」,是在客戶端端口號上加10000,好比16379,用於節點之間經過二進制協議通信。各節點經過集羣總線檢測宕機節點、更新配置、故障轉移驗證等。客戶端只能使用客戶端端口,不能使用集羣總線端口。請確保你的防火牆容許打開這兩個端口,不然Redis集羣無法工做。客戶端端口和集羣總線端口之間的差值是固定的,集羣總線端口比客戶端端口高10000。

注意,關於集羣的2個端口:

  • 客戶端端口(通常是6379)須要對全部客戶端和集羣節點開放,由於集羣節點須要經過該端口轉移數據。
  • 集羣總線端口(通常是16379)只需對集羣中的全部節點開放

這2個端口必須打開,不然集羣無法正常工做。

集羣節點之間經過集羣總線端口交互數據,使用的協議不一樣於客戶端的協議,是二進制協議,這能夠減小帶寬和處理時間。

Redis集羣數據的分片

Redis集羣不是使用一致性哈希,而是使用哈希槽。整個Redis集羣有16384個哈希槽,決定一個key應該分配到那個槽的算法是:計算該key的CRC16結果再模16834。

集羣中的每一個節點負責一部分哈希槽,好比集羣中有3個節點,則:

  • 節點A存儲的哈希槽範圍是:0 – 5500
  • 節點B存儲的哈希槽範圍是:5501 – 11000
  • 節點C存儲的哈希槽範圍是:11001 – 16384

這樣的分佈方式方便節點的添加和刪除。好比,須要新增一個節點D,只須要把A、B、C中的部分哈希槽數據移到D節點。一樣,若是但願在集羣中刪除A節點,只須要把A節點的哈希槽的數據移到B和C節點,當A節點的數據所有被移走後,A節點就能夠徹底從集羣中刪除。

由於把哈希槽從一個節點移到另外一個節點是不須要停機的,因此,增長或刪除節點,或更改節點上的哈希槽,也是不須要停機的。

若是多個key都屬於一個哈希槽,集羣支持經過一個命令(或事務, 或lua腳本)同時操做這些key。經過「哈希標籤」的概念,用戶可讓多個key分配到同一個哈希槽。哈希標籤在集羣詳細文檔中有描述,這裏作個簡單介紹:若是key含有大括號」{}」,則只有大括號中的字符串會參與哈希,好比」this{foo}」和」another{foo}」這2個key會分配到同一個哈希槽,因此能夠在一個命令中同時操做他們。

Redis集羣的主從模式

爲了保證在部分節點故障或網絡不通時集羣依然能正常工做,集羣使用了主從模型,每一個哈希槽有一(主節點)到N個副本(N-1個從節點)。在咱們剛纔的集羣例子中,有A,B,C三個節點,若是B節點故障集羣就不能正常工做了,由於B節點中的哈希槽數據無法操做。可是,若是咱們給每個節點都增長一個從節點,就變成了:A,B,C三個節點是主節點,A1, B1, C1 分別是他們的從節點,當B節點宕機時,咱們的集羣也能正常運做。B1節點是B節點的副本,若是B節點故障,集羣會提高B1爲主節點,從而讓集羣繼續正常工做。可是,若是B和B1同時故障,集羣就不能繼續工做了。

Redis集羣的一致性保證

Redis集羣不能保證強一致性。一些已經向客戶端確認寫成功的操做,會在某些不肯定的狀況下丟失。

產生寫操做丟失的第一個緣由,是由於主從節點之間使用了異步的方式來同步數據。

一個寫操做是這樣一個流程:

      1)客戶端向主節點B發起寫的操做
      2)主節點B迴應客戶端寫操做成功
      3)主節點B向它的從節點B1,B2,B3同步該寫操做

從上面的流程能夠看出來,主節點B並無等從節點B1,B2,B3寫完以後再回復客戶端此次操做的結果。因此,若是主節點B在通知客戶端寫操做成功以後,但同步給從節點以前,主節點B故障了,其中一個沒有收到該寫操做的從節點會晉升成主節點,該寫操做就這樣永遠丟失了。

就像傳統的數據庫,在不涉及到分佈式的狀況下,它每秒寫回磁盤。爲了提升一致性,能夠在寫盤完成以後再回復客戶端,但這樣就要損失性能。這種方式就等於Redis集羣使用同步複製的方式。

基本上,在性能和一致性之間,須要一個權衡。

若是真的須要,Redis集羣支持同步複製的方式,經過WAIT指令來實現,這可讓丟失寫操做的可能性降到很低。但就算使用了同步複製的方式,Redis集羣依然不是強一致性的,在某些複雜的狀況下,好比從節點在與主節點失去鏈接以後被選爲主節點,不一致性仍是會發生。

這種不一致性發生的狀況是這樣的,當客戶端與少數的節點(至少含有一個主節點)網絡聯通,但他們與其餘大多數節點網絡不通。好比6個節點,A,B,C是主節點,A1,B1,C1分別是他們的從節點,一個客戶端稱之爲Z1。

當網絡出問題時,他們被分紅2組網絡,組內網絡聯通,但2組之間的網絡不通,假設A,C,A1,B1,C1彼此之間是聯通的,另外一邊,B和Z1的網絡是聯通的。Z1能夠繼續往B發起寫操做,B也接受Z1的寫操做。當網絡恢復時,若是這個時間間隔足夠短,集羣仍然能繼續正常工做。若是時間比較長,以至B1在大多數的這邊被選爲主節點,那剛纔Z1發給B的寫操做都將丟失。

注意,Z1給B發送寫操做是有一個限制的,若是時間長度達到了大多數節點那邊能夠選出一個新的主節點時,少數這邊的全部主節點都不接受寫操做。

這個時間的配置,稱之爲節點超時(node timeout),對集羣來講很是重要,當達到了這個節點超時的時間以後,主節點被認爲已經宕機,能夠用它的一個從節點來代替。一樣,在節點超時時,若是主節點依然不能聯繫到其餘主節點,它將進入錯誤狀態,再也不接受寫操做。

Redis集羣參數配置

咱們後面會部署一個Redis集羣做爲例子,在那以前,先介紹一下集羣在redis.conf中的參數。

  • cluster-enabled <yes/no>: 若是配置」yes」則開啓集羣功能,此redis實例做爲集羣的一個節點,不然,它是一個普通的單一的redis實例。
  • cluster-config-file <filename>: 注意:雖然此配置的名字叫「集羣配置文件」,可是此配置文件不能人工編輯,它是集羣節點自動維護的文件,主要用於記錄集羣中有哪些節點、他們的狀態以及一些持久化參數等,方便在重啓時恢復這些狀態。一般是在收到請求以後這個文件就會被更新。
  • cluster-node-timeout <milliseconds>: 這是集羣中的節點可以失聯的最大時間,超過這個時間,該節點就會被認爲故障。若是主節點超過這個時間仍是不可達,則用它的從節點將啓動故障遷移,升級成主節點。注意,任何一個節點在這個時間以內若是仍是沒有連上大部分的主節點,則此節點將中止接收任何請求。
  • cluster-slave-validity-factor <factor>: 若是設置成0,則不管從節點與主節點失聯多久,從節點都會嘗試升級成主節點。若是設置成正數,則cluster-node-timeout乘以cluster-slave-validity-factor獲得的時間,是從節點與主節點失聯後,此從節點數據有效的最長時間,超過這個時間,從節點不會啓動故障遷移。假設cluster-node-timeout=5,cluster-slave-validity-factor=10,則若是從節點跟主節點失聯超過50秒,此從節點不能成爲主節點。注意,若是此參數配置爲非0,將可能出現因爲某主節點失聯卻沒有從節點能頂上的狀況,從而致使集羣不能正常工做,在這種狀況下,只有等到原來的主節點從新迴歸到集羣,集羣才恢復運做。
  • cluster-migration-barrier <count>:主節點須要的最小從節點數,只有達到這個數,主節點失敗時,它從節點纔會進行遷移。更詳細介紹能夠看本教程後面關於副本遷移到部分。
  • cluster-require-full-coverage <yes/no>:在部分key所在的節點不可用時,若是此參數設置爲」yes」(默認值), 則整個集羣中止接受操做;若是此參數設置爲」no」,則集羣依然爲可達節點上的key提供讀操做。

建立和使用Redis集羣

注意:手動部署Redis集羣可以很好的瞭解它是如何運做的,但若是你但願儘快的讓集羣運行起來,能夠跳過本節和下一節,直接到」使用create-cluster腳本建立Redis集羣」章節。

要建立集羣,首先須要以集羣模式運行的空redis實例。也就說,以普通模式啓動的redis是不能做爲集羣的節點的,須要以集羣模式啓動的redis實例纔能有集羣節點的特性、支持集羣的指令,成爲集羣的節點。

下面是最小的redis集羣的配置文件(redis.conf):

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

開啓集羣模式只需打開cluster-enabled配置項便可。每個redis實例都包含一個配置文件,默認是nodes.conf(啓動時會自動生成),用於存儲此節點的一些配置信息。這個配置文件由redis集羣的節點自行建立和更新,不能由人手動地去修改。

一個最小的集羣須要最少3個主節點。第一次測試,強烈建議你配置6個節點:3個主節點和3個從節點。

開始測試,步驟以下:先進入新的目錄,以redis實例的端口爲目錄名,建立目錄,咱們將在這些目錄裏運行咱們的實例。

相似這樣:

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

在7000-7005的每一個目錄中建立配置文件redis.conf,內容就用上面的最簡配置作模板,注意修改端口號,改成跟目錄一致的端口。

把你的Redis服務器(用GitHub中的不穩定分支的最新的代碼編譯來/或者穩定代碼)拷貝到cluster-test目錄,而後打開6個終端頁準備測試。

第一臺:

在每一個終端啓動一個redis實例,指令相似這樣:

cd 7000
../redis-server ./redis.conf

在日誌中咱們能夠看到,因爲沒有nodes.conf文件不存在,每一個節點都給本身一個新的ID。

[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1

這個ID將一直被此節點使用,做爲此節點在整個集羣中的惟一標識。節點區分其餘節點也是經過此ID來標識,而非IP或端口。IP能夠改,端口能夠改,但此ID不能改,直到這個節點離開集羣。這個ID稱之爲節點ID(Node ID)。

第二臺:

第三臺:

第四臺:

第五臺:

第六臺:

重複第一臺的操做。

建立集羣

如今6個實例已經運行起來了,咱們須要給節點寫一些有意義的配置來建立集羣。redis集羣的命令工具redis-trib可讓咱們建立集羣變得很是簡單。redis-trib是一個用ruby寫的腳本,用於給各節點發指令建立集羣、檢查集羣狀態或給集羣從新分片等。redis-trib在Redis源碼的src目錄下,須要gem redis來運行redis-trib。

gem install redis

建立集羣只需輸入指令:

./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實例的地址。

咱們建立的集羣有3個主節點和3個從節點。

redis-trib會給你一些配置建議,輸入yes表示接受。集羣會被配置並彼此鏈接好,意思是各節點實例被引導彼此通話並最終造成集羣。最後,若是一切順利,會看到相似下面的信息:

[OK] All 16384 slots covered

這表示,16384個哈希槽都被主節點正常服務着。

使用create-cluster腳本建立redis集羣

若是你不想像上面那樣,單獨的手工配置各節點的方式來建立集羣,還有一個更簡單的系統(固然也無法瞭解到集羣運做的一些細節)。

在utils/create-cluster目錄下,有一個名爲create-cluster的bash腳本。若是須要啓動一個有3個主節點和3個從節點的集羣,只須要輸入如下指令

#1
create-cluster start #2
create-cluster create

在步驟2,當redis-trib要你接受集羣的佈局時,輸入」yes」。

如今你能夠跟集羣交互,第一個節點的起始端口默認是30001。當你完成後,中止集羣用以下指令:

create-cluster stop

請查看目錄下的README,它有詳細的介紹如何使用此腳本。

實際操做以下:

版本:4.0.2

下載地址:https://redis.io/download

離線版本:(連接: https://pan.baidu.com/s/1bpwDtOr 密碼: 4cxk)

源碼編譯:

wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar xzf redis-4.0.2.tar.gz
cd redis-4.0.2
make

若是不安裝到指定位置,那麼程序默認放在src文件夾下,

建立集羣文件及文件夾:

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

進入7000建立redis.conf,內容以下:

cd 7000
sudo vim redis.conf
#內容
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

進入7001建立redis.conf,內容以下:

cd 7001
sudo vim redis.conf #內容 port 7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

進入7002建立redis.conf,內容以下:

cd 7002
sudo vim redis.conf #內容 port 7002 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

進入7003建立redis.conf,內容以下:

cd 7003
sudo vim redis.conf #內容 port 7003 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes 

進入7004建立redis.conf,內容以下:

cd 7004
sudo vim redis.conf #內容 port 7004 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

進入7005建立redis.conf,內容以下:

cd 7005
sudo vim redis.conf #內容 port 7005 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

分別啓動6臺集羣:

cd 7000
../redis-server ./redis.conf
cd 7001
../redis-server ./redis.conf
cd 7002
../redis-server ./redis.conf
cd 7003
../redis-server ./redis.conf
cd 7004
../redis-server ./redis.conf
cd 7005
../redis-server ./redis.conf

建立集羣:

先安裝ruby

sudo apt-get ruby

進入src文件夾

再經過gem安裝redis

cd src
gem install redis

若是出現錯誤,參考:http://www.cnblogs.com/EasonJim/p/7629314.html

啓動

./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

期間會提示輸入yes,而後基本完成。輸出的信息上有提示哪些是主節點和從節點。

 

 

參考:

http://ifeve.com/redis-cluster-tutorial/(以上內容部分轉自此篇文章)

http://blog.csdn.net/fengshizty/article/details/51368004 (節點操做的測試)

http://www.redis.cn/topics/cluster-tutorial.html

http://ifeve.com/redis-cluster-spec/

http://os.51cto.com/art/201512/499551.htm

http://blog.csdn.net/robertohuang/article/details/70766809

http://blog.csdn.net/robertohuang/article/details/70768922

http://blog.csdn.net/robertohuang/article/details/70833231

http://blog.chinaunix.net/uid-28396214-id-4981572.html

http://blog.51yip.com/nosql/1725.html

http://www.cnblogs.com/wuxl360/p/5920330.html

http://blog.csdn.net/men_wen/article/details/72853078

http://blog.csdn.net/xu470438000/article/details/42971091

http://www.cnblogs.com/gomysql/p/4395504.html

相關文章
相關標籤/搜索