redis集群搭建

                                                                    redis集群搭建


一、下载redis 编译

redis-4.0.8.tar.gz


二、建6个目录

[root@server1 ~]# cd /usr/local/
[root@server1 local]# mkdir rediscluster    #先建一个根目录

[root@server1 local]# cd rediscluster/
[root@server1 rediscluster]# mkdir 700{1..6} 


Screenshot from 2018-07-03 22-36-52.png


注:与大多数分布式中间件一样,redis的cluster也是依赖选举算法来保证集群的高可用,所以类似ZK一样,一般是奇数个节点(可以允许N/2以 下的节点失效),再考虑到每个节点做Master-Slave互为备份,所以一个redis cluster集群最少也得6个节点


三、配置文件

[root@server1 rediscluster]# cd 7001
[root@server1 7001]# vim redis.conf

port 7001       # 修改启动端口为7001

cluster-enabled yes    # 开启允许集群

cluster-config-file nodes.conf       # 修改集群配置文件指向路径
daemonize yes     # 开启守护进程模式

  dir /usr/local/rediscluster/7001   #目录

  cluster-node-timeout 5000        #集群中各节点相互通讯时,允许"失联"的最大毫秒数,配置为5秒,超过5秒某个节点没向其它节点汇报成功,认为该节点挂了。


  appendonly yes        #开启持久化


把上面的redis.conf,放到每个目录的redis目录中,注意修改port端口,即7001目录下的port为7001,7002目录下的port为7002...

[root@server1 rediscluster]# cp 7001/redis.conf 7002/    依次复制过去并修改

[root@server1 ~]# cd redis-4.0.8


[root@server1 redis-4.0.8]# cd src/


[root@server1 src]# scp redis-trib.rb /usr/local/bin/


[root@server1 src]# cd /usr/local/bin/


Screenshot from 2018-07-03 22-47-01.png


虽然可以把6个redis server启动成功,但是启动后彼此之间是完全独立的,需要借助其它工具将其加入cluster,而这个工具就是redis提供的一个名为redis-trib.rb的ruby脚本



四、安装redis的ruby模块

ruby-2.2.3-1.el6.x86_64.rpm
rubygems-1.3.7-5.el6.noarch.rpm
libyaml-0.1.3-4.el6_6.x86_64.rpm


[root@server1 ~]# yum install -y rubygems-1.3.7-5.el6.noarch.rpm

[root@server1 ~]# yum install -y ruby-2.2.3-1.el6.x86_64.rpm    libyaml-0.1.3-4.el6_6.x86_64.rpm


[root@server1 ~]# gem list      查看模块

Screenshot from 2018-07-03 22-56-32.png


[root@server1 ~]# gem install --local redis-4.0.1.gem     安装模块


Screenshot from 2018-07-03 22-59-07.png


Screenshot from 2018-07-03 22-59-55.png


五、依次启动各个redis

[root@server1 rediscluster]# cd 7001


[root@server1 7001]# redis-server redis.conf 


Screenshot from 2018-07-03 23-02-15.png


如下,各个端口已开


Screenshot from 2018-07-03 23-04-33.png


六、创建cluster


[root@server1 ~]# redis-trib.rb create --replicas 1 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 127.0.0.1:7006



replicas 1的意思,就是每个节点创建1个副本(即:slave),所以最终的结果,就是后面的127.0.0.1:7001~127.0.0.1:7006中,会有3个会指定成master,而其它3个会指定成slave。


Screenshot from 2018-07-03 23-09-51.png


注:利用redis-trib创建cluster的操作,只需要一次即可,假设系统关机,把所有6个节点全关闭后,下次重启后,即自动进入cluster模式,不用再次redis-trib.rb create。


如果想知道,哪些端口的节点是master,哪些端口的节点是slave,可以用下面的命令:


[root@server1 ~]# redis-trib.rb check 127.0.0.1:7001

Screenshot from 2018-07-03 23-14-40.png


[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001

Screenshot from 2018-07-03 23-15-57.png


它会把所有的master信息输出,包括这个master上有几个缓存key,有几个slave,所有master上的keys合计,以及平均每个slot上有多少key.


解释slot

Screenshot from 2018-07-03 23-17-54.png


如上图,redis-cluster把整个集群的存储空间划分为16384个slot(译为:插槽?),当6个节点分为3主3从时,相当于整个 cluster中有3组HA的节点,3个master会平均分摊所有slot,每次向cluster中的key做操作时(比如:读取/写入缓 存),redis会对key值做CRC32算法处理,得到一个数值,然后再对16384取模,通过余数判断该缓存项应该落在哪个slot上,确定了 slot,也就确定了保存在哪个master节点上,当cluster扩容或删除节点时,只需要将slot重新分配即可(即:把部分slot从一些节点移 动到其它节点)。


七、redis-cli客户端操作


[root@server1 ~]# redis-cli -c -h localhost -p 7001   注意加参数-c,表示进入cluster模式,随便添加一个缓存试试


[root@server1 ~]# redis-cli -c -h localhost -p 7001
localhost:7001> set name cara
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"cara"
127.0.0.1:7002> set password redhat
OK
127.0.0.1:7002> get password
"redhat"
127.0.0.1:7002> quit


[root@server1 ~]# redis-cli -c -h localhost -p 7002
localhost:7002> set user liu
OK
localhost:7002> quit


参考如下,理解

localhost:7000> set user1 jimmy
-> Redirected to slot [8106] located at 127.0.0.1:7001
OK

注意第2行的输出,表示user1这个缓存通过计算后,落在8106这个slot上,最终定位在7001这个端口对应的节点上(解释:因为7000 是slave,7001才是master,只有master才能写入),如果是在7001上重复上面的操作时,不会出现第2行(解释:7001是 master,所以不存在redirect的过程)


➜  src ./redis-cli -c -h localhost -p 7001
localhost:7001> set user1 yang
OK
localhost:7001>


八、FailOver测试

先用redis-trib.rb 查看下当前的主、从情况

[root@server1 ~]# redis-trib.rb check 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: b3b4e08e73e09d7f87158118e2b6e748109c1d08 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 60427b62e3b9ffe991dda6498ceeca5d611b3b8e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b3b4e08e73e09d7f87158118e2b6e748109c1d08
S: 0f907e0d51e0a9ff2a5c415a714badbf666eb87f 127.0.0.1:7006
   slots: (0 slots) slave
   replicates 770c0d7a31be9204e244fd61ed17b8a041b2eb74
M: 3dbafd70a2f4f1c608c996b6ad82964a2f473f42 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: 770c0d7a31be9204e244fd61ed17b8a041b2eb74 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 5b9745fabdd98b820616a11d4f397db1410aa073 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 3dbafd70a2f4f1c608c996b6ad82964a2f473f42
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

从输出上看7005是7001(b3b4e08e73e09d7f87158118e2b6e748109c1d08)的slave,现在我们人工把7001的redis进程给kill掉,然后观察7005的终端输出:


Screenshot from 2018-07-03 23-50-30.png


[root@server1 ~]# kill -9 1131

3872:S 21 Mar 10:55:55.771 # Cluster state changed: fail
3872:S 21 Mar 10:55:55.869 # Start of election delayed for 954 milliseconds (rank #0, offset 183).

3872:S 21 Mar 10:55:56.911 # Failover election won: I'm the new master.


注意这几行,第1行表明由于7001宕机,cluster状态已经切换到fail状态,第2行表示发起选举,第3行表示7005端口对应的节点当选为new master。

注:如果一组分片中的master、slave全挂了,整个cluster集群不再接受任何读/写指令,redis-cli终端里会直接报cluster down,但是info等其它指令仍然可用,直到这一组分片中,有一个节点恢复为止。


九、cluster 扩容

再添加2个节点,先把7001复制二份,变成7007,7008,然后进入7007/7008目录redis的src子目录下

[root@server1 rediscluster]# cd 7001
[root@server1 7001]# ls
appendonly.aof  dump.rdb  nodes.conf  redis.conf
[root@server1 7001]# rm appendonly.aof dump.rdb nodes.conf

由于7001我们刚才启动过,里面有已经有一些数据了,所以要把数据文件,日志文件,以及cluster的nodes.conf文件删除,变成一个空的redis独立节点,否则无法加入cluster。

[root@server1 rediscluster]# mkdir 700{7..8}
[root@server1 rediscluster]# ls
7001  7002  7003  7004  7005  7006  7007  7008
[root@server1 rediscluster]# cp 7001/redis.conf 7007
[root@server1 rediscluster]# cp 7001/redis.conf 7008

7/8的文件修改

Screenshot from 2018-07-04 00-26-49.png


修改完成后,分别开启

[root@server1 7007]# redis-server redis.conf

[root@server1 7008]# redis-server redis.conf

将上面关掉的7001开启,redis-server redis.conf


然后加入集群

[root@server1 ~]# redis-trib.rb add-node 127.0.0.1:7008 127.0.0.1:7001

注:第1个参数为新节点的"IP:端口",第2个参数为集群中的任一有效的节点


Screenshot from 2018-07-04 00-31-35.png


用下面的命令把7008当成slave加入

redis-trib.rb add-node --slave --master-id 226d1af3c95bf0798ea9fed86373b89347f889da 127.0.0.1:7008 127.0.0.1:7006

这里多出了二个参数:--slave 表示准备将新节点当成slave加入,--master-id xxxxx 则是指定要当谁的slave,后面的xxx部分,即为前面check的输出结果中,7006的ID,完事之后,可以再次确认状态


十、reshard 重新划分slot


增加新的节点之后,问题就来了,16384个slot已经被其它3组节点分完了,新节点没有slot,没办法存放缓存,所以需要将slot重新分布。

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:7008 (a2776c09...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.

用下面的命令可以重新分配slot

1
redis-trib.rb reshard 127.0.0.1:7001

reshard后面的IP:port,只要是在cluster中的有效节点即可。


执行

[root@server1 ~]# redis-trib.rb reshard 127.0.0.1:7001

How many slots do you want to move (from 1 to 16384)? 1000    #这里输入要移动多少slot


What is the receiving node ID? 78f82a304e1056ae6c5c358350fe77a1c0191ba3    #这里输入目标节点的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    #将所有node都当成源节点


Do you want to proceed with the proposed reshard plan (yes/no)? yes      #确认执行


注:第一个交互询问,填写多少slot移动时,要好好想想,如果填成16384,则将所有slot都移动到一个固定节点上,会导致更加不均衡!建议每次移动500~1000,这样对线上的影响比较小。

另外在填写source node时,除了all之外,还可以直接填写源节点的id,即:



How many slots do you want to move (from 1 to 16384)? 300
What is the receiving node ID? a2776c0928507f893ca43bdb9c146dd77e95af66
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:3d8958bc397e6a37095ba0ea1ef8e1f8e3b85996         #这里填写源节点的id


Source node #2:done           #这里输入done表示,不再继续添加源节点了


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


查看分布情况:

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 4828 slots | 1 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7008 (a2776c09...) -> 0 keys | 300 slots | 0 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.


十一、删除节点del-node

某些节点不再需要时,可以用del-node删除


删除节点命令:

1
redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66

del-node后面的ip:port只要是cluster中有效节点即可,最后一个参数为目标节点的id

注意:只有slave节点和空的master节点可以删除,如果 master非空,先用reshard把上面的slot移动到其它node后再删除,如果有一组master-slave节点,将master上所有 slot移到其它节点,然后将master删除,剩下的slave会另寻他主,变成其它master的slave。


另外:删除节点的含义,不仅仅是从cluster中将这个节点移除,还会直接将目标节点的redis服务停止。


如下报错

[root@server1 ~]# redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66
>>> Removing node a2776c0928507f893ca43bdb9c146dd77e95af66 from cluster 127.0.0.1:7001
[ERR] Node 127.0.0.1:7008 is not empty! Reshard data away and try again.

redis cluster提示7001已经有数据了,不能够被删除,需要将他的数据转移出去,也就是和新增主节点一样需重新分片。

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7008
127.0.0.1:7008 (a2776c09...) -> 0 keys | 300 slots | 0 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 4828 slots | 1 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.

可以看出7008占用300个槽点

[root@server1 ~]# redis-trib.rb reshard 127.0.0.1:7008
How many slots do you want to move (from 1 to 16384)? 300     #写入所占槽
What is the receiving node ID? 3d8958bc397e6a37095ba0ea1ef8e1f8e3b85996    #7001 ( 移给谁 )
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:a2776c0928507f893ca43bdb9c146dd77e95af66    #7008 
Source node #2:done

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


[root@server1 ~]# redis-trib.rb info 127.0.0.1:7008
127.0.0.1:7008 (a2776c09...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 5128 slots | 1 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.


再次删除节点

[root@server1 ~]# redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66
>>> Removing node a2776c0928507f893ca43bdb9c146dd77e95af66 from cluster 127.0.0.1:7008
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.


如下7008在进程中已消失
 1267 ?        Ssl    0:09 redis-server *:7001 [cluster]
 1272 ?        Ssl    0:07 redis-server *:7002 [cluster]
 1277 ?        Ssl    0:07 redis-server *:7003 [cluster]
 1282 ?        Ssl    0:05 redis-server *:7004 [cluster]
 1287 ?        Ssl    0:05 redis-server *:7005 [cluster]
 1292 ?        Ssl    0:05 redis-server *:7006 [cluster]
 1311 pts/0    Sl+    0:07 redis-server *:7007 [cluster]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章