Redis集群

来源:互联网 发布:python turtle安装 编辑:程序博客网 时间:2024/05/29 18:36

Redis集群

标签(空格分隔): Redis


为什么要使用集群

在主从复制架构下,每个节点都要保留整份数据,容易形成木桶效应(存储数据的量取决于主数据库的内存大小)。
在之前Jedis实现了分片集群。由客户端控制哪些key数据存储到哪个数据库中(根据hash值算法分配),这个方法在水平扩容,需要将数据手工进行迁移(因为由于水平扩容之后,key值进行hash之后的值可能不同。容易导致读取不到原来的数据。所以需要做手工迁移),而且还需要将整个集群停止服务。这非常不好

架构图

这里写图片描述

(1) 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2) 节点的fail是通过集群中超过半数的节点检测失效时才生效.(某一节点和集群中的超过半数的节点PING-PONG失败之后,认为节点失效)
(3) 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4) redis-cluster把所有的物理节点映射到[0-16383]slot(插槽)上,cluster 负责维护node<->slot<->value

配置集群

1、 设置不同的端口,6379、6380、6381
在同一台机器,需保证不同的端口,如果一个实例在不同的服务器,该步骤可忽略
2、 修改redis.conf 开启集群,修改cluster-enabled

cluster-enabled yes

3、 指定集群的配置文件

cluster-config-file “nodes-xxxx.conf”
—- 这个集群文件不需要创建,redis自动创建。

启动redis-server

[root@node3 6380]# ps -ef | grep redisroot     18282     1  0 03:54 ?        00:00:00 redis-server *:6379 [cluster]  root     18292     1  0 03:54 ?        00:00:00 redis-server *:6380 [cluster]  root     18296     1  1 03:54 ?        00:00:00 redis-server *:6381 [cluster]  root     18300 10741  0 03:54 pts/0    00:00:00 grep redis[root@node3 6380]# 

可以看到,cluster标识。说明配置完成,但是几个节点并没有关联,需要创建集群

创建集群

1、 安装Ruby。
因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境

[root@node3 redis-3.0.2]# yum -y install zlib ruby rubygems[root@node3 redis-3.0.2]# gem install redis

手动安装:

rz上传redis-3.2.1.gem
gem install -l redis-3.2.1.gem

2、 首先进入redis安装目录的src文件夹下
执行命令:

[root@node3 src]# ./redis-trib.rb create –replicas 0 192.168.116.137:6379 192.168.116.137:6380 192.168.116.137:6381

注意: 这里不能使用127.0.0.1,否则在Jedis客户端使用时无法连接到!
执行结果:
这里写图片描述

测试集群

[root@node3 src]# redis-cli127.0.0.1:6379> set abc 123(error) MOVED 7638 192.168.116.137:6380127.0.0.1:6379> 

报错:说abc计算出来的插槽值在6380中,不在6379中.所以应该按照下面方式执行redis-cli -c

[root@node3 src]# redis-cli -c127.0.0.1:6379> set abc 123-> Redirected to slot [7638] located at 192.168.116.137:6380OK192.168.116.137:6380> 

因计算出来的slot在6380中,所以最终调到了 6380客户端中。

取值也是一样的

[root@node3 src]# redis-cli127.0.0.1:6379> keys *(empty list or set)127.0.0.1:6379> get abc(error) MOVED 7638 192.168.116.137:6380127.0.0.1:6379> 

原因同上

[root@node3 src]# redis-cli -c127.0.0.1:6379> keys *(empty list or set)127.0.0.1:6379> get abc-> Redirected to slot [7638] located at 192.168.116.137:6380"123"192.168.116.137:6380> 

插槽

通过cluster nodes命令可以查看当前集群的信息:

192.168.116.137:6380> cluster nodes69a0af5017c0e5adc51de29c9a022530aac886c8 192.168.116.137:6381 master - 0 1512303504163 3 connected 10923-16383ce4cdb447b36cbf5988b6d112ddcb44444bdd689 192.168.116.137:6379 master - 0 1512303503027 1 connected 0-54604256ff7618f82950c6f96a821659456b2de7c16f 192.168.116.137:6380 myself,master - 0 0 2 connected 5461-10922192.168.116.137:6380> 

该信息反映出了集群中的每个节点的id、身份、连接数、插槽数等。

当我们执行set abc 123命令时,redis是如何将数据保存到集群中的呢?执行步骤:

1、 接收命令set abc 123
2、 通过key(abc)计算出插槽值,然后根据插槽值找到对应的节点。(abc的插槽值为:7638)
3、 重定向到该节点执行命令

整个Redis提供了16384个插槽,也就是说集群中的每个节点分得的插槽数总和为16384。
./redis-trib.rb脚本实现了是将16384个插槽平均分配给了N个节点。

注意:如果插槽数有部分是没有指定到节点的,那么这部分插槽所对应的key将不能使用。

插槽和key的关系

计算key的插槽值:
key的有效部分使用CRC16算法计算出哈希值,再将哈希值对16384取余,得到插槽值。

什么是有效部分?
1、 如果key中包含了{符号,且在{符号后存在}符号,并且{和}之间至少有一个字符,则有效部分是指{和}之间的部分;
a) key={hello}_tatao的有效部分是hello
2、 如果不满足上一条情况,整个key都是有效部分;
a) key=hello_taotao的有效部分是全部

新增集群节点

新增一个6382实例

[root@node3 redis]# cp -R 6381 6382[root@node3 6382]# redis-server ./redis.conf [root@node3 6382]# ps -ef | grep redisroot     18282     1  0 03:54 ?        00:00:06 redis-server *:6379 [cluster]  root     18292     1  0 03:54 ?        00:00:06 redis-server *:6380 [cluster]  root     18296     1  0 03:54 ?        00:00:06 redis-server *:6381 [cluster]  root     20585     1  0 04:29 ?        00:00:00 redis-server *:6382 [cluster]root     20591 10741  0 04:29 pts/0    00:00:00 grep redis[root@node3 6382]# 

执行增加节点命令:

[root@node3 src]# ./redis-trib.rb add-node 192.168.116.137:6382 192.168.116.137:6380>>> Adding node 192.168.116.137:6382 to cluster 192.168.116.137:6380Connecting to node 192.168.116.137:6380: OKConnecting to node 192.168.116.137:6381: OKConnecting to node 192.168.116.137:6379: OK>>> Performing Cluster Check (using node 192.168.116.137:6380)M: 4256ff7618f82950c6f96a821659456b2de7c16f 192.168.116.137:6380   slots:5461-10922 (5462 slots) master   0 additional replica(s)M: 69a0af5017c0e5adc51de29c9a022530aac886c8 192.168.116.137:6381   slots:10923-16383 (5461 slots) master   0 additional replica(s)M: ce4cdb447b36cbf5988b6d112ddcb44444bdd689 192.168.116.137:6379   slots:0-5460 (5461 slots) master   0 additional replica(s)[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.Connecting to node 192.168.116.137:6382: OK>>> Send CLUSTER MEET to node 192.168.116.137:6382 to make it join the cluster.[OK] New node added correctly.

查看下集群状态

127.0.0.1:6379> cluster nodes4256ff7618f82950c6f96a821659456b2de7c16f 192.168.116.137:6380 master - 0 1512304444298 2 connected 5461-10922ce4cdb447b36cbf5988b6d112ddcb44444bdd689 192.168.116.137:6379 myself,master - 0 0 1 connected 0-54608112354eecd7e65ef50ab74a43382edfa2757e87 192.168.116.137:6382 master - 0 1512304447379 0 connected69a0af5017c0e5adc51de29c9a022530aac886c8 192.168.116.137:6381 master - 0 1512304446357 3 connected 10923-16383127.0.0.1:6379> 

发现没有插槽数。
接下来需要给6382这个服务分配插槽,将6379的一部分(1000个)插槽分配给6382。

分配插槽:
这里写图片描述

插槽就分配完成了

删除集群节点

想要删除集群节点中的某一个节点,需要严格执行2步:
1、 将这个节点上的所有插槽转移到其他节点上;
a) 假设我们想要删除6380这个节点
b) 执行脚本:./redis-trib.rb reshard 192.168.116.137:6380
c) 选择需要转移的插槽的数量,因为6380有5128个,所以转移5128个
e) 查看集群信息,可以看到6380节点已经没有插槽了。
2、2、 使用redis-trib.rb删除节点
a) ./redis-trib.rb del-node 192.168.116.137:6380 4256ff7618f82950c6f96a821659456b2de7c16f
b) del-node host:port node_id
c) 查看集群信息,可以看到已经没有6380这个节点了。

原创粉丝点击