redis集羣-4

redis集羣原理

redis cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說,集羣中的每一個節點都是平等的關係,都是對等的,每一個節點都保存各自的數據和整個集羣的狀態。
每一個節點都和其餘全部節點鏈接,並且這些鏈接保持活躍,這樣就保證了咱們只須要鏈接集羣中的任意一個節點,就能夠獲取到其餘節點的數據。 Redis 集羣沒有並使用傳統的一致性哈希來分配數據,而是採用另一種叫作哈希槽 (hash slot)的方式來分配的。
redis cluster 默認分配了
16384 個slot,當咱們set一個key 時,會用CRC16算法來取模獲得所屬的slot,而後將這個key 分到哈希槽區間的節點上,具體算法就是:CRC16(key) % 16384
因此咱們在測試的時候看到set 和 get 的時候,直接跳轉到了7001端口的節點。 Redis 集羣會把數據存在一個 master 節點,而後在這個 master 和其對應的salve 之間進行數據同步。
當讀取數據時,也根據一致性哈希算法到對應的 master 節點獲取數據。只有當一個master 掛掉以後,纔會啓動一個對應的 salve 節點,充當 master 。

使用環境

解決單點固障,鏈接上集羣中的任務一個節點都能取到數據.

安裝環境

須要注意的是:reids集羣從3.0開始支持的。必需要3個或以上的主節點,不然在建立集羣時會失敗,而且當存活的主節點數小於總節點數的一半時,整個集羣就沒法提供服務了
192.168.23.150 使用的docker
    node1_redis 172.16.0.10
    node2_redis 172.16.0.11

6個redis節點信息:
    172.16.0.10:7001
    172.16.0.10:7002
    172.16.0.10:7003
    172.16.0.11:7004
    172.16.0.11:7005
    172.16.0.11:7006

安裝redis-3.2.8

分別在兩個節點上安裝redis
yum install -y gcc tar
-xf redis-3.2.8.tar.gz cd redis-3.2.8 make && make PREFIX=/opt/redis install
#centos7安裝
make MALLOC=libc && make PREFIX=/opt/redis install
cd src 
cp redis
-trib.rb /opt/redis/bin/
echo
"export PATH=$PATH:/opt/redis/bin" >> /etc/profile.d/env.sh
source
/etc/profile

建立redis節點

分別在兩個節點上建立,別外一臺是7004,70057006
建立目錄
    cd /opt/redis
    mkdir -p {data,logs}/redis_cluster/{7001,7002,7003}
準備配置文件redis.conf
    daemonize yes
  protected-mode no  #3.2 後的新特性,禁止公網訪問redis cache,增強redis安全的 pidfile
/opt/redis/data/redis_cluster/7001/redis_7001.pid port 7001 timeout 300 loglevel debug logfile /opt/redis/data/redis_cluster/7001/redis_7001.log databases 16 save 900 1 save 300 10 save 60 10000 rdbcompression yes dbfilename dump.rdb dir /opt/redis/data/redis_cluster/7001/ cluster-enabled yes #開啓集羣 把註釋#去掉 cluster-config-file nodes_7001.conf #集羣的配置 配置文件首次啓動自動生成 7001,7001,7002 cluster-node-timeout 15000 #請求超時 默認15秒,可自行設置 cp -a redis.conf /opt/redis/data/redis_cluster/7001/ cp -a redis.conf /opt/redis/data/redis_cluster/7002/ cp -a redis.conf /opt/redis/data/redis_cluster/7003/ sed -i 's/7001/7001/g' /opt/redis/data/redis_cluster/7001/redis.conf sed -i 's/7001/7002/g' /opt/redis/data/redis_cluster/7002/redis.conf sed -i 's/7001/7003/g' /opt/redis/data/redis_cluster/7003/redis.conf redis-server /opt/redis/data/redis_cluster/7001/redis.conf redis-server /opt/redis/data/redis_cluster/7002/redis.conf redis-server /opt/redis/data/redis_cluster/7003/redis.conf

建立redis集羣

安裝依賴
    yum -y install ruby ruby-devel rubygems rpm-build

    安裝ruby redis 接口
        gem install redis #執行這步失敗的話。能夠說明的方式操做 1. Fetching: redis-3.2.2.gem (100%)
          2. Successfully installed redis-3.2.2
          3. Parsing documentation for redis-3.2.2
          4. Installing ri documentation for redis-3.2.2
          5. Done installing documentation for redis after 1 seconds
          6. 1 gem installed
        說明:因爲ruby 官放提供的gem 源被GFW 幹掉了,因此這裏須要從新使用國內的源,方法以下:
        移除自帶的源:
            gem sources -l
            gem sources --remove https://rubygems.org/
            添加國內淘寶源:
            gem source --add https://ruby.taobao.org/
            gem sources -l
            gem install redis
 報錯:redis requires Ruby version >= 2.2.2
    解決:
    方法1:採用rvm來更新ruby(很差用)
      gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
      curl -L get.rvm.io | bash -s stable
      source /usr/local/rvm/scripts/rvm
      rvm list known #查看rvm庫中已知的ruby版本
rvm install 2.3.3
      rvm use 2.3.3
rvm use 2.3.3 --default #默認使用版本
rvm remove 2.0.0 #移除2.0.0版本
ruby --version #查看版本
      
      gem install redis
 方法2:編譯安裝(好用)
      (1)
安裝Ruby
      wget http://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.tar.gz
      tar zxvf  ruby-2.3.5.tar.gz
      cd ruby-2.3.5
      ./configure  --prefix=/opt/ruby
      make && make install
      ln -s /opt/ruby/bin/ruby /usr/bin/ruby
      ln -s /opt/ruby/bin/gem /usr/bin/gem
      ruby -v #查看版本
      (2)安裝rubygem redis依賴
      wget http://rubygems.org/downloads/redis-3.3.0.gem
      gem install -l redis-3.3.0.gem
      redis-trib.rb   #出現幫助文檔,說明成功了

       建立集羣 redis
-trib.rb create --replicas 1 172.16.0.10:7001 172.16.0.10:7002 172.16.0.10:7003 172.16.0.11:7004 172.16.0.11:7005 172.16.0.11:7006 #--replicas 1 就是這個集羣節點都有一個副本

鏈接集羣

鏈接方式爲 redis-cli -h 172.16.0.10 -c -p 7002  ,加參數 -c 可鏈接到集羣,由於上面 redis.conf 將 bind 改成了ip地址,因此 -h 參數不能夠省略。

集羣驗證

在第一臺機器上鍊接集羣的7002端口的節點,在另一臺鏈接7005節點,鏈接方式爲 redis-cli -h 172.16.0.10 -c -p 7002  
,加參數 -c 可鏈接到集羣,由於上面 redis.conf 將 bind 改成了ip地址,因此 -h 參數不能夠省略。 在7005節點執行命令: set hello world 在7002節點執行: get hello 在任何節點上能獲取到hello的值,說明集羣運做正常(注意:用keys *查看不到key.可是get hello 能夠獲取到值,另外能夠在副本節點上面添加數據)

集羣狀態查看

隨便登錄一個redis node節點執行命令:
    redis-cli -h 172.16.0.10 -c -p 7002 #登錄
    cluster nodes  #查看節點信息

 添加節點

添加啓動個節點,步聚和上面同樣
執行redis-trib.rb add-node 添加新節點:
/opt/src/redis-3.0.5/src/redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001
說明:添加新節點到羣集中,須要指定羣集中任意一個已存在的節點,實例中的第一個IP:PORT 爲新的redis 節點的IP及端口,第二個IP:PORT 爲redis 羣集中已經存在的任意redis 節點。
添加完成,登錄羣集,驗證加入後的新節點變爲主節點:
redis-cli -c -h 127.0.0.1:7001
  1. 127.0.0.1:7001> cluster nodes
  2. 1455e7fe08990793e9663ed14cf9c19778ef01a7 127.0.0.1:7004 slave 5951f796ac2930f73b6988ccb633ab2ea10a873b 0 1447233606830 5 connected
  3. 577be6355e37a54c7a076e27ab0927298abcae5f 127.0.0.1:7003 slave 73bf492caa9ba02567581145b5d4f32f9f28e09d 0 1447233608841 4 connected
  4. 30117592dc0d31b1c611ca47820f1d820565926e 127.0.0.1:7005 slave 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 0 1447233607331 6 connected
  5. 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 127.0.0.1:7002 master - 0 1447233607835 3 connected 10923-16383
  6. 9868224efa99bca26a171f6e1c21dc11c4e2ab5c 127.0.0.1:7006 master - 0 1447233607331 0 connected
  7. 73bf492caa9ba02567581145b5d4f32f9f28e09d 127.0.0.1:7001 myself,master - 0 0 1 connected 0-5460
  8. 5951f796ac2930f73b6988ccb633ab2ea10a873b 127.0.0.1:7001 master - 0 1447233607331 2 connected 5461-10922
2.添加從節點:
/opt/src/redis-3.0.5/src/redis-trib.rb add-node --slave 127.0.0.1:7008 127.0.0.1:7001
redis-cli -c -p 7001
  1. 127.0.0.1:7001> cluster nodes
  2. ef275d7c4c1f00ce236011f0c0cd7b4be7eb7772 127.0.0.1:7007 slave 9868224efa99bca26a171f6e1c21dc11c4e2ab5c 0 1447241281594 0 connected
  3. 1455e7fe08990793e9663ed14cf9c19778ef01a7 127.0.0.1:7004 slave 5951f796ac2930f73b6988ccb633ab2ea10a873b 0 1447241282095 5 connected
  4. 577be6355e37a54c7a076e27ab0927298abcae5f 127.0.0.1:7003 slave 73bf492caa9ba02567581145b5d4f32f9f28e09d 0 1447241282597 4 connected
  5. 30117592dc0d31b1c611ca47820f1d820565926e 127.0.0.1:7005 slave 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 0 1447241281594 6 connected
  6. 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 127.0.0.1:7002 master - 0 1447241283098 3 connected 10923-16383
  7. 9868224efa99bca26a171f6e1c21dc11c4e2ab5c 127.0.0.1:7006 master - 0 1447241282095 0 connected
  8. 73bf492caa9ba02567581145b5d4f32f9f28e09d 127.0.0.1:7001 myself,master - 0 0 1 connected 0-5460
  9. 5951f796ac2930f73b6988ccb633ab2ea10a873b 127.0.0.1:7001 master - 0 1447241283599 2 connected 5461-10922

數據分片轉移

數據分片,也可稱數據轉移。由第二篇中添加的主節點可知,新的主節點沒有數據,也不能參加主的選舉,因此,爲了該主恩可以正常被選舉,咱們能夠將原有主節點的數據轉移至該節點:
咱們先來看下新主節點:node

192.168.159.30:7003> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 myself,master - 0 0 3 connected 10923-16383
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523528690606 6 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 6d377542e01a23fe5cfc7f8f25365e910480a11a 0 1523528689096 4 connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523528688595 5 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523528687589 7 connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30:7001 master - 0 1523528686584 1 connected 0-5460
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 master - 0 1523528687087 2 connected 5461-10922
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523528689600 7 connected  #新加節點沒有數據

 從上面的實例中能夠很明顯的看出,有三個從,四個主,當前登陸的主爲7003,且除了主節點7007沒有數據外,其它三個主都有(7001:0-5460;7002:5461-10922;7003:10923-16383)web

如今,我須要從三個節點抽取500個數據槽給新節點 7007,那麼執行redis

redis-trib.rb reshard 127.0.0.1:7007

詢問從1-16384 個插槽中要移動多少數據槽,我這裏是500:算法

How many slots do you want to move (from 1 to 16384)? 500

詢問接收數據槽節點的ID(根據上面的cluster nodes 能夠獲得 7007 的ID):docker

What is the receiving node ID? 9868224efa99bca26a171f6e1c21dc11c4e2ab5c

詢問你是從全部主節點移除500 個數據槽仍是單從某一個主節點中移出 500個數據槽?輸入 all ,表明從全部主節點;若是要從某個節點逸出,那麼只須要輸入該主節點ID,回車便可:centos

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

輸入完成,回車後開始移動數據槽安全

移動完成,再來看各主的數據ruby

192.168.159.30:7003> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 myself,master - 0 0 3 connected 11172-16383
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523530671361 6 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 6d377542e01a23fe5cfc7f8f25365e910480a11a 0 1523530673372 8 connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523530675386 5 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523530670360 9 connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30:7001 master - 0 1523530674379 8 connected 500-5711 10923-11171
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 master - 0 1523530674883 2 connected 5712-10922
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523530672367 9 connected 0-499    #很明顯,主 7006 上已經被分配數據槽了!

上面是從全部主節點中平均抽取數據槽到新的主節點上。bash

==================對單一節點進行===========================app

那麼,咱們也能夠針對單一節點進行,好比,我想將7001 剩餘的數據槽所有轉移到 7007 上,那麼以下:

執行:

redis-trib.rb reshard 127.0.0.1:7007

主節點 7001 上能夠轉移的數據槽:

How many slots do you want to move (from 1 to 16384)? 5295

接收數據節點的ID:

What is the receiving node ID? 9868224efa99bca26a171f6e1c21dc11c4e2ab5c

轉移數據主節點的ID(就是要把哪一個節點的數據轉移出去的節點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:73bf492caa9ba02567581145b5d4f32f9f28e09d

輸完一個要轉移數據的節點後,會繼續要求輸入第二個節點的ID。因爲這裏我只想轉移主節點7000 上的全部數據,因此,第二個節點ID 我輸入done,表明只須要轉移第一個主節點:

Source node #2:done

詢問你是否確認要執行數據分片:

Do you want to proceed with the proposed reshard plan (yes/no)? yes

再次登陸查看集羣:

192.168.159.30:7003> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 myself,master - 0 0 3 connected 11172-16383
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523531456275 6 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531457281 9 connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523531454767 5 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531454266 9 connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30:7001 master - 0 1523531453260 8 connected #能夠看到7001沒有數據了
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 master - 0 1523531455270 2 connected 5712-10922
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523531452253 9 connected 0-5711 10923-11171

 節點刪除

redis 羣集中,要刪除節點,必須先將該節點的數據所有轉移,不然是沒法刪除節點的(也就是,redis 羣集中智能刪除空節點):

查看集羣信息:

redis-cli -h 192.168.159.30 -p 7001 -c
192.168.159.30:7001> cluster nodes
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523531623348 6 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531627894 9 connected
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 127.0.0.1:7007 master - 0 1523531625877 9 connected 0-5711 10923-11171
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523531626887 5 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531624862 9 connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 127.0.0.1:7001 myself,master - 0 0 8 connected #7001沒有數據
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 master - 0 1523531628902 2 connected 5712-10922
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 master - 0 1523531623853 3 connected 11172-16383

咱們來嘗試刪除某個帶有數據的主節點:

[root@docker1 ~]# redis-trib.rb del-node 127.0.0.1:7002 '73b5273bfa67693eeb01a5c99c855a333d6214e0'  
>>> Removing node 73b5273bfa67693eeb01a5c99c855a333d6214e0 from cluster 127.0.0.1:7002
[ERR] Node 127.0.0.1:7002 is not empty! Reshard data away and try again  #7002是隨便哪一個能連上集羣的端口,後面的是非空數據的節點ID. 能夠看出非空的節點不能刪除

再次刪除空節點:

redis-trib.rb del-node 127.0.0.1:7002 '6d377542e01a23fe5cfc7f8f25365e910480a11a'
>>> Removing node 6d377542e01a23fe5cfc7f8f25365e910480a11a from cluster 127.0.0.1:7002
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.


注:在刪除節點時,不容許使用 redis-trib.rb del-node 刪除節點IP:PORT '刪除節點的ID'.只能用其它節點IP:PORT '要刪除節點的ID'

驗證被刪除:

[root@docker1 ~]# redis-cli -h 192.168.159.30 -p 7002 -c
192.168.159.30:7002> cluster nodes
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523532545171 9 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 192.168.159.30:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523532546685 9 connected
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523532548195 9 connected 0-5711 10923-11171
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523532546181 5 connected
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 myself,master - 0 0 2 connected 5712-10922
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 master - 0 1523532544157 3 connected 11172-16383
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523532547190 6 connected



注#能夠看出7001已經被刪除了,上面刪除的id就是7001的
相關文章
相關標籤/搜索