Redis集群搭建之Redis Cluster实践

来源:互联网 发布:如何理解大数据运用 编辑:程序博客网 时间:2024/04/28 06:49

之前一直有用redis,但也一直停留在用的阶段,自己也单机部署过玩玩,但总感觉不深入,所以现在继续研究研究redis集群,下面就根据自己学习实践,记录下使用Redis官网提供的Redis集群方案;

Redis Cluster背景介绍

Redis Cluster与Redis3.0.0同时发布,以此结束了Redis无官方集群方案的时代,目前,Redis已经发布了3.0.7版本。

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 wind

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

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

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

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

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

redis cluster 动手实践

首先去官方下载Redis,我这里下载的是3.0.5版本。
1.解压

[root@spg redis-claster]# tar -zxvf redis-3.0.5.tar.gz

2.安装

[root@spg redis-claster]#cd redis-3.0.5[root@spg redis-3.0.5]#make && make install

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

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

4.开始集群搭建,首先修改配置文件。

[root@spg redis-3.0.5]#vi redis.conf修改如下几处:port 7000cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000appendonly yes

新建6个节点(注意:Redis Cluster要求至少6个节点,3主3备,否则构建集群会报错):

#这里文件名就按端口号命名,方便区分。[root@spg redis-claster]# mkdir 7000[root@spg redis-claster]# mkdir 7001[root@spg redis-claster]# mkdir 7002[root@spg redis-claster]# mkdir 7003[root@spg redis-claster]# mkdir 7004[root@spg redis-claster]# mkdir 7005

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

[root@spg redis-claster]# cd 7000[root@spg 7000]# redis-server redis.conf &#其他几个启动略...

可通过查看进程查看各redis是否已经正常启动。

[root@spg redis-claster]# ps -ef | grep redisroot      6568  6127  0 21:50 pts/0    00:00:03 redis-server *:7000 [cluster]root      6590  6127  0 21:50 pts/0    00:00:02 redis-server *:7001 [cluster]root      6607  6127  0 21:51 pts/0    00:00:02 redis-server *:7002 [cluster]root      6613  6127  0 21:51 pts/0    00:00:01 redis-server *:7003 [cluster]root      6888  6127  0 22:02 pts/0    00:00:00 redis-server *:7004 [cluster]root      6905  6127  0 22:03 pts/0    00:00:00 redis-server *:7005 [cluster]

接着将6个Redis加入集群。
需要用到的命令就是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,所以,会报错:

[root@spg 7003]# 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/bin/env: ruby: 没有那个文件或目录

通过如下命令安装ruby:

[root@spg 7003]# yum install ruby ruby-devel rubygems rpm-build

完成后继续执行,结果还是报错:

[root@spg 7003]# 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/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- redis (LoadError)    from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'    from /usr/local/bin/redis-trib.rb:25:in `<main>'

这是因为ruby和redis的连接没安装好:

[root@spg 7003]# gem install redisFetching: redis-3.2.2.gem (100%)Successfully installed redis-3.2.2Parsing documentation for redis-3.2.2Installing ri documentation for redis-3.2.21 gem installed

安装完后再创建集群。

[root@spg redis-claster]# 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 clusterConnecting to node 127.0.0.1:7000: OKConnecting to node 127.0.0.1:7001: OKConnecting to node 127.0.0.1:7002: OKConnecting to node 127.0.0.1:7003: OKConnecting to node 127.0.0.1:7004: OKConnecting to node 127.0.0.1:7005: OK>>> Performing hash slots allocation on 6 nodes...Using 3 masters:127.0.0.1:7000127.0.0.1:7001127.0.0.1:7002Adding replica 127.0.0.1:7003 to 127.0.0.1:7000Adding replica 127.0.0.1:7004 to 127.0.0.1:7001Adding replica 127.0.0.1:7005 to 127.0.0.1:7002M: be26c521481afcd6e739e2bfef69e9dcfb63d0a6 127.0.0.1:7000   slots:0-5460 (5461 slots) masterM: ce06b13387702c3ee63e0118dd10c5f81a1285b5 127.0.0.1:7001   slots:5461-10922 (5462 slots) masterM: 947cc4a9e890672cfad4806a5921e9f8bdf05c05 127.0.0.1:7002   slots:10923-16383 (5461 slots) masterS: 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40c 127.0.0.1:7003   replicates be26c521481afcd6e739e2bfef69e9dcfb63d0a6S: 05ac96f9cdee679f98e8f7ce8e97cf1cbea608ca 127.0.0.1:7004   replicates ce06b13387702c3ee63e0118dd10c5f81a1285b5S: b65f33d97416795226964aa22f3b4a8ac7366a99 127.0.0.1:7005   replicates 947cc4a9e890672cfad4806a5921e9f8bdf05c05Can I set the above configuration? (type 'yes' to accept): yes>>> Nodes configuration updated>>> Assign a different config epoch to each node6568:M 27 Feb 22:07:57.661 # configEpoch set to 1 via CLUSTER SET-CONFIG-EPOCH6590:M 27 Feb 22:07:57.661 # configEpoch set to 2 via CLUSTER SET-CONFIG-EPOCH6607:M 27 Feb 22:07:57.662 # configEpoch set to 3 via CLUSTER SET-CONFIG-EPOCH6613:M 27 Feb 22:07:57.663 # configEpoch set to 4 via CLUSTER SET-CONFIG-EPOCH6888:M 27 Feb 22:07:57.664 # configEpoch set to 5 via CLUSTER SET-CONFIG-EPOCH6905:M 27 Feb 22:07:57.664 # configEpoch set to 6 via CLUSTER SET-CONFIG-EPOCH>>> Sending CLUSTER MEET messages to join the cluster6568:M 27 Feb 22:07:57.749 # IP address for this node updated to 127.0.0.16590:M 27 Feb 22:07:57.751 # IP address for this node updated to 127.0.0.16613:M 27 Feb 22:07:57.751 # IP address for this node updated to 127.0.0.16607:M 27 Feb 22:07:57.853 # IP address for this node updated to 127.0.0.16905:M 27 Feb 22:07:57.853 # IP address for this node updated to 127.0.0.16888:M 27 Feb 22:07:57.853 # IP address for this node updated to 127.0.0.1Waiting for the cluster to join....6568:M 27 Feb 22:08:02.646 # Cluster state changed: ok6613:S 27 Feb 22:08:02.720 # Cluster state changed: ok6590:M 27 Feb 22:08:02.722 # Cluster state changed: ok6888:S 27 Feb 22:08:02.723 # Cluster state changed: ok6905:S 27 Feb 22:08:02.724 # Cluster state changed: ok>>> Performing Cluster Check (using node 127.0.0.1:7000)6607:M 27 Feb 22:08:02.747 # Cluster state changed: okM: be26c521481afcd6e739e2bfef69e9dcfb63d0a6 127.0.0.1:7000   slots:0-5460 (5461 slots) masterM: ce06b13387702c3ee63e0118dd10c5f81a1285b5 127.0.0.1:7001   slots:5461-10922 (5462 slots) masterM: 947cc4a9e890672cfad4806a5921e9f8bdf05c05 127.0.0.1:7002   slots:10923-16383 (5461 slots) masterM: 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40c 127.0.0.1:7003   slots: (0 slots) master   replicates be26c521481afcd6e739e2bfef69e9dcfb63d0a6M: 05ac96f9cdee679f98e8f7ce8e97cf1cbea608ca 127.0.0.1:7004   slots: (0 slots) master   replicates ce06b13387702c3ee63e0118dd10c5f81a1285b5M: b65f33d97416795226964aa22f3b4a8ac7366a99 127.0.0.1:7005   slots: (0 slots) master   replicates 947cc4a9e890672cfad4806a5921e9f8bdf05c05[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.

OK,从上面可看出集群已经创建成果,最后再检查集群各节点状态:

[root@spg redis-3.0.5]# redis-trib.rb check 127.0.0.1:7000Connecting to node 127.0.0.1:7000: OKConnecting to node 127.0.0.1:7002: OKConnecting to node 127.0.0.1:7004: OKConnecting to node 127.0.0.1:7005: OKConnecting to node 127.0.0.1:7001: OKConnecting to node 127.0.0.1:7003: OK>>> Performing Cluster Check (using node 127.0.0.1:7000)M: be26c521481afcd6e739e2bfef69e9dcfb63d0a6 127.0.0.1:7000   slots:0-5460 (5461 slots) master   1 additional replica(s)M: 947cc4a9e890672cfad4806a5921e9f8bdf05c05 127.0.0.1:7002   slots:10923-16383 (5461 slots) master   1 additional replica(s)S: 05ac96f9cdee679f98e8f7ce8e97cf1cbea608ca 127.0.0.1:7004   slots: (0 slots) slave   replicates ce06b13387702c3ee63e0118dd10c5f81a1285b5S: b65f33d97416795226964aa22f3b4a8ac7366a99 127.0.0.1:7005   slots: (0 slots) slave   replicates 947cc4a9e890672cfad4806a5921e9f8bdf05c05M: ce06b13387702c3ee63e0118dd10c5f81a1285b5 127.0.0.1:7001   slots:5461-10922 (5462 slots) master   1 additional replica(s)S: 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40c 127.0.0.1:7003   slots: (0 slots) slave   replicates be26c521481afcd6e739e2bfef69e9dcfb63d0a6[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.

从上面结果可看出集群中6个节点均正常,其中有3个主节点,3个从节点。

5.测试集群链接状况
刚才集群搭建成功了。按照redis cluster的特点,它是去中心化,每个节点都是对等的,所以,你连接哪个节点都可以获取和设置数据,我们来试一下。

redis-cli是redis默认的客户端工具,启动时加上`-c`参数,就可以连接到集群。
连接任意一个节点端口:

[root@spg 7006]# redis-cli -c -p 7003127.0.0.1:7003>

设置值:

127.0.0.1:7003> set my_name wind-> Redirected to slot [12803] located at 127.0.0.1:7002OK127.0.0.1:7002> get my_name"wind"

前面说过Redis Cluster值分配规则,所以分配key的时候,它会使用CRC16(‘my_name’)%16384算法,来计算,将这个key 放到哪个节点,这里分配到了12803slot 就分配到了7002(10923-16383)这个节点上。所以有:

Redirected to slot [12803] located at 127.0.0.1:7002

同样,链接其他节点也可获取刚设置的数据,也可以设置其他值测试其key分配。

6.测试集群中某节点宕机情况
上面我们建立来了一个集群。3个主节点[7000-7002]提供数据存储和读取,3个从节点[7003-7005]则是负责把[7000-7002]的数据同步到自己的节点上来,我们来看一下[7003-7005]的appendonly.aof的内容,验证是不是说的这样,我们看7005节点数据:

[root@spg 7005]# vim appendonly.aof *2                                                                                                                                                   $6SELECT$10*3$3set$7my_name$4wind

我们看下,的确是从7000节点上同步过来的数据,7003,7004也是。

下面,我们先来模拟其中一台Master主服务器挂掉的情况,那就7000挂掉吧:

[root@spg 7005]# ps -ef | grep redisroot      3027  2974  0 20:03 pts/0    00:00:04 redis-server *:7000 [cluster]root      3063  2974  0 20:04 pts/0    00:00:03 redis-server *:7001 [cluster]root      3081  2974  0 20:05 pts/0    00:00:03 redis-server *:7002 [cluster]root      3093  2974  0 20:05 pts/0    00:00:03 redis-server *:7003 [cluster]root      3109  2974  0 20:06 pts/0    00:00:02 redis-server *:7004 [cluster]root      3123  2974  0 20:06 pts/0    00:00:02 redis-server *:7005 [cluster]root      3406  2974  0 20:23 pts/0    00:00:00 grep --color=auto redis[root@spg 7005]# kill -9 3027

好,按照前面的理论,7000主节点挂掉了,那么这个时候,7000的从节点只有7003一个,肯定7003就会被选举称Master节点了:

[root@spg 7005]# redis-trib.rb check 127.0.0.1:7001Connecting to node 127.0.0.1:7001: OKConnecting to node 127.0.0.1:7005: OKConnecting to node 127.0.0.1:7002: OKConnecting to node 127.0.0.1:7003: OKConnecting to node 127.0.0.1:7004: OK>>> Performing Cluster Check (using node 127.0.0.1:7001)M: ce06b13387702c3ee63e0118dd10c5f81a1285b5 127.0.0.1:7001   slots:5461-10922 (5462 slots) master   1 additional replica(s)S: b65f33d97416795226964aa22f3b4a8ac7366a99 127.0.0.1:7005   slots: (0 slots) slave   replicates 947cc4a9e890672cfad4806a5921e9f8bdf05c05M: 947cc4a9e890672cfad4806a5921e9f8bdf05c05 127.0.0.1:7002   slots:10923-16383 (5461 slots) master   1 additional replica(s)M: 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40c 127.0.0.1:7003   slots:0-5460 (5461 slots) master   0 additional replica(s)S: 05ac96f9cdee679f98e8f7ce8e97cf1cbea608ca 127.0.0.1:7004   slots: (0 slots) slave   replicates ce06b13387702c3ee63e0118dd10c5f81a1285b5[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.

看了下,上面有了三个M 节点了,果真,7003被选取成了替代7000成为主节点了。如果前面在7000节点上存有数据,此时连接redis,7000节点上数据依然可正常获取,因为数据已经同步到其备机7003上。

OK。我们再来模拟 7000节点重新启动了的情况,那么它还会自动加入到集群中吗?那么,7000这个节点上充当什么角色呢? 我们试一下:

[root@spg 7005]# cd ../7000   [root@spg 7000]# redis-server redis.conf &

启动完成后再验证集群状态,同时查看集群中7000角色

[root@spg 7000]# redis-trib.rb check 127.0.0.1:7000Connecting to node 127.0.0.1:7000: OKConnecting to node 127.0.0.1:7003: OKConnecting to node 127.0.0.1:7002: OKConnecting to node 127.0.0.1:7004: OKConnecting to node 127.0.0.1:7001: OKConnecting to node 127.0.0.1:7005: OK>>> Performing Cluster Check (using node 127.0.0.1:7000)S: be26c521481afcd6e739e2bfef69e9dcfb63d0a6 127.0.0.1:7000   slots: (0 slots) slave   replicates 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40cM: 1da8a7f4c3cd5d7537e90e0ca5f4fb416f41a40c 127.0.0.1:7003   slots:0-5460 (5461 slots) master   1 additional replica(s)M: 947cc4a9e890672cfad4806a5921e9f8bdf05c05 127.0.0.1:7002   slots:10923-16383 (5461 slots) master   1 additional replica(s)S: 05ac96f9cdee679f98e8f7ce8e97cf1cbea608ca 127.0.0.1:7004   slots: (0 slots) slave   replicates ce06b13387702c3ee63e0118dd10c5f81a1285b5M: ce06b13387702c3ee63e0118dd10c5f81a1285b5 127.0.0.1:7001   slots:5461-10922 (5462 slots) master   1 additional replica(s)S: b65f33d97416795226964aa22f3b4a8ac7366a99 127.0.0.1:7005   slots: (0 slots) slave   replicates 947cc4a9e890672cfad4806a5921e9f8bdf05c05[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.

由上面可知7000已经正常,但是作为了7003的备机存在。

总结:至此,基于Redis官网的Redis Cluster解决方案,完成了Redis集群的搭建,过程稍微复杂,但相信熟练起来就会很顺手,后面会继续实践集群中节点的增减情况。

参考:
https://www.zybuluo.com/phper/note/195558
http://redisdoc.com/topic/cluster-tutorial.html

1 0
原创粉丝点击