1. 程式人生 > >redis叢集(Redis Cluster)原理和應用

redis叢集(Redis Cluster)原理和應用

全面剖析Redis Cluster原理和應用

1.Redis Cluster總覽

1.1 設計原則和初衷

官方文件Cluster Spec中,作者詳細介紹了Redis叢集為什麼要設計成現在的樣子。最核心的目標有三個:

  1. 效能:這是Redis賴以生存的看家本領,增加叢集功能後當然不能對效能產生太大影響,所以Redis採取了P2P而非Proxy方式、非同步複製、客戶端重定向等設計,而犧牲了部分的一致性、使用性。
  2. 水平擴充套件:叢集的最重要能力當然是擴充套件,文件中稱可以線性擴充套件到1000結點。
  3. 可用性:在Cluster推出之前,可用性要靠Sentinel保證。有了叢集之後也自動具有了Sentinel的監控和自動Failover能力。

1.2 架構變化與CAP理論

Redis Cluster叢集功能推出已經有一段時間了。在單機版的Redis中,每個Master之間是沒有任何通訊的,所以我們一般在Jedis客戶端或者Codis這樣的代理中做Pre-sharding。按照CAP理論來說,單機版的Redis屬於保證CP(Consistency & Partition-Tolerancy)而犧牲A(Availability),也就說Redis能夠保證所有使用者看到相同的資料(一致性,因為Redis不自動冗餘資料)和網路通訊出問題時,暫時隔離開的子系統能繼續執行(分割槽容忍性,因為Master之間沒有直接關係,不需要通訊),但是不保證某些結點故障時,所有請求都能被響應(可用性,某個Master結點掛了的話,那麼它上面分片的資料就無法訪問了)。

有了Cluster功能後,Redis從一個單純的NoSQL記憶體資料庫變成了分散式NoSQL資料庫,CAP模型也從CP變成了AP。也就是說,通過自動分片和冗餘資料,Redis具有了真正的分散式能力,某個結點掛了的話,因為資料在其他結點上有備份,所以其他結點頂上來就可以繼續提供服務,保證了Availability。然而,也正因為這一點,Redis無法保證曾經的強一致性了。這也是CAP理論要求的,三者只能取其二。

關於CAP理論的通俗講解,請參考我的譯文《可能是CAP理論的最好解釋 》。簡單分析了Redis在架構上的變化後,咱們就一起來體驗一下Redis Cluster功能吧!

2.Redis叢集初探

Redis的安裝很簡單,以前已經介紹過,就不詳細說了。關於Redis Cluster的基礎知識之前也有過整理,請參考《Redis叢集功能預覽》。如果需要全面的瞭解,那一定要看官方文件Cluster Tutorial,只看這一個就夠了!

2.1 叢集配置

要想開啟Redis Cluster模式,有幾項配置是必須的。此外為了方便使用和後續的測試,我還額外做了一些配置:

  • 繫結地址:bind 192.168.XXX.XXX。不能繫結到127.0.0.1或localhost,否則指導客戶端重定向時會報”Connection refused”的錯誤。
  • 開啟Cluster:cluster-enabled yes
  • 叢集配置檔案:cluster-config-file nodes-7000.conf。這個配置檔案不是要我們去配的,而是Redis執行時儲存配置的檔案,所以我們也不可以修改這個檔案。
  • 叢集超時時間:cluster-node-timeout 15000。結點超時多久則認為它宕機了。
  • 槽是否全覆蓋:cluster-require-full-coverage no。預設是yes,只要有結點宕機導致16384個槽沒全被覆蓋,整個叢集就全部停止服務,所以一定要改為no
  • 後臺執行:daemonize yes
  • 輸出日誌:logfile “./redis.log”
  • 監聽埠:port 7000

配置好後,根據我們的叢集規模,拷貝出來幾份同樣的配置檔案,唯一不同的就是監聽埠,可以依次改為7001、7002… 因為Redis Cluster如果資料冗餘是1的話,至少要3個Master和3個Slave,所以我們拷貝出6個例項的配置檔案。為了避免相互影響,為6個例項的配置檔案建立獨立的資料夾。

[[email protected]8gVm redis-3.0.4]# pwd
/root/Software/redis-3.0.4
[[email protected]8gVm redis-3.0.4]# tree -I "*log|nodes*" cfg-cluster/
cfg-cluster/
├── 7000
│   └── redis.conf.7000
├── 7001
│   └── redis.conf.7001
├── 7002
│   └── redis.conf.7002
├── 7003
│   └── redis.conf.7003
├── 7004
│   └── redis.conf.7004
└── 7005
    └── redis.conf.7005

6 directories, 6 files
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.2 redis-trib管理器

Redis作者應該是個Ruby愛好者,Ruby客戶端就是他開發的。這次叢集的管理功能沒有嵌入到Redis程式碼中,於是作者又順手寫了個叫做redis-trib的管理指令碼。redis-trib依賴Ruby和RubyGems,以及redis擴充套件。可以先用which命令檢視是否已安裝ruby和rubygems,用gem list –local檢視本地是否已安裝redis擴充套件。

最簡便的方法就是用apt或yum包管理器安裝RubyGems後執行gem install redis。如果網路或環境受限的話,可以手動安裝RubyGems和redis擴充套件(國外連結可能無法下載,可以從CSDN下載):

[[email protected]8gVm Software]# wget https://github.com/rubygems/rubygems/releases/download/v2.2.3/rubygems-2.2.3.tgz
[[email protected]8gVm Software]# tar xzvf rubygems-2.2.3.tgz 
[[email protected]8gVm Software]# cd rubygems-2.2.3
[[email protected]8gVm rubygems-2.2.3]# ruby setup.rb --no-rdoc --no-ri

[[email protected]8gVm Software]# wget https://rubygems.org/downloads/redis-3.2.1.gem
[[email protected]8gVm Software]# gem install redis-3.2.1.gem --local --no-rdoc --no-ri
Successfully installed redis-3.2.1
1 gem installed
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.3 叢集建立

首先,啟動我們配置好的6個Redis例項。

[[email protected]8gVm redis-3.0.4]# for ((i=0; i<6; ++i))
> do
> cd cfg-cluster/700$i && ../../src/redis-server redis.conf.700$i && cd -
> done
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

此時6個例項還沒有形成叢集,現在用redis-trb.rb管理指令碼建立起叢集。可以看到,redis-trib預設用前3個例項作為Master,後3個作為Slave。因為Redis基於Master-Slave做資料備份,而非像Cassandra或Hazelcast一樣不區分結點角色,自動複製並分配Slot的位置到各個結點

[[email protected] redis-3.0.4]# src/redis-trib.rb create --replicas 1 192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005
>>> Creating cluster
Connecting to node 192.168.1.100:7000: OK
Connecting to node 192.168.1.100:7001: OK
Connecting to node 192.168.1.100:7002: OK
Connecting to node 192.168.1.100:7003: OK
Connecting to node 192.168.1.100:7004: OK
Connecting to node 192.168.1.100:7005: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.1.100:7000
192.168.1.100:7001
192.168.1.100:7002
Adding replica 192.168.1.100:7003 to 192.168.1.100:7000
Adding replica 192.168.1.100:7004 to 192.168.1.100:7001
Adding replica 192.168.1.100:7005 to 192.168.1.100:7002
    ...
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.1.100:7000)
    ...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

至此,叢集就已經建立成功了!“貼心”的Redis還在utils/create-cluster下提供了一個create-cluster指令碼,能夠創建出一個叢集,類似我們上面建立起的3主3從的叢集。

2.4 簡單測試

我們連線到叢集中的任意一個結點,啟動redis-cli時要加-c選項,存取兩個Key-Value感受一下Redis久違的叢集功能。

[[email protected]8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000
192.168.1.100:7000> set foo bar
-> Redirected to slot [12182] located at 192.168.1.100:7002
OK
192.168.1.100:7002> set hello world
-> Redirected to slot [866] located at 192.168.1.100:7000
OK
192.168.1.100:7000> get foo
-> Redirected to slot [12182] located at 192.168.1.100:7002
"bar"
192.168.1.100:7002> get hello
-> Redirected to slot [866] located at 192.168.1.100:7000
"world"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

仔細觀察能夠注意到,redis-cli根據指示,不斷在7000和7002結點之前重定向跳轉。如果啟動時不加-c選項的話,就能看到以錯誤形式顯示出的MOVED重定向訊息。

[[email protected]8gVm redis-3.0.4]# src/redis-cli -h 192.168.1.100 -p 7000
192.168.1.100:7000> get foo
(error) MOVED 12182 192.168.1.100:7002
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

2.5 叢集重啟

目前redis-trib的功能還比較弱,需要重啟叢集的話先手動kill掉各個程序,然後重新啟動就可以了。這也有點太… 網上有人重啟後會碰到問題,我還比較幸運,這種“土鱉”的方式重啟試了兩次還沒發現問題。

[[email protected]8gVm redis-3.0.4]# ps -ef | grep redis | awk '{print $2}' | xargs kill
  • 1
  • 1

3.高階功能嚐鮮

說是“高階功能”,其實在其他分散式系統中早就都有實現了,只不過在Redis世界裡是比較新鮮的。本部分主要試驗一下Redis Cluster中的資料遷移(Resharding)和故障轉移功能。

3.1 資料遷移

本小節我們體驗一下Redis叢集的Resharding功能!

3.1.1 建立測試資料

首先儲存foo1~10共10個Key-Value作為測試資料。

[[email protected]8gVm redis-3.0.4]# for ((i=0; i<10; ++i))
> do
> src/redis-cli -c -h 192.168.1.100 -p 7000 set foo$i bar
> done

[[email protected]8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000
192.168.1.100:7000> keys *
1) "foo6"
2) "foo7"
3) "foo3"
4) "foo2"
192.168.1.100:7000> get foo4
-> Redirected to slot [9426] located at 192.168.1.100:7001
"bar"
192.168.1.100:7001> keys *
1) "foo4"
2) "foo8"
192.168.1.100:7001> get foo5
-> Redirected to slot [13555] located at 192.168.1.100:7002
"bar"
192.168.1.100:7002> keys *
1) "foo5"
2) "foo1"
3) "foo10"
4) "foo9"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 相關推薦

    redis叢集(Redis Cluster)原理應用

    全面剖析Redis Cluster原理和應用 1.Redis Cluster總覽 1.1 設計原則和初衷 在官方文件Cluster Spec中,作者詳細介紹了Redis叢集為什麼要設計成現在的樣子。最核心的目標有三個: 效能:這

    全面剖析Redis Cluster原理應用

            Redis3以上版本叢集方式,使用Ruby解本命令完成叢集、主從配置。前段時間配置redis主從時在配置哨兵模式時卡死了,主要是用YUM安裝的redis導致sentinel.conf配置失敗。現在使用Redis Cluster可以完美解決問題了,並且支援Jed

    [redis]redis五種資料型別應用場景

    一、String(字串)字串型別是redis最基礎的資料結構,首先鍵是字串型別,而且其他幾種結構都是在字串型別基礎上構建的,所以字串型別能為其他四種資料結構的學習尊定基礎。字串型別實際上可以是字串(簡單的字串、複雜的字串(xml、json)、數字(整數、浮點數)、二進位制(圖片、音訊、視訊)),但最大不能超過

    redis總結(一)--cap原理base

    1cap原理 1.1來自http://www.ruanyifeng.com/blog/2018/07/cap.html的解釋    1.1.1先看 Partition tolerance,中文叫做"分割槽容錯"。 大多數分散式系統都分佈在多個子網路。每個子網路就叫做一

    Redis叢集配置與原理

    叢集原理: 其實它的原理不是三兩句話能說明白的,redis 3.0 版本之前是不支援叢集的,官方 推薦最大的節點數量為 1000,至少需 要 3(Master)+3(Slave)才能建立叢集,是無中心的分散式儲存架構,可以在多個節點之間進行資料共享,解決了 Redis 高可 用、可

    Redis叢集Redis-cluster搭建及測試

    一、Redis叢集部署 三臺物理機:172.20.0.17、172.20.0.18、172.20.0.19 二、安裝Redis 下載安裝redis壓縮包 解壓壓縮包,進入redis-5.0.2資料夾,執行命令./make install安裝redis mv redis-5.0.2 /usr/loca

    redis叢集節點的新增刪除

    前面的文章已經搭建好了redis三主三從的叢集模式,本文將介紹演示向叢集中新增節點 根據新新增節點的種類, 我們需要用兩種方法來將新節點新增到叢集裡面: 如果要新增的新節點是一個主節點, 那麼我們需要建立一個空節點(empty node), 然後將某些雜湊桶移

    5,redis叢集在專案當中的應用

    前面我們從資料結構開始一路走來,已經比較全面的認識了redis。這篇文章開始分享redis在我們業務當中的使用。 開始分享之前我先提兩個我聽到的問題: 1、哨兵模式下,我們的業務端應該連線到哪個redis伺服器,既我們應該配置哪些資訊? 我先吧jedis提供的J

    玩轉Redis叢集Cluster

    前面我們介紹了國人自己開發的Redis叢集方案——Codis,Codis友好的管理介面以及強大的自動平衡槽位的功能深受廣大開發者的喜愛。今天我們一起來聊一聊Redis作者自己提供的叢集方案——Cluster。希望讀完這篇文章,你能夠充分了解Codis和Cluster各自的優缺點,面對不同的應用場景可以從容的做

    redis叢集環境的搭建錯誤分析

    解決方法: 1)、將需要新增的節點下aof、rdb等本地備份檔案刪除; 2)、同時將新Node的叢集配置檔案刪除,即:刪除你redis.conf裡面cluster-config-file所在的檔案; 3)、再次新增新節點如果還是報錯,則登入新Node,./redis-cli–h x –p對資料庫進行

    在windows上搭建redis叢集(redis-cluster)

    一 所需軟體:Redis、Ruby語言執行環境、Redis的Ruby驅動redis-xxxx.gem、建立Redis叢集的工具redis-trib.rb 二 安裝配置redis  叢集規劃有三個節點的叢集,每個節點有一主一備。需要6臺虛擬機器。 把 redis 解壓後,再

    搭建 redis 叢集 (redis-cluster)

    一 所需軟體:Redis、Ruby語言執行環境、Redis的Ruby驅動redis-xxxx.gem、建立Redis叢集的工具redis-trib.rb二 安裝配置redis 叢集規劃有三個節點的叢集,每個節點有一主一備。需要6臺虛擬機器。把 redis 解壓後,再複製出 5

    Redis學習筆記(五)jedis(JedisCluster)操作Redis叢集 redis-cluster

    redis系列文章目錄 版本說明 jedis2.9.0 redis3.2.5 參考資料:redis命令參考。 不過這個稍微有一點點老 java(JedisCluster)操作redis叢集 這裡只是幾個簡單的demo,直接

    redis叢集redis-cluster

    cluster addslots <slot> [slot ...] :將一個或多個槽( slot)指派( assign)給當前節點 cluster delslots <slot> [slot ...] :移除一個或多個槽對當前節點的指派 cluster flushslots :移除

    redis叢集(Sharding)線上擴容(Pre-Sharding)

    redis叢集分為服務端叢集和客戶端分片,redis3.0以上版本實現了叢集機制,即服務端叢集,3.0以下使用客戶端分片(Sharding)。redis3.0服務端叢集使用雜湊槽,計算key的CRC16結果再模16834。3.0以下版本採用Key的一致性hash演算法來區

    Redis叢集的配置檔案程式碼

    Redis叢集的配置 java程式碼 public class RedisService { // 登入校驗資訊的key public static final String DPM_LOGIN_LOGININFO_KEY = "DPM_LOGIN_LOGININFO_

    redis長連線的原理示例

    1.長連線的概念理解 長連線其實就是建立了一次連線 然後中間redis的命令都能一直使用,每次使用都不需要重新建立一個連線,這樣可以減少建立redis連線時間。 redis的長連線的

    redis叢集Cluster方式配置以及spring的整合

    Windows 配置Reids叢集 Redis Cluster 1. 下載安裝Redis Redis官方不支援Windows,但是Microsoft Open Tech group在 GitHub上開發了一個Win64的版本,下載地址為: https://github

    Windows 配置Redis叢集 Redis Cluster

    Windows 配置Reids叢集 Redis Cluster 1. 下載安裝Redis Redis官方不支援Windows,但是Microsoft Open Tech group在 GitHub上開發了一個Win64的版本,下載地址為: https:

    nginx+tomcat+redis叢集實現負載均衡session同步的步驟問題處理方法

    最近在研究nginx+tomcat的負載均衡功能, 因為需要實現failover時使用者無感知的效果,所以我考慮使用tomcat的session同步方式來實現。網上能查到的東西我就直接貼連結了,我把搭建這套系統的過程,與遇到的坑的處理方式說明一下。 我使用的系