redis集羣配置----

redis 採用 redis-3.2.4 版本。因爲redis .3.0.0版本之後纔有集羣,之前配置文件中沒有

兩臺虛擬機都是 CentOS ,一臺 CentOS6.5 (IP:192.168.31.245),一臺 CentOS7(IP:192.168.31.210) 。

安裝過程

1. 下載並解壓


 
cd /root/software
wget http://download.redis.io/releases/redis-3.2.4.tar.gz
tar -zxvf redis-3.2.4.tar.gz 

2. 編譯安裝

cd redis-3.2.4
make && make install

3. 將 redis-trib.rb 複製到 /usr/local/bin 目錄下

cd src
cp redis-trib.rb /usr/local/bin/  

4. 創建 Redis 節點

首先在 192.168.31.245 機器上 /root/software/redis-3.2.4 目錄下創建 redis_cluster 目錄;

mkdir redis_cluster  

在 redis_cluster 目錄下,創建名爲7000、7001、7002的目錄,並將 redis.conf 拷貝到這三個目錄中

mkdir 7000 7001 7002<br>cp redis.conf redis_cluster/7000
cp redis.conf redis_cluster/7001
cp redis.conf redis_cluster/7002  

分別修改這三個配置文件,修改如下內容

複製代碼
port  7000                                        //端口7000,7002,7003        
bind 本機ip                                       //默認ip爲127.0.0.1 需要改爲其他節點機器可訪問的ip 否則創建集羣時無法訪問對應的端口,無法創建集羣
daemonize    yes                               //redis後臺運行
pidfile  /var/run/redis_7000.pid          //pidfile文件對應7000,7001,7002
cluster-enabled  yes                           //開啓集羣  把註釋#去掉
cluster-config-file  nodes_7000.conf   //集羣的配置  配置文件首次啓動自動生成 7000,7001,7002
cluster-node-timeout  15000                //請求超時  默認15秒,可自行設置
appendonly  yes                           //aof日誌開啓  有需要就開啓,它會每次寫操作都記錄一條日誌 
複製代碼
  • 接着在另外一臺機器上(192.168.31.210),的操作重複以上三步,只是把目錄改爲7003、7004、7005,對應的配置文件也按照這個規則修改即可

5. 啓動各個節點

複製代碼
第一臺機器上執行
redis-server redis_cluster/7000/redis.conf
redis-server redis_cluster/7001/redis.conf
redis-server redis_cluster/7002/redis.conf
 
另外一臺機器上執行
redis-server redis_cluster/7003/redis.conf
redis-server redis_cluster/7004/redis.conf
redis-server redis_cluster/7005/redis.conf 
複製代碼

6. 檢查 redis 啓動情況

複製代碼
##一臺機器<br>ps -ef | grep redis
root      61020      1  0 02:14 ?        00:00:01 redis-server 127.0.0.1:7000 [cluster]    
root      61024      1  0 02:14 ?        00:00:01 redis-server 127.0.0.1:7001 [cluster]    
root      61029      1  0 02:14 ?        00:00:01 redis-server 127.0.0.1:7002 [cluster]    
 
netstat -tnlp | grep redis
tcp        0      0 127.0.0.1:17000             0.0.0.0:*                   LISTEN      61020/redis-server 
tcp        0      0 127.0.0.1:17001             0.0.0.0:*                   LISTEN      61024/redis-server 
tcp        0      0 127.0.0.1:17002             0.0.0.0:*                   LISTEN      61029/redis-server 
tcp        0      0 127.0.0.1:7000              0.0.0.0:*                   LISTEN      61020/redis-server 
tcp        0      0 127.0.0.1:7001              0.0.0.0:*                   LISTEN      61024/redis-server 
tcp        0      0 127.0.0.1:7002              0.0.0.0:*                   LISTEN      61029/redis-server
1
2
3
4
5
6
7
8
9
10
11
12
13
    
##另外一臺機器
ps -ef | grep redis
root       9957      1  0 02:32 ?        00:00:01 redis-server 127.0.0.1:7003 [cluster]
root       9964      1  0 02:32 ?        00:00:01 redis-server 127.0.0.1:7004 [cluster]
root       9971      1  0 02:32 ?        00:00:01 redis-server 127.0.0.1:7005 [cluster]
root      10065   4744  0 02:38 pts/0    00:00:00 grep --color=auto redis
netstat -tlnp | grep redis
tcp        0      0 127.0.0.1:17003         0.0.0.0:*               LISTEN      9957/redis-server 1
tcp        0      0 127.0.0.1:17004         0.0.0.0:*               LISTEN      9964/redis-server 1
tcp        0      0 127.0.0.1:17005         0.0.0.0:*               LISTEN      9971/redis-server 1
tcp        0      0 127.0.0.1:7003          0.0.0.0:*               LISTEN      9957/redis-server 1
tcp        0      0 127.0.0.1:7004          0.0.0.0:*               LISTEN      9964/redis-server 1
tcp        0      0 127.0.0.1:7005          0.0.0.0:*               LISTEN      9971/redis-server 1 
複製代碼

7.創建集羣

Redis 官方提供了 redis-trib.rb 這個工具,就在解壓目錄的 src 目錄中,第三步中已將它複製到 /usr/local/bin 目錄中,可以直接在命令行中使用了。使用下面這個命令即可完成安裝。

redis-trib.rb  create  --replicas  1  192.168.31.245:7000 192.168.31.245:7001  192.168.31.245:7002 192.168.31.210:7003  192.168.31.210:7004  192.168.31.210:7005

其中,前三個 ip:port 爲第一臺機器的節點,剩下三個爲第二臺機器。

等等,出錯了。這個工具是用 ruby 實現的,所以需要安裝 ruby。安裝命令如下:

yum -y install ruby ruby-devel rubygems rpm-build
 
然後執行命令:gem install redis
 
這裏可能無法安裝,因爲無法連接gem服務器:
[@zw_22_90 src]# gem install redis --version 3.0.0
ERROR: Could not find a valid gem 'redis' (= 3.0.0) in any repository
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)


需要手工下載並安裝:
wget https://rubygems.global.ssl.fastly.net/gems/redis-3.2.1.gem
gem install -l ./redis-3.2.1.gem


6.4 再次執行第步的命令,正常執行
 
redis-trib.rb  create  --replicas  1  192.168.31.245:7000 192.168.31.245:7001  192.168.31.245:7002 192.168.31.210:7003  192.168.31.210:7004  192.168.31.210:7005

8. 集羣驗證

在第一臺機器上連接集羣的7002端口的節點,在另外一臺連接7005節點,連接方式爲 redis-cli -h 192.168.31.245 -c -p 7002  ,加參數 -C 可連接到集羣,因爲上面 redis.conf 將 bind 改爲了ip地址,所以 -h 參數不可以省略。

在7005節點執行命令  set hello world ,執行結果如下:

然後在另外一臺7002端口,查看 key 爲 hello 的內容, get hello  ,執行結果如下:

說明集羣運作正常。

簡單說一下原理

redis cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說,集羣中的每個節點都是平等的關係,都是對等的,每個節點都保存各自的數據和整個集羣的狀態。每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集羣中的任意一個節點,就可以獲取到其他節點的數據。

Redis 集羣沒有並使用傳統的一致性哈希來分配數據,而是採用另外一種叫做哈希槽 (hash slot)的方式來分配的。redis cluster 默認分配了 16384 個slot,當我們set一個key 時,會用CRC16算法來取模得到所屬的slot,然後將這個key 分到哈希槽區間的節點上,具體算法就是:CRC16(key) % 16384。所以我們在測試的時候看到set 和 get 的時候,直接跳轉到了7000端口的節點。

Redis 集羣會把數據存在一個 master 節點,然後在這個 master 和其對應的salve 之間進行數據同步。當讀取數據時,也根據一致性哈希算法到對應的 master 節點獲取數據。只有當一個master 掛掉之後,纔會啓動一個對應的 salve 節點,充當 master 。

需要注意的是:必須要3個或以上的主節點,否則在創建集羣時會失敗,並且當存活的主節點數小於總節點數的一半時,整個集羣就無法提供服務了。

 

(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.

(2)節點的fail是通過集羣中超過半數的節點檢測失效時才生效.

(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集羣所有節點,連接集羣中任何一個可用節點即可。

(4)redis-cluster把所有的物理節點映射到[0-16383]slot上(哈希槽),cluster 負責維護

Redis 集羣中內置了 16384 個哈希槽,當需要在Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大致均等的將哈希槽映射到不同的節點。

 

Redis 集羣的鍵空間被分割爲16383個槽,集羣的最大節點數也是16484個。本篇文章主要來看一下redis集羣選取情況。

 

一、節點信息瞭解

 

爲了下面看節點主從選擇的信息,我們先來了解一下每個節點常用信息。

從上面列出的三行信息中,從左到右的各個域分別是:節點ID,Ip地址和端口號,標誌(是從節點還是主節點),最後發送PING的時間,最後接收PONG的時間,連接狀態(connected還是unConnected),節點負責處理的槽。

 

二.集羣的主從選擇

 

目前集羣中搭建了6個節點,三主三從,主節點爲6379、6380、6381,從節點是6381、6382、6384.

 

(1)啓動集羣,查看6個節點的服務狀態,全部爲啓動。

 

(2)查看集羣各個節點的主從狀態

三主三從,現在6379是其中一個主節點,其從節點是6382,以這兩個端口爲例,演示一下主從選舉過程。

 

(3)現在在6379中添加三個值,分別爲“school” "grage" "age"

 

(4)現在模擬將6379節點掛掉,按照redis集羣原理,會將6379節點的從節點選舉爲6382爲主節點。


 

(5)現在查看集羣運行狀況

可以看到6379節點掛掉之後,6379節點連接不上,現在6382節點變成了主節點。

 

(6) 並且可以從6382節點中得到和6379節點相同的數據內容。

 

(7)現在我們將6379節點重啓,查看6379是否會自動加入集羣,此時在集羣中充當的是M節點還是S節點。

查看進程,6379端口啓動成功。

 

(8)6379節點變爲了6382節點的從節點

如果redis集羣中,一主一從都宕機,則redis-cluster不可用,fail狀態

1、集羣是如何判斷是否有某個節點掛掉

  首先要說的是,每一個節點都存有這個集羣所有主節點以及從節點的信息。它們之間通過互相的ping-pong判斷是否節點可以連接上。如果有一半以上的節點去ping一個節點的時候沒有迴應,集羣就認爲這個節點宕機了,然後去連接它的備用節點。

 

2、集羣進入fail狀態的必要條件

A、某個主節點和所有從節點全部掛掉,我們集羣就進入faill狀態。

B、如果集羣超過半數以上master掛掉,無論是否有slave,集羣進入fail狀態.

 C、如果集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態

4、集羣中的主從複製
      集羣中的每個節點都有1個至N個複製品,其中一個爲主節點,其餘的爲從節點,如果主節點下線了,集羣就會把這個主節點的一個從節點設置爲新的主節點繼續工作,這樣集羣就不會因爲一個主節點的下線而無法正常工作。
注意:
1、如果某一個主節點和他所有的從節點都下線的話,redis集羣就會停止工作了。redis集羣不保證數據的強一致性,在特定的情況下,redis集羣會丟失已經被執行過的寫命令。
2、使用異步複製(asynchronous replication)是redis 集羣可能會丟失寫命令的其中一個原因,有時候由於網絡原因,如果網絡斷開時間太長,redis集羣就會啓用新的主節點,之前發給主節點的數據就會丟失。

 

 

Redis集羣數據分片的形式

 

Redis集羣不適用一致性hash,而是使用hash slot的方式將key分開來。這裏有16384個hash桶在redis集羣中,我們簡單的使用key的CRC16值模上16384,每一個redis實例都負責redis集羣中一些桶。 
比如說你有三個實例節點:

  • A包含0-5500的hash桶
  • B包含5501-11000的hash桶
  • C包含11001-16384的桶

這使得添加和新增節點更加容易,如果我想要增加實例節點D,我需要把實例節點A,B,C的一些數據移動到D,如果我想要移除節點A,我只需要把節點A的數據遷移到B跟C,當A當中數據爲0的時候我就可以移除節點A。 
從一個幾點移動hash桶到另外一個節點無需stop的操作,所以在移除新增節點,改變各個節點的百分比的時候故障時間。 
Redis集羣支持多key操作,即多個key在一個執行鏈中執行(一個事務或者一個lua腳本中),用戶使用命令hash tags可以強制多key處以同一個hash桶中。Hash tags的要旨是如果在keys中有子串用大括號{},那麼CRC16只會hash被大括號括住的子串。

 

Redis集羣中的主從模式

在我們的例子中,A、B、C節點中B節點宕機,我們將會喪失5501-11000節點的數據。 
假設我們給A、B、C節點加上從節點A1、B1、C1,當B節點宕機時候集羣仍舊可以正常使用。B1複製B的數據,當B節點宕機時候,節點B1將會提升爲主節點。更進一步,如果B1和B實例節點同時宕機,那麼整個集羣將無法繼續操作。

 

cluster命令

複製代碼

 
cluster info :打印集羣的信息
cluster nodes :列出集羣當前已知的所有節點( node),以及這些節點的相關信息。
節點
cluster meet <ip> <port> :將 ip 和 port 所指定的節點添加到集羣當中,讓它成爲集羣的一份子。
cluster forget <node_id> :從集羣中移除 node_id 指定的節點。
cluster replicate <node_id> :將當前節點設置爲 node_id 指定的節點的從節點。
cluster saveconfig :將節點的配置文件保存到硬盤裏面。
槽(slot)
cluster addslots <slot> [slot ...] :將一個或多個槽( slot)指派( assign)給當前節點。
cluster delslots <slot> [slot ...] :移除一個或多個槽對當前節點的指派。
cluster flushslots :移除指派給當前節點的所有槽,讓當前節點變成一個沒有指派任何槽的節點。
cluster setslot <slot> node <node_id> :將槽 slot 指派給 node_id 指定的節點,如果槽已經指派給
另一個節點,那麼先讓另一個節點刪除該槽>,然後再進行指派。
cluster setslot <slot> migrating <node_id> :將本節點的槽 slot 遷移到 node_id 指定的節點中。
cluster setslot <slot> importing <node_id> :從 node_id 指定的節點中導入槽 slot 到本節點。
cluster setslot <slot> stable :取消對槽 slot 的導入( import)或者遷移( migrate)。

cluster keyslot <key> :計算鍵 key 應該被放置在哪個槽上。
cluster countkeysinslot <slot> :返回槽 slot 目前包含的鍵值對數量。
cluster getkeysinslot <slot> <count> :返回 count 個 slot 槽中的鍵  
//新增 CLUSTER SLAVES node-id 返回一個master節點的slaves 列表
 

 

添加集羣節點

redis-trib.rb add-node 127.0.0.1:7007127.0.0.1:7001

PS:這個IP:PORT可以是集羣裏邊兒任意一個主節點的IP和端口,下同

 

接下來還要把7008做爲7007的從節點也加入到集羣裏邊兒來,這裏的話我們首先要記住7007這個主節點的節點id.從節點加入到集羣的時候要用到.

 redis-trib.rb add-node --slave --master-id 36d53c7f1896838249c0b4afdcf680bac2f4ec2e 127.0.0.1:7008 127.0.0.1:7001

注意:使用命令add-node添加的時候,本人測試基本都是作爲slave從節點存在,所以使用另外一個命令

我們可以通過CLUSTER MEET命令將6385節點加入到集羣中(例如:CLUSTER MEET 127.0.0.16385)則加入的是master節點。

 

cluster saveconfig

 

將節點的配置文件保存到硬盤裏面.

試一下:

127.0.0.1:7009> cluster saveconfig
OK

ok說明成功了,它會覆蓋配置文件夾裏的nodes.conf文件。這樣做是爲了某種情況下nodes文件丟失,這樣就會生成一個最新的節點配置文件。

cluster delslots

移除當前節點的一個或多個槽點。只能刪除自己的節點,刪除別人的沒用。

因爲master纔會有槽點,所以,也是隻能在master 節點上操作,在slave 操作也沒用。

用法是:

cluster delslots slots1 slotes2 slots3

我們看一下槽點的分配情況:

 
複製代碼
[root@web3 7009]# redis-cli -p 7009 -c cluster nodes| grep master
3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 192.168.33.13:7000 master - 0 1448529511113 1 connected 0-4095
404cf1ecf54d4df46d5faaec4103cfdf67888ad2 192.168.33.13:7001 master - 0 1448529511113 2 connected 4096-8191
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448529509101 3 connected 8192-12287
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 master - 0 1448529510609 4 connected 12288-16383
複製代碼

4臺master,那就把16381 16382 16383 3個槽點給刪掉。

開始:

 
[root@web3 7009]# redis-cli -p 7003
127.0.0.1:7003> cluster delslots 16381 16382 16383
OK
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected 12288-16380

看,7003的缺失少了3個節點。我們在看下cluster info

127.0.0.1:7003> cluster info
cluster_state:fail
cluster_slots_assigned:16381
cluster_slots_ok:16381
 
只有16381個,確實少了4個。但是,注意:cluster_state:fail,集羣失敗了!!!

爲什麼呢?爲什麼刪除了3個槽點就失敗了呢。因爲集羣就是要滿足所有的16364個槽點全部分配纔會成功。所以。就失敗了。

數據讀取自然也會失敗:

 
127.0.0.1:7003> get name
(error) CLUSTERDOWN The cluster is down

我們用redis-trib檢查一下,就知道了:

複製代碼
[root@web3 7009]# redis-trib.rb check 192.168.33.13:7000
...
...
[ERR] Nodes don't agree about configuration!
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
複製代碼

那如何挽救呢?那就順便看下下面的這個命令吧。

cluster addslots

將一個或多個槽(slot)指派(assign)給當前節點

用法是:

cluster addslots slots1 slotes2 slots3
那,我就用這個命令將上面刪掉的3個槽點再加到7003上看看:
127.0.0.1:7003> cluster addslots 16381 16382 16383
OK
127.0.0.1:7003>

OK了,看下是不是真的成功了: 

127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected 12288-16383

確實回來了,再看下集羣狀態,啓動了沒?

127.0.0.1:7003> cluster info
cluster_state:ok

數據讀取也正常了:

 
127.0.0.1:7003> get name
-> Redirected to slot [5798] located at 192.168.33.13:7001
"123"
192.168.33.13:7001>

我們已經獲取了要遷移的槽,是6918。因此,流程如下:

  • 目標6385節點中,將槽6918設置爲導入狀態
127.0.0.1:6385> CLUSTER SETSLOT 6918 importing 8f285670923d4f1c599ecc93367c95a30fb8bf34
OK
// 8f285670923d4f1c599ecc93367c95a30fb8bf34 是 6380 節點的名字

目標6385節點中,查看槽6918導入狀態

127.0.0.1:6385> CLUSTER NODES
cb987394a3acc7a5e606c72e61174b48e437cedb 127.0.0.1:6385 myself,master - 0 0 8 connected [6918-<-8f285670923d4f1c599ecc93367c95a30fb8bf34]
  • 6380節點中,將槽6918設置爲導出狀態
127.0.0.1:6380> CLUSTER SETSLOT 6918 migrating cb987394a3acc7a5e606c72e61174b48e437cedb
OK
// cb987394a3acc7a5e606c72e61174b48e437cedb 是 6385 節點的名字

6380節點中,查看槽6918導出狀態

127.0.0.1:6380> CLUSTER NODES
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 myself,master - 0 0 3 connected 5462-10922 [6918->-cb987394a3acc7a5e606c72e61174b48e437cedb]
  • 批量獲取槽6918中的鍵
127.0.0.1:6380> CLUSTER GETKEYSINSLOT 6918 5
1) "key:{test}:555"
2) "key:{test}:666"
3) "key:{test}:777"

確認一下這三個鍵是否存在於源6380節點。

127.0.0.1:6380> MGET key:{test}:777 key:{test}:666 key:{test}:555
1) "value:test:777"
2) "value:test:666"
3) "value:test:555"
  • 執行migrate命令進行遷移
127.0.0.1:6380> MIGRATE 127.0.0.1 6385 "" 0 1000 keys key:{test}:777 key:{test}:666 key:{test}:555
OK

批量遷移版本的MIGRATE命令是在redis 3.0.6之後加入的,命令參數如下:

MIGRATE host port key dbid timeout [COPY | REPLACE]
MIGRATE host port "" dbid timeout [COPY | REPLACE] KEYS key1 key2 ... keyN
// host port 指定遷移的目的節點地址
// dbid 指定遷移的數據庫id
// timeout 遷移的超時時間
// 如果指定了 COPY 選項,表示不刪除源節點上的key
// 如果指定了 REPLACE 選項,替換目標節點上已存在的key(如果存在)

當遷移完成後,我們在源6380節點查詢這三個鍵,發送回覆了一個ASK錯誤

127.0.0.1:6380> MGET key:{test}:777 key:{test}:666 key:{test}:555
(error) ASK 6918 127.0.0.1:6385

最後,我們只需向任意節點發送CLUSTER SETSLOT <slot> NODE <target_name>命令,將槽指派的信息發送給節點,然後這個節點會將這個指派信息發送至整個集羣。

CLUSTER SETSLOT 6918 node cb987394a3acc7a5e606c72e61174b48e437cedb
// cb987394a3acc7a5e606c72e61174b48e437cedb 是 6385 節點的名字

6381節點執行命令

127.0.0.1:6381> CLUSTER SETSLOT 6918 node cb987394a3acc7a5e606c72e61174b48e437cedb
OK

6379節點查看當前集羣槽指派信息

127.0.0.1:6379> CLUSTER NODES
29978c0169ecc0a9054de7f4142155c1ab70258b 127.0.0.1:6379 myself,master - 0 0 7 connected 0-5461
66478bda726ae6ba4e8fb55034d8e5e5804223ff 127.0.0.1:6381 master - 0 1496736248776 2 connected 10923-16383
cb987394a3acc7a5e606c72e61174b48e437cedb 127.0.0.1:6385 master - 0 1496736244766 10 connected 6918
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 master - 0 1496736247773 3 connected 5462-6917 6919-10922
// 過濾掉從節點和未指派槽的主節點

可以看到6380節點負責的槽變爲5462-6917 6919-10922,而6918已經被6385節點負責了。

如果出現以下情況(本人遇到的)

在7002節點登陸中執行命令clsuter delslot 135.刪除槽135

然後在執行 redis-trib.rb fix 192.168.0.109:7007命令來修復槽,

輸入yes即可,然後登陸查看cluster nodes信息,即可看到135槽平移到7002中,

7007中135被分割

 

edis集羣 Waiting for the cluster to join 一直等待

原創 2016年09月13日 23:37:59
  • 7915

redis集羣創建執行

 

./redis-trib.rb create --replicas 1 XXXX:PORT1 XXXX:PORT2 ....
的時候
一直等待 Waiting for the cluster to join 很久都沒有反應
原因:
redis集羣不僅需要開通redis客戶端連接的端口,而且需要開通集羣總線端口
集羣總線端口爲redis客戶端連接的端口 + 10000
如redis端口爲6379
則集羣總線端口爲16379
故,所有服務器的點需要開通redis的客戶端連接端口和集羣總線端口

注意:iptables 放開,如果有安全組,也要放開這兩個端口

 

重新分片

 

所謂重新分片,就是重新分配各個節點擁有的slots,這裏我們的主要目的是從老的節點中遷移一部分slots放到新節點中去,以便讓新節點真正成爲集羣中的一員.

同樣, 還是利用redis-trib.rb 工具.

[root@localhost redis-3.2.0]# /usr/local/redis/bin/redis-trib.rb reshard 127.0.0.1:7001

//PS: 這條命令是交互的,按照提示操作即可.

[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)?4096  //輸入一個數,這個4096表示遷移多少個slots數

What is the receiving node ID? 36d53c7f1896838249c0b4afdcf680bac2f4ec2e //輸入目標節點ID,表示遷移到哪個目標節點

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.

Source node #1:all //輸入all表示從老的所有節點進行重分配,湊夠4096個slots給到新節點.

也可以輸入源節點id, 可以輸入多個源節點id,最後輸入done.就開始從你輸入的源節點id的節點進行遷移了.

刪除節點

要刪除集羣中的某個節點(注:這裏說的是集羣中的主節點),首先必須確保這個節點沒有擁有任何一個slots.我們現在來刪除7001 這個節點.

首先,我們要把7001這個節點上的slots全部遷移出去.

我們直接執行命令刪除看看.

[root@localhost redis-3.2.0]# /usr/local/redis/bin/redis-trib.rb del-node 127.0.0.1:7001 a2eee0ea546f2c3701b08981737c07938039857c

>>> Removing node a2eee0ea546f2c3701b08981737c07938039857c from cluster 127.0.0.1:7001

[ERR] Node 127.0.0.1:7001 is not empty! Reshard data away and try again.

[root@localhost redis-3.2.0]#

 由此可知,直接刪會提示不爲空,不能刪除,分片後再刪吧.把這個節點擁有的slots全部遷移出去即可.

[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)?16384 //輸入一個大於或等於7001節點所擁有的slots數的數即可.

What is the receiving node ID? 8ab3d14eba181c06dc8826bea0db1becdead2533 //接收這些slots的目標節點,這裏是7002節點

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.

Source node #1:a2eee0ea546f2c3701b08981737c07938039857c //因爲我們要刪除7001這個節點,所以源節點的id就是7001的節點ID

Source node #2:done //輸入done,回車,就會開始從7001 這個節點遷移16384個slot(沒有這麼多就遷移擁有的全部)到7002節點中去.

7001 已經沒有分配slots了,可以從集羣中刪除了.

 [root@localhost redis-3.2.0]# redis-trib.rb del-node 127.0.0.1:7002 a2eee0ea546f2c3701b08981737c07938039857c           另外經過觀察,這個主節點被刪除之後,它之前擁有的從節點會自動成爲其他主節點的從節點.                                  

以上就是利用官方提供的redis-trib.rb 工具來完成上述的各項工作,事實上這個工具也是利用cluster的內部命令進行的整合以方便我們使用和管理.如果想了解更多的細節,需要查看官方的文檔,可以完全脫離redis-trib.rb的便利性純手工使用cluster內部命令來完成集羣的搭建以及分配slots,添加節點,刪除節點等等.

 

redis緩存會出現什麼問題?

redis緩存數據庫的數據,有一點就顯得特別重要,那就是數據一致性的問題。

單個數據庫在多線程操作的時候如果不是數據庫鎖的限制會出現很多數據不一致的問題,ACID這裏我就不多說了。

redis緩存也會有這樣的問題,就是數據庫的數據更新到redis是會有時間差的,這樣的時間差就會導致數據不一致。

比如一件商品價格在數據庫裏面是500,然後redis也是500,但是突然數據庫修改成了600,如果所有用戶都是讀入數據庫的話,數據庫會加鎖,然後避免用戶讀出之前那個500,但是redis的更新怎麼說都是有時間差的,所以用戶就有可能讀取到500這個數據。

這就是數據不一致的問題。

 

 

redis適合緩存怎麼樣的數據?

這裏的數據分爲兩塊,第一是數據庫的數據,第二是頁面的一些靜態數據。

這裏說的是數據庫的數據。

頁面的一些靜態數據不適合存放在緩存中。

然後對於上面提出的數據不一致的問題,所以緩存的數據也有要求。

 

不要緩存那些對於數據一致性要求很高的數據。

如果這個數據存在被修改的可能性,那麼最好不要存緩存,要麼,就不要放數據庫,只放緩存。

那些對於數據一致性不高的數據,都是可以放的。

強調一點是,如果這個數據放了,但是對於這個數據的操作不是修改,而是隻有刪除的話,也是可以存放緩存的,因爲在實際操作中,如果一個刪除操作被執行的時候,緩存可以先進行刪除,這樣就能確保沒有用戶能夠讀取到刪除之後的數據,然後再對數據庫進行刪除。

本人在集羣操作中出現以下錯誤:
1、[ERR] Node 192.168.161.131:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 
解決:1)將每個節點下aof、rdb、nodes.conf本地備份文件刪除; 
   2)172.168.63.201:7001> flushdb #清空當前數據庫(可省略) 
   3)之後再執行腳本,成功執行;
2、執行分片命令./redis-trib.rb reshard 192.168.0.109:7001 出現
>>> Check for open slots...
[WARNING] Node 192.168.0.109:7001 has slots in importing state (8230).
[WARNING] The following slots are open: 8230
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** Please fix your cluster problems before resharding
解決:1)執行命令redis-trib.rb fix 192.168.0.109:7001
   2)如果無法修復,只要把redis.conf中定義的cluster-config-file所在的文件刪除,重新啓動redis-server及運行redis-trib即可
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章