1.爲何使用redis?php
redis是一種典型的no-sql 即非關係數據庫 像python的字典同樣 存儲key-value鍵值對 工做在memory中java
因此很適合用來充當整個互聯網架構中各級之間的cache 好比lvs的4層轉發層 nginx的7層代理層node
尤爲是lnmp架構應用層如php-fpm或者是Tomcat到mysql之間 作一個cache 以減輕db的壓力python
由於有至關一部分的數據 只是簡單的key-value對應關係,並且在實際的業務中經常在短期內迅速變更 mysql
若是用關係數據庫mysql之類存儲 會大大增長對db的訪問 致使db的負擔很重 由於全部的require中的大部分最後都要匯聚到dbnginx
因此若是想要業務穩定 那麼解決db的壓力 就是關鍵 因此如今大部分的解決方案就是在db層之上的各級使用多級的no-sql redis
像memcache redis 等 來爲db提供緩衝 算法
2.爲何使用redis-cluster?sql
爲了在大流量訪問下提供穩定的業務,集羣化是存儲的必然形態數據庫
將來的發展趨勢確定是雲計算和大數據的緊密結合 只有分佈式架構能知足要求
若是沒有集羣化 何來的分佈式?
3.順帶一提總結一波今天的redis原理之數據持久化
雖然redis這種no-sql通常都是做爲cache來服務 可是若是徹底沒有數據可持久化的方法 那麼顯得有些單薄
就像memcache 因爲這種no-sql是工做在memory的 那麼因爲memory的實體是ram
因此若是重啓或者宕機 memory中的數據就全沒了 數據的一致性的不到保障
可是 redis不一樣 redis有相對的數據持久化的方案 由兩種方式構成 aof & rdb
aof就像關係數據庫中的binlog同樣 把每一次寫操做以追加的形式記錄在其中以文件的形式刷到磁盤裏
而且可使用不一樣的fsync策略 無fsync,每秒fsync,每次寫的時候fsync.
使用默認的每秒fsync策略,Redis的性能依然很好(fsync是由後臺線程進行處理的,主線程會盡力處理客戶端請求)
一旦出現故障,最多丟失1秒的數據.
可是缺點也隨之而來 那就是aof文件的大小會隨着時間線性增加 一段時間以後 就會變得很大
若是要在一端以AOF的形式來恢復數據 那麼因爲AOF文件的巨大致積 可能會讓進程如同假死同樣 十分的慢
rdb則是一種快照機制
redis工做在內存中 rdb就是每隔一段時間 對內存中的數據作一次快照 保存在rdb文件中
並且redis的主從同步能夠實現異步 也是因爲rdb的機制 他在作快照時會fork出一個子進程 由子進程來作快照
父進程徹底處理請求 絕不影響 很適合數據的備份
可是問題是 若是數據量很大的話 rdb它要保存一個完整的數據集 是一個大的工做 若是時間間隔設置的過短
那麼嚴重影響redis的性能 可是按照常規設置的話 如5分鐘一次 那麼若是宕機或者重啓 就會基於上次作rdb的時間
從而丟失分鐘級的數據
point:在redis4.0的新特性中 採用了aof-rdb的混合方案來保障數據的持久性 可是官方的說法是還不成熟
是一個長期的工做 因此有待觀察吧
4.redis集羣實現方案:
關於redis的集羣化方案 目前有三種
(1)Twitter開發的twemproxy
(2)豌豆莢開發的codis
(3)redis官方的redis-cluster
簡介:twemproxy架構簡單 就是用proxy對後端redis server進行代理 可是因爲代理層的消耗性能很低 並且一般涉及多個key的操做都是不支持的 並且自己不支持動態擴容和透明的數據遷移 並且也失去維護 Twitter內部已經不使用了
redis-cluster是三個裏性能最強大的 由於他使用去中心化的思想 使用hash slot方式 將16348個hash slot 覆蓋到全部節點上 對於存儲的每一個key值 使用CRC16(KEY)&16348=slot 獲得他對應的hash slot 並在訪問key時就去找他的hash slot在哪個節點上 而後由當前訪問節點從實際被分配了這個hash slot的節點去取數據 節點之間使用輕量協議通訊 減小帶寬佔用 性能很高 自動實現負載均衡與高可用 自動實現failover 而且支持動態擴展 官方已經玩到能夠1000個節點 實現的複雜度低 總之我的比較喜歡這個架構 由於他的去中心化思想免去了proxy的消耗 是全新的思路
可是它也有一些不足 例如官方沒有提供圖形化管理工具 運維體驗差 全手工數據遷移 而且本身對本身自己的redis命令支持也不徹底等 可是這些問題 我以爲不能掩蓋他關鍵的新思想所帶來的的優點 隨着官方的推動 這些問題應該都能在必定時間內獲得解決 那麼這時候去中心化思想帶來的高性能就會表現出他巨大的優點
codis使用的也是proxy思路 可是作的比較好 是這兩種之間的一箇中間級 並且支持redis命令是最多的 有圖形化GUI管理和監控工具 運維友好 這個過段時間會詳細另外寫出來原理 工做機制和搭建實現
Redis集羣
基本介紹
Redis
集羣是一個能夠在多個 Redis
節點之間進行數據共享的設施installation
。
Redis
集羣不支持那些須要同時處理多個鍵的 Redis
命令, 由於執行這些命令須要在多個 Redis
節點之間移動數據, 而且在高負載的狀況下, 這些命令將下降Redis
集羣的性能, 並致使不可預測的行爲。
Redis
集羣經過分區partition
來提供必定程度的可用性availability
: 即便集羣中有一部分節點失效或者沒法進行通信, 集羣也能夠繼續處理命令請求。
Redis
集羣提供瞭如下兩個好處:
- 將數據自動切分
split
到多個節點的能力。
- 當集羣中的一部分節點失效或者沒法進行通信時, 仍然能夠繼續處理命令請求的能力。
集羣原理
redis-cluster架構圖

-
全部的redis
節點彼此互聯(PING
-PONG
機制),內部使用二進制協議優化傳輸速度和帶寬。
-
節點的fail
是經過集羣中超過半數的節點檢測失效時才生效。
-
客戶端與redis
節點直連,不須要中間proxy
層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。
-
redis-cluster
把全部的物理節點映射到[0-16383
]slot
上,cluster
負責維護node
<->slot
<->value
Redis
集羣中內置了 16384
個哈希槽,當須要在 Redis
集羣中放置一個 key-value
時,redis
先對key
使用 crc16
算法算出一個結果,而後把結果對 16384
求餘數,這樣每一個 key
都會對應一個編號在 0-16383
之間的哈希槽,redis
會根據節點數量大體均等的將哈希槽映射到不一樣的節點
redis-cluster投票:容錯

-
投票過程是集羣中全部master
參與,若是半數以上master
節點與master
節點通訊超時(cluster-node-timeout
),認爲當前master
節點掛掉.
-
何時整個集羣不可用(cluster_state:fail
)?
- 若是集羣任意
master
掛掉,且當前master
沒有slave
.集羣進入fail
狀態,也能夠理解成集羣的slot
映射[0-16383
]不完整時進入fail狀態.
redis-3.0.0.rc1
加入cluster-require-full-coverage
參數,默認關閉,打開集羣兼容部分失敗.
- 若是集羣超過半數以上
master
掛掉,不管是否有slave
,集羣進入fail
狀態.
Redis集羣搭建
Redis
單機版的安裝見博客《redis入門——安裝篇》,安裝好以後,將redis
複製成6
份,注意要將.rdb
和.aof
後綴的文件刪除,若是有的話。
Ruby環境
使用
-
-
安裝ruby環境。
網上下載redis-3.0.0.gem
,執行gem install redis-3.0.0.gem
安裝。
redis配置文件修改
如今已經準備好了,6
份乾淨的redis
,以下所示
-
[root
@localhost redis-cluster]
-
/usr/
local/redis/redis-cluster
-
[root
@localhost redis-cluster]
-
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:17 redis1
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:25 redis2
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:25 redis3
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:25 redis4
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:25 redis5
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:25 redis6
-
-rwxr-xr-
x 1 root root 48141 Nov 2 00:16 redis-trib.rb
-
[root
@localhost redis-cluster]
PS:注意,這裏已經將redis
源文件src
目錄下的redis-trib.rb
文件拷貝過來了。
redis-trib.rb
這個文件是redis
集羣的管理文件,ruby
腳本。
將六個節點的redis.conf
配置文件按照以下進行修改
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
PS:端口號若是是同一臺主機的話,必須不一樣。不一樣主機能夠相同。
PS:我這裏是使用一臺主機,因此我將六個節點的端口號修改成7001
-7006
編寫集羣啓動腳本和中止腳本
啓動腳本start-all.sh
-
-
./redis-server redis.conf
-
-
-
./redis-server redis.conf
-
-
-
./redis-server redis.conf
-
-
-
./redis-server redis.conf
-
-
-
./redis-server redis.conf
-
-
-
./redis-server redis.conf
-
中止腳本stop-all.sh
-
./redis1/redis-cli -p 7001 shutdown
-
./redis1/redis-cli -p 7002 shutdown
-
./redis1/redis-cli -p 7003 shutdown
-
./redis1/redis-cli -p 7004 shutdown
-
./redis1/redis-cli -p 7005 shutdown
-
./redis1/redis-cli -p 7006 shutdown
PS:兩個腳本都放在以下所屬目錄
-
[root
@localhost redis-cluster]
-
/usr/
local/redis/redis-cluster
-
[root
@localhost redis-cluster]
-
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:52 redis1
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:51 redis2
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:53 redis3
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:53 redis4
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:53 redis5
-
drwxr-xr-
x 2 root root 4096 Nov 2 00:53 redis6
-
-rwxr-xr-
x 1 root root 48141 Nov 2 00:16 redis-trib.rb
-
-rw-r--r--
1 root root 252 Nov 2 00:55 start-all.sh
-
-rw-r--r--
1 root root 216 Nov 2 00:57 stop-all.sh
-
[root
@localhost redis-cluster]
修改權限
[root@localhost redis-cluster]# chmod -u+x start-all.sh stop-all.sh
啓動節點
-
[root
@localhost redis-cluster]# ./start-all.sh
-
[root
@localhost redis-cluster]# ps aux | grep redis
-
root
2924 0.8 0.1 33932 2048 ? Ssl Nov01 3:53 ./redis-server *:6379 [cluster]
-
root
11924 0.0 0.1 33936 1948 ? Ssl 01:01 0:00 ./redis-server *:7001 [cluster]
-
root
11928 0.0 0.1 33936 1952 ? Ssl 01:01 0:00 ./redis-server *:7002 [cluster]
-
root
11932 0.0 0.1 33936 1948 ? Ssl 01:01 0:00 ./redis-server *:7003 [cluster]
-
root
11936 0.0 0.1 33936 1952 ? Ssl 01:01 0:00 ./redis-server *:7004 [cluster]
-
root
11940 0.0 0.1 33936 1952 ? Ssl 01:01 0:00 ./redis-server *:7005 [cluster]
-
root
11944 0.0 0.1 33936 1948 ? Ssl 01:01 0:00 ./redis-server *:7006 [cluster]
-
root
11948 0.0 0.0 4360 748 pts/2 S+ 01:01 0:00 grep redis
-
[root
@localhost redis-cluster]#
執行建立集羣命令
-
[root
@localhost redis-cluster]
-
/usr/
local/redis/redis-cluster
-
[root
@localhost redis-cluster]
成功啓動信息
-
-
Connecting
to node 192.168.37.131:7001: OK
-
Connecting
to node 192.168.37.131:7002: OK
-
Connecting
to node 192.168.37.131:7003: OK
-
Connecting
to node 192.168.37.131:7004: OK
-
Connecting
to node 192.168.37.131:7005: OK
-
Connecting
to node 192.168.37.131:7006: OK
-
>>> Performing hash slots allocation
on 6 nodes...
-
-
-
-
-
Adding replica
192.168.37.131:7004 to 192.168.37.131:7001
-
Adding replica
192.168.37.131:7005 to 192.168.37.131:7002
-
Adding replica
192.168.37.131:7006 to 192.168.37.131:7003
-
M:
8b153503b52f83634e04b0077f32ef629ad91ee6 192.168.37.131:7001
-
slots:
0-5460 (5461 slots) master
-
M: f89799066dd8ecaaa1430559be4ce9c8c87055d8
192.168.37.131:7002
-
slots:
5461-10922 (5462 slots) master
-
M:
53d698ad56b09f89cfef34850213e2d0a44154dd 192.168.37.131:7003
-
slots:
10923-16383 (5461 slots) master
-
S: e73204399d08c14def1f71d0c5377cbc757dc4b8
192.168.37.131:7004
-
replicates
8b153503b52f83634e04b0077f32ef629ad91ee6
-
S:
1d5dcc8d1ccb6bce55efc3e3aadc690dc77808d8 192.168.37.131:7005
-
replicates f89799066dd8ecaaa1430559be4ce9c8c87055d8
-
S: e9458233cb85bd897ff694003e6d8a834eba2b44
192.168.37.131:7006
-
replicates
53d698ad56b09f89cfef34850213e2d0a44154dd
-
Can I
set the above configuration? (type
-
-
[root@localhost redis-cluster]
# ./redis-trib.rb create --replicas 1 192.168.37.131:7001 192.168.37.131:7002 192.168.37.131:7003 192.168.37.131:7004 192.168.37.131:7005 192.168.37.131:7006
-
-
Connecting
to node 192.168.37.131:7001: OK
-
Connecting
to node 192.168.37.131:7002: OK
-
Connecting
to node 192.168.37.131:7003: OK
-
Connecting
to node 192.168.37.131:7004: OK
-
Connecting
to node 192.168.37.131:7005: OK
-
Connecting
to node 192.168.37.131:7006: OK
-
>>> Performing hash slots allocation
on 6 nodes...
-
-
-
-
-
Adding replica
192.168.37.131:7004 to 192.168.37.131:7001
-
Adding replica
192.168.37.131:7005 to 192.168.37.131:7002
-
Adding replica
192.168.37.131:7006 to 192.168.37.131:7003
-
M:
8b153503b52f83634e04b0077f32ef629ad91ee6 192.168.37.131:7001
-
slots:
0-5460 (5461 slots) master
-
M: f89799066dd8ecaaa1430559be4ce9c8c87055d8
192.168.37.131:7002
-
slots:
5461-10922 (5462 slots) master
-
M:
53d698ad56b09f89cfef34850213e2d0a44154dd 192.168.37.131:7003
-
slots:
10923-16383 (5461 slots) master
-
S: e73204399d08c14def1f71d0c5377cbc757dc4b8
192.168.37.131:7004
-
replicates
8b153503b52f83634e04b0077f32ef629ad91ee6
-
S:
1d5dcc8d1ccb6bce55efc3e3aadc690dc77808d8 192.168.37.131:7005
-
replicates f89799066dd8ecaaa1430559be4ce9c8c87055d8
-
S: e9458233cb85bd897ff694003e6d8a834eba2b44
192.168.37.131:7006
-
replicates
53d698ad56b09f89cfef34850213e2d0a44154dd
-
Can I
set the above configuration? (type
-
>>> 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.37.131:7001)
-
M:
8b153503b52f83634e04b0077f32ef629ad91ee6 192.168.37.131:7001
-
slots:
0-5460 (5461 slots) master
-
M: f89799066dd8ecaaa1430559be4ce9c8c87055d8
192.168.37.131:7002
-
slots:
5461-10922 (5462 slots) master
-
M:
53d698ad56b09f89cfef34850213e2d0a44154dd 192.168.37.131:7003
-
slots:
10923-16383 (5461 slots) master
-
M: e73204399d08c14def1f71d0c5377cbc757dc4b8
192.168.37.131:7004
-
-
replicates
8b153503b52f83634e04b0077f32ef629ad91ee6
-
M:
1d5dcc8d1ccb6bce55efc3e3aadc690dc77808d8 192.168.37.131:7005
-
-
replicates f89799066dd8ecaaa1430559be4ce9c8c87055d8
-
M: e9458233cb85bd897ff694003e6d8a834eba2b44
192.168.37.131:7006
-
-
replicates
53d698ad56b09f89cfef34850213e2d0a44154dd
-
[OK] All nodes agree about slots configuration.
-
>>> Check
for open slots...
-
>>> Check slots coverage...
-
[OK] All
16384 slots covered.
-
[root@localhost redis-cluster]
#
異常
-
-
Connecting to node 192.168.37.131:7001: OK
-
[ERR] Node 192.168.37.131:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解決方法是刪除生成的配置文件nodes.conf
,若是不行則說明如今建立的結點包括了舊集羣的結點信息,須要刪除redis
的持久化文件後再重啓redis
,好比:appendonly.aof
、dump.rdb
首先,使用stop-all.sh
中止服務
-
[root
@localhost redis-cluster]
-
[root
@localhost redis-cluster]
-
root
2924 0.8 0.1 33932 2048 ? Ssl Nov01 3:54 ./redis-server *:6379 [cluster]
-
root
11969 0.0 0.0 4360 744 pts/2 S+ 01:10 0:00 grep redis
-
[root
@localhost redis-cluster]
而後每一個節點中的appendonly.aof
、dump.rdb
、nodes.conf
。
-
[root
@localhost redis-cluster]
-
[root
@localhost redis-cluster]
-
[root
@localhost redis-cluster]
而後使用腳本start-all.sh
啓動,再啓動集羣管理服務。
-
[root
@localhost redis-cluster]
-
[root
@localhost redis-cluster]
-
root
2924 0.8 0.1 33932 2048 ? Ssl Nov01 3:54 ./redis-server *:6379 [cluster]
-
root
11980 0.0 0.1 33936 1952 ? Ssl 01:12 0:00 ./redis-server *:7001 [cluster]
-
root
11982 0.0 0.1 33936 1952 ? Ssl 01:12 0:00 ./redis-server *:7002 [cluster]
-
root
11984 0.0 0.1 33936 1952 ? Ssl 01:12 0:00 ./redis-server *:7003 [cluster]
-
root
11986 0.0 0.1 33936 1952 ? Ssl 01:12 0:00 ./redis-server *:7004 [cluster]
-
root
11988 0.0 0.1 33936 1948 ? Ssl 01:12 0:00 ./redis-server *:7005 [cluster]
-
root
11990 0.0 0.1 33936 1948 ? Ssl 01:12 0:00 ./redis-server *:7006 [cluster]
-
root
12004 0.0 0.0 4360 748 pts/2 S+ 01:12 0:00 grep redis
-
[root
@localhost redis-cluster]
-
[root
@localhost redis-cluster]
Redis集羣節點的操做
查詢集羣信息
集羣建立成功登錄任意redis
結點查詢集羣中的節點狀況。
客戶端以集羣方式登錄:
-
[root
@localhost redis-cluster]
-
說明:
./redis1/redis-cli -c -h 192.168.37.131 -p 7001
,其中-c
表示以集羣方式鏈接redis
,-h
指定ip
地址,-p
指定端口號
cluster nodes
查詢集羣結點信息
-
192
.168.37.131:7001> cluster nodes
-
8
e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003 master - 0 1478085160899 3 connected 10923-16383
-
80
de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004 master - 0 1478085156858 8 connected 0-5460
-
652
caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005 slave 3adba62fdcc331ce231ca580cd2c8701e047bc6d 0 1478085158876 9 connected
-
1
cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001 myself,slave 80de7003738f74134a3403fc939fed253b7774f2 0 0 1 connected
-
3
adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002 master - 0 1478085159889 9 connected 5461-10922
-
cf23ca6d78cba3d3924065e1f7a394f6c51d4b28 192.168.37.131:7006 slave 8e1186475f87c928e8a146d3804d9a2697246ad0 0 1478085157867 6 connected
-
cluster info
查詢集羣狀態信息
-
192
.168.37.131:7001> cluster info
-
-
cluster_slots_assigned:16384
-
-
-
-
-
-
-
-
cluster_stats_messages_sent:12727
-
cluster_stats_messages_received:10820
-
添加主節點
集羣建立成功後能夠向集羣中添加節點,下面是添加一個master
主節點。
首先,準備一個乾淨的redis
節點。按上面集羣版修改redis
配置文件。開啓該redis
節點。
查看redis
進程
-
[root
@localhost redis-cluster]# !ps
-
-
root
2924 0.6 0.1 33932 1800 ? Ssl Nov01 4:08 ./redis-server *:6379 [cluster]
-
root
11980 0.0 0.2 33936 2216 ? Ssl 01:12 0:09 ./redis-server *:7001 [cluster]
-
root
11982 0.0 0.2 33936 2244 ? Ssl 01:12 0:09 ./redis-server *:7002 [cluster]
-
root
11984 0.0 0.2 33936 2220 ? Ssl 01:12 0:09 ./redis-server *:7003 [cluster]
-
root
11986 0.0 0.2 33936 2216 ? Ssl 01:12 0:09 ./redis-server *:7004 [cluster]
-
root
11988 0.0 0.2 33936 2228 ? Ssl 01:12 0:09 ./redis-server *:7005 [cluster]
-
root
11990 0.0 0.2 33936 2212 ? Ssl 01:12 0:09 ./redis-server *:7006 [cluster]
-
root
13913 0.0 0.1 33936 1952 ? Ssl 04:21 0:00 ./redis7/redis-server *:7007 [cluster]
-
root
13917 0.0 0.0 4360 728 pts/3 S+ 04:21 0:00 grep redis
-
[root
@localhost redis-cluster]#
執行下邊命令:
-
[root@localhost redis-cluster]
# ./redis-trib.rb add-node 192.168.37.131:7007 192.168.37.131:7001
-
>>> Adding node
192.168.37.131:7007 to cluster 192.168.37.131:7001
-
Connecting
to node 192.168.37.131:7001: OK
-
Connecting
to node 192.168.37.131:7003: OK
-
Connecting
to node 192.168.37.131:7004: OK
-
Connecting
to node 192.168.37.131:7005: OK
-
Connecting
to node 192.168.37.131:7002: OK
-
Connecting
to node 192.168.37.131:7006: OK
-
>>> Performing Cluster Check (
using node 192.168.37.131:7001)
-
S:
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001
-
-
replicates
80de7003738f74134a3403fc939fed253b7774f2
-
M:
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003
-
slots:
10923-16383 (5461 slots) master
-
-
M:
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004
-
slots:
0-5460 (5461 slots) master
-
-
S:
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005
-
-
replicates
3adba62fdcc331ce231ca580cd2c8701e047bc6d
-
M:
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002
-
slots:
5461-10922 (5462 slots) master
-
-
S: cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006
-
-
replicates
8e1186475f87c928e8a146d3804d9a2697246ad0
-
[OK] All nodes agree about slots configuration.
-
>>> Check
for open slots...
-
>>> Check slots coverage...
-
[OK] All
16384 slots covered.
-
Connecting
to node 192.168.37.131:7007: OK
-
>>> Send CLUSTER MEET
to node 192.168.37.131:7007 to make it join the cluster.
-
[OK]
New node added correctly.
-
[root@localhost redis-cluster]
#
查看集羣結點發現7007
已添加到集羣中:
-
[root@localhost redis-cluster]
-
192.168.37.131:7001> cluster nodes
-
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003 master - 0 1478085870038 3 connected 10923-16383
-
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004 master - 0 1478085868020 8 connected 0-5460
-
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005 slave 3adba62fdcc331ce231ca580cd2c8701e047bc6d 0 1478085874075 9 connected
-
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001 myself,slave 80de7003738f74134a3403fc939fed253b7774f2 0 0 1 connected
-
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002 master - 0 1478085873064 9 connected 5461-10922
-
cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006 slave 8e1186475f87c928e8a146d3804d9a2697246ad0 0 1478085875086 6 connected
-
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7007 master - 0 1478085872056 0 connected
-
hash槽從新分配
添加完主節點須要對主節點進行hash
槽分配這樣該主節才能夠存儲數據。
redis
集羣有16384
個槽,集羣中的每一個master
結點分配一些槽,經過查看集羣結點能夠看到槽佔用狀況。
給剛添加的7007
結點分配槽:
第一步:鏈接上集羣
./redis-trib.rb reshard 192.168.37.131:7001
(鏈接集羣中任意一個可用結點都行)
-
[root@localhost redis-cluster]
# ./redis-trib.rb reshard 192.168.37.131:7001
-
Connecting
to node 192.168.37.131:7001: OK
-
Connecting
to node 192.168.37.131:7003: OK
-
Connecting
to node 192.168.37.131:7004: OK
-
Connecting
to node 192.168.37.131:7005: OK
-
Connecting
to node 192.168.37.131:7002: OK
-
Connecting
to node 192.168.37.131:7006: OK
-
Connecting
to node 192.168.37.131:7007: OK
-
>>> Performing Cluster Check (
using node 192.168.37.131:7001)
-
S:
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001
-
-
replicates
80de7003738f74134a3403fc939fed253b7774f2
-
M:
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003
-
slots:
10923-16383 (5461 slots) master
-
-
M:
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004
-
slots:
0-5460 (5461 slots) master
-
-
S:
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005
-
-
replicates
3adba62fdcc331ce231ca580cd2c8701e047bc6d
-
M:
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002
-
slots:
5461-10922 (5462 slots) master
-
-
S: cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006
-
-
replicates
8e1186475f87c928e8a146d3804d9a2697246ad0
-
M:
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7007
-
-
-
[OK] All nodes agree about slots configuration.
-
>>> Check
for open slots...
-
>>> Check slots coverage...
-
[OK] All
16384 slots covered.
-
How many slots
do you want to move (from 1 to 16384)?
第二步:輸入要分配的槽數量
-
How many slots
do you want to move (from 1 to 16384)? 1000
-
What
is the receiving node ID?
輸入1000
表示要分配1000
個槽
第三步:輸入接收槽的結點id
這裏準備給7007
分配槽,經過cluster nodes
查看7007
結點id
爲5d6c61ecff23bff3b0fb01a86c66d882f2d402a0
輸入:5d6c61ecff23bff3b0fb01a86c66d882f2d402a0
-
What
is the receiving node ID? 5d6c61ecff23bff3b0fb01a86c66d882f2d402a0
-
Please enter all
the source node IDs.
-
Type 'all' to use all the nodes as source nodes for the hash slots.
-
Type 'done' once you entered all the source nodes IDs.
-
第四步:輸入源結點id
輸入源結點id
,槽將從源結點中拿,分配後的槽在源結點中就不存在了。
輸入all
表示從全部源結點中獲取槽。
輸入done
取消分配。
這裏輸入all
-
-
-
-
-
Moving slot
11253 from 8e1186475f87c928e8a146d3804d9a2697246ad0
-
Moving slot
11254 from 8e1186475f87c928e8a146d3804d9a2697246ad0
-
Moving slot
11255 from 8e1186475f87c928e8a146d3804d9a2697246ad0
-
Do you want to proceed with the proposed reshard plan (yes/no)?
第五步:輸入yes
開始移動槽到目標結點id
-
-
-
Moving slot 11253 from 192.168.37.131:7003 to 192.168.37.131:7007:
-
Moving slot 11254 from 192.168.37.131:7003 to 192.168.37.131:7007:
-
Moving slot 11255 from 192.168.37.131:7003 to 192.168.37.131:7007:
-
[root@localhost redis-cluster]#
第六步:查看結點信息
-
[root@localhost redis-cluster]
-
192.168.37.131:7001> cluster nodes
-
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003 master - 0 1478086754466 3 connected 11256-16383
-
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004 master - 0 1478086758509 8 connected 333-5460
-
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005 slave 3adba62fdcc331ce231ca580cd2c8701e047bc6d 0 1478086756490 9 connected
-
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001 myself,slave 80de7003738f74134a3403fc939fed253b7774f2 0 0 1 connected
-
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002 master - 0 1478086757500 9 connected 5795-10922
-
cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006 slave 8e1186475f87c928e8a146d3804d9a2697246ad0 0 1478086755477 6 connected
-
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7007 master - 0 1478086759518 10 connected 0-332 5461-5794 10923-11255
-
查看結點信息,能夠發現7007
結點已經從三個主節點中獲取了slot
。
添加從節點
集羣建立成功後能夠向集羣中添加節點,下面是添加一個slave
從節點。
添加7008
從結點,將7008
做爲7007
的從結點。
首先,準備一個乾淨的redis
節點。按上面集羣版修改redis
配置文件。開啓該redis
節點。
查看redis
進程
-
[root
@localhost redis-cluster]# ps aux | grep redis
-
root
2924 0.5 0.1 33932 1800 ? Ssl Nov01 4:12 ./redis-server *:6379 [cluster]
-
root
11980 0.0 0.2 33936 2308 ? Ssl 01:12 0:13 ./redis-server *:7001 [cluster]
-
root
11982 0.0 0.2 33936 2288 ? Ssl 01:12 0:13 ./redis-server *:7002 [cluster]
-
root
11984 0.0 0.2 33936 2236 ? Ssl 01:12 0:13 ./redis-server *:7003 [cluster]
-
root
11986 0.0 0.2 33936 2288 ? Ssl 01:12 0:13 ./redis-server *:7004 [cluster]
-
root
11988 0.0 0.2 33936 2248 ? Ssl 01:12 0:13 ./redis-server *:7005 [cluster]
-
root
11990 0.0 0.2 33936 2244 ? Ssl 01:12 0:13 ./redis-server *:7006 [cluster]
-
root
13913 0.1 0.2 33936 2092 ? Ssl 04:21 0:04 ./redis7/redis-server *:7007 [cluster]
-
root
14000 0.1 0.1 33936 1948 ? Ssl 05:24 0:00 ./redis-server *:7008 [cluster]
-
root
14006 0.0 0.0 4360 732 pts/3 S+ 05:24 0:00 grep redis
-
[root
@localhost redis-cluster]#
命令格式爲:
./redis-trib.rb add-node --slave --master-id 主節點id 添加節點的ip和端口 集羣中已存在節點ip和端口
執行以下命令:
-
[root@localhost redis-cluster]
# ./redis-trib.rb add-node --slave --master-id 5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7008 192.168.37.131:7001
-
>>> Adding node
192.168.37.131:7008 to cluster 192.168.37.131:7001
-
Connecting
to node 192.168.37.131:7001: OK
-
Connecting
to node 192.168.37.131:7003: OK
-
Connecting
to node 192.168.37.131:7004: OK
-
Connecting
to node 192.168.37.131:7005: OK
-
Connecting
to node 192.168.37.131:7002: OK
-
Connecting
to node 192.168.37.131:7006: OK
-
Connecting
to node 192.168.37.131:7007: OK
-
>>> Performing Cluster Check (
using node 192.168.37.131:7001)
-
S:
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001
-
-
replicates
80de7003738f74134a3403fc939fed253b7774f2
-
M:
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003
-
slots:
11256-16383 (5128 slots) master
-
-
M:
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004
-
slots:
333-5460 (5128 slots) master
-
-
S:
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005
-
-
replicates
3adba62fdcc331ce231ca580cd2c8701e047bc6d
-
M:
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002
-
slots:
5795-10922 (5128 slots) master
-
-
S: cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006
-
-
replicates
8e1186475f87c928e8a146d3804d9a2697246ad0
-
M:
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7007
-
slots:
0-332,5461-5794,10923-11255 (1000 slots) master
-
-
[OK] All nodes agree about slots configuration.
-
>>> Check
for open slots...
-
>>> Check slots coverage...
-
[OK] All
16384 slots covered.
-
Connecting
to node 192.168.37.131:7008: OK
-
>>> Send CLUSTER MEET
to node 192.168.37.131:7008 to make it join the cluster.
-
Waiting
for the cluster to join.
-
>>> Configure node
as replica of 192.168.37.131:7007.
-
[OK]
New node added correctly.
-
[root@localhost redis-cluster]
#
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0
是7007
結點的id
,能夠經過cluster nodes
查看。
查看集羣中的結點,剛添加的7008
爲7007
的從節點:
-
[root@localhost redis-cluster]
-
8e1186475f87c928e8a146d3804d9a2697246ad0 192.168.37.131:7003 master - 0 1478089964769 3 connected 11256-16383
-
80de7003738f74134a3403fc939fed253b7774f2 192.168.37.131:7004 master - 0 1478089966584 8 connected 333-5460
-
652caf5daf7971135679951324eba7b50e99251a 192.168.37.131:7005 slave 3adba62fdcc331ce231ca580cd2c8701e047bc6d 0 1478089963748 9 connected
-
1cd6482fd7038d78ad556b52b0cb9e2590ad5598 192.168.37.131:7001 myself,slave 80de7003738f74134a3403fc939fed253b7774f2 0 0 1 connected
-
3adba62fdcc331ce231ca580cd2c8701e047bc6d 192.168.37.131:7002 master - 0 1478089966787 9 connected 5795-10922
-
cf23ca6d78cba3d3924065e1f7a394f6c51d4b28
192.168.37.131:7006 slave 8e1186475f87c928e8a146d3804d9a2697246ad0 0 1478089962729 6 connected
-
5c97e8eab019c40ea3df4925c7400fe7df1846bb 192.168.37.131:7008 slave 5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 0 1478089961713 10 connected
-
5d6c61ecff23bff3b0fb01a86c66d882f2d402a0 192.168.37.131:7007 master - 0 1478089965777 10 connected 0-332 5461-5794 10923-11255
-
刪除結點
./redis-trib.rb del-node 192.168.37.131:7007 5d6c61ecff23bff3b0fb01a86c66d882f2d402a0
刪除已經佔有hash
槽的結點會失敗,報錯以下:
[ERR] Node 192.168.37.131:7007 is not empty! Reshard data away and try again.
須要將該結點佔用的hash
槽分配出去,請參考《hash槽從新分配》這段內容。
客戶端對Redis集羣的使用方法
使用redis命令行客戶端鏈接
-
[root@localhost redis-cluster]
-
-
-> Redirected
to slot [15495] located at 192.168.37.131:7003
-
-
必定要加-c
參數,節點之間就能夠互相跳轉
使用jedis鏈接
-
package com.pc.jedis.test;
-
-
import java.util.HashSet;
-
-
-
import redis.clients.jedis.HostAndPort;
-
import redis.clients.jedis.JedisCluster;
-
-
-
-
-
-
-
-
-
public class JedisClusterTest {
-
public static void main(String[] args) {
-
-
Set<HostAndPort> nodes =
new HashSet<>();
-
nodes.add(
new HostAndPort("192.168.37.131", 7001));
-
nodes.add(
new HostAndPort("192.168.37.131", 7002));
-
nodes.add(
new HostAndPort("192.168.37.131", 7003));
-
nodes.add(
new HostAndPort("192.168.37.131", 7004));
-
nodes.add(
new HostAndPort("192.168.37.131", 7005));
-
nodes.add(
new HostAndPort("192.168.37.131", 7006))
-
-
JedisCluster jedisCluster =
new JedisCluster(nodes);
-
-
-
String key =
"jedisCluster";
-
String setResult = jedisCluster.set(key,
"hello redis!");
-
System.out.println(setResult);
-
-
String getResult = jedisCluster.get(key);
-
System.out.println(getResult);
-
-
-
-
-
——參考《Redis官方文檔》