redis 槽点重新分配 集群_Redis Cluster

前言

redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用。现在的2.x的稳定版本是2.8.19,也是我们项目中普遍用到的版本。

redis在年初发布了3.0.0,官方支持了redis cluster,也就是集群。至此结束了redis 没有官方集群的时代,之前我们用redis cluster用的最多的应该是twitter 发布的Twemproxy(https://github.com/twitter/twemproxy)

这2个我会在后续去使用它们。下面的文字,我尽量用通熟易懂的方式来阐述。

redis cluster 理论知识

截止写这篇文章前,redis 3.x的最新版本是3.0.5。今天的学习和实践就是用这个版本。

Redis Cluster设计要点

redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

那么redis 是如何合理分配这些节点和数据的呢?

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。

注意的是:必须要3个以后的主节点,否则在创建集群时会失败,我们在后续会实践到。

所以,我们假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:

节点A覆盖0-5460;

节点B覆盖5461-10922;

节点C覆盖10923-16383.

如下图所示:

那么,现在我想设置一个key ,比如叫my_name:

set my_name yangyi

按照redis cluster的哈希槽算法:CRC16('my_name')%16384 = 2412。 那么就会把这个key 的存储分配到 A 上了。

同样,当我连接(A,B,C)任何一个节点想获取my_name这个key时,也会这样的算法,然后内部跳转到B节点上获取数据。

这种哈希槽的分配方式有好也有坏,好处就是很清晰,比如我想新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上,我会在接下来的实践中实验。大致就会变成这样:

节点A覆盖1365-5460

节点B覆盖6827-10922

节点C覆盖12288-16383

节点D覆盖0-1364,5461-6826,10923-12287

同样删除一个节点也是类似,移动完成后就可以删除这个节点了。

所以redis cluster 就是这样的一个形状:

Redis Cluster主从模式

redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。

上面那个例子里, 集群有ABC三个主节点, 如果这3个节点都没有加入从节点,如果B挂掉了,我们就无法访问整个集群了。A和C的slot也无法访问。

所以我们在集群建立的时候,一定要为每个主节点都添加了从节点, 比如像这样, 集群包含主节点A、B、C, 以及从节点A1、B1、C1, 那么即使B挂掉系统也可以继续正确工作。

B1节点替代了B节点,所以Redis集群将会选择B1节点作为新的主节点,集群将会继续正确地提供服务。 当B重新开启后,它就会变成B1的从节点。

不过需要注意,如果节点B和B1同时挂了,Redis集群就无法继续正确地提供服务了。

流程下图所示:

redis cluster 动手实践

网上有很多教程,我最先是按照这个教程(http://blog.51yip.com/nosql/1725.html) 一步步的按照这个教程来,可是在最后启动集群的时候第一台机器的6379端口死活启动不了,这样就没有3台主服务器,就完成不了集群。最后也没找到解决办法。[知道原因了:我把redis-trib.rb create --replicas 1的 这个1没有写!!!!]

现在,还是按照官方的教程,全程再演示一次,官方教程是在一台机器上启动6个节点,3个当主,3个当从(http://redis.io/topics/cluster-tutorial):

下载不了,请自行FQ。我这次是在centos6.5上演示,用的是root 账户。

如果之前已经下载了redis的 2.x版本,只需要将 /usr/local/bin/redis-* 这几个命令先删除即可。

1.解压

[root@web3 ~]# tar zxvf redis-3.0.5.tar.gz

2.安装

[root@web3 ~]# cd redis-3.0.5

[root@web3 ~]# make && make install

3.将redis-trib.rb 复制到/usr/local/bin

[root@web3 redis-3.0.5]# cd src/

[root@web3 src]# cp redis-trib.rb /usr/local/bin

4.开始集群搭建

[root@web3 redis-3.0.5]# vi redis.conf

#修改以下地方

port 7000

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

新建6个节点:

[root@web3 redis-3.0.5]# mkdir -p /usr/local/cluster-test

[root@web3 redis-3.0.5]# cd /usr/local/cluster-test/

[root@web3 cluster-test]# mkdir 7000

[root@web3 cluster-test]# mkdir 7001

[root@web3 cluster-test]# mkdir 7002

[root@web3 cluster-test]# mkdir 7003

[root@web3 cluster-test]# mkdir 7004

[root@web3 cluster-test]# mkdir 7005

将redis.conf 分别拷贝到这6个文件夹中,并修改成对应的端口号

#拷贝配置文件

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7000

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7001

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7002

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7003

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7004

[root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7005

#修改端口号

root@web3 cluster-test]# sed -i "s/7000/7001/g" /usr/local/cluster-test/7001/redis.conf

[root@web3 cluster-test]# sed -i "s/7000/7002/g" /usr/local/cluster-test/7002/redis.conf

[root@web3 cluster-test]# sed -i "s/7000/7003/g" /usr/local/cluster-test/7003/redis.conf

[root@web3 cluster-test]# sed -i "s/7000/7004/g" /usr/local/cluster-test/7004/redis.conf

[root@web3 cluster-test]# sed -i "s/7000/7005/g" /usr/local/cluster-test/7005/redis.conf

分别,启动这6个节点

[root@web3 cluster-test]# cd /usr/local/cluster-test/7000/

[root@web3 7000]# redis-server redis.conf

[root@web3 7000]# cd ../7001

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

[root@web3 7001]# cd ../7002

[root@web3 7002]# redis-server redis.conf

[root@web3 7002]# cd ../7003

[root@web3 7003]# redis-server redis.conf

[root@web3 7003]# cd ../7004

[root@web3 7004]# redis-server redis.conf

[root@web3 7004]# cd ../7005

[root@web3 7005]# redis-server redis.conf

[root@web3 7005]#

查看6个节点的启动进程情况:

[root@web3 7005]# ps -ef|grep redis

root 11380 1 0 07:37 ? 00:00:00 redis-server *:7000 [cluster]

root 11384 1 0 07:37 ? 00:00:00 redis-server *:7001 [cluster]

root 11388 1 0 07:37 ? 00:00:00 redis-server *:7002 [cluster]

root 11392 1 0 07:37 ? 00:00:00 redis-server *:7003 [cluster]

root 11396 1 0 07:37 ? 00:00:00 redis-server *:7004 [cluster]

root 11400 1 0 07:37 ? 00:00:00 redis-server *:7005 [cluster]

root 11404 8259 0 07:38 pts/0 00:00:00 grep redis

将6个节点连在一起构招成集群

需要用到的命令就是redis-trib.rb,这是官方的一个用ruby写的一个操作redis cluster的命令,所以,你的机器上需要安装ruby。我们先试一下这个命令:

redis-trib.rb create --replicas 1 127.0.0.1:7000 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

因为我们要新建集群, 所以这里使用create命令. --replicas 1 参数表示为每个主节点创建一个从节点. 其他参数是实例的地址集合。

由于我机子上没安装ruby,所以,会报错:

/usr/bin/env: ruby: No such file or directory

那先安装ruby和rubygems:

[root@web3 7005]# yum install ruby ruby-devel rubygems rpm-build

然后,再执行一次,发现还是报错:

[root@web3 7005]# redis-trib.rb create --replicas 1 127.0.0.1:7000 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

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)

from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'

from /usr/local/bin/redis-trib.rb:25

[root@web3 7005]#

原来是ruby和redis的连接没安装好:

[root@web3 7005]# gem install redis

Successfully installed redis-3.2.1

1 gem installed

Installing ri documentation for redis-3.2.1...

Installing RDoc documentation for redis-3.2.1...

好了。最重要的时刻来临了,胜败成举在此了,啊啊啊啊啊啊,好激动:

[root@web3 7005]# redis-trib.rb create --replicas 1 127.0.0.1:7000 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

>>> Creating cluster

Connecting to node 127.0.0.1:7000: OK

Connecting to node 127.0.0.1:7001: OK

Connecting to node 127.0.0.1:7002: OK

Connecting to node 127.0.0.1:7003: OK

Connecting to node 127.0.0.1:7004: OK

Connecting to node 127.0.0.1:7005: OK

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

127.0.0.1:7000

127.0.0.1:7001

127.0.0.1:7002

Adding replica 127.0.0.1:7003 to 127.0.0.1:7000

Adding replica 127.0.0.1:7004 to 127.0.0.1:7001

Adding replica 127.0.0.1:7005 to 127.0.0.1:7002

M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000

slots:0-5460 (5461 slots) master

M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001

slots:5461-10922 (5462 slots) master

M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002

slots:10923-16383 (5461 slots) master

S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003

replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4

S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004

replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c

S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005

replicates dfa0754c7854a874a6ebd2613b86140ad97701fc

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 127.0.0.1:7000)

M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000

slots:0-5460 (5461 slots) master

M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001

slots:5461-10922 (5462 slots) master

M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002

slots:10923-16383 (5461 slots) master

M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003

slots: (0 slots) master

replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4

M: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004

slots: (0 slots) master

replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c

M: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005

slots: (0 slots) master

replicates dfa0754c7854a874a6ebd2613b86140ad97701fc

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。终于他妈的成功了!!!!

Redis-trib会提示你做了什么配置, 输入yes接受. 集群就被配置和加入了, 意思是, 实例会经过互相交流后启动。

测试集群的状态:

[root@web3 7000]# redis-trib.rb check 127.0.0.1:7000

Connecting to node 127.0.0.1:7000: OK

Connecting to node 127.0.0.1:7002: OK

Connecting to node 127.0.0.1:7003: OK

Connecting to node 127.0.0.1:7005: OK

Connecting to node 127.0.0.1:7001: OK

Connecting to node 127.0.0.1:7004: OK

>>> Performing Cluster Check (using node 127.0.0.1:7000)

M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000

slots:0-5460 (5461 slots) master

1 additional replica(s)

M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002

slots:10923-16383 (5461 slots) master

1 additional replica(s)

S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003

slots: (0 slots) slave

replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4

S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005

slots: (0 slots) slave

replicates dfa0754c7854a874a6ebd2613b86140ad97701fc

M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001

slots:5461-10922 (5462 slots) master

1 additional replica(s)

S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004

slots: (0 slots) slave

replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值