Redis集群

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 redis
root     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-cli
127.0.0.1:6379> set abc 123
(error) MOVED 7638 192.168.116.137:6380
127.0.0.1:6379> 

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

[root@node3 src]# redis-cli -c
127.0.0.1:6379> set abc 123
-> Redirected to slot [7638] located at 192.168.116.137:6380
OK
192.168.116.137:6380> 

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

取值也是一样的

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

原因同上

[root@node3 src]# redis-cli -c
127.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 nodes
69a0af5017c0e5adc51de29c9a022530aac886c8 192.168.116.137:6381 master - 0 1512303504163 3 connected 10923-16383
ce4cdb447b36cbf5988b6d112ddcb44444bdd689 192.168.116.137:6379 master - 0 1512303503027 1 connected 0-5460
4256ff7618f82950c6f96a821659456b2de7c16f 192.168.116.137:6380 myself,master - 0 0 2 connected 5461-10922
192.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 redis
root     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:6380
Connecting to node 192.168.116.137:6380: OK
Connecting to node 192.168.116.137:6381: OK
Connecting 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 nodes
4256ff7618f82950c6f96a821659456b2de7c16f 192.168.116.137:6380 master - 0 1512304444298 2 connected 5461-10922
ce4cdb447b36cbf5988b6d112ddcb44444bdd689 192.168.116.137:6379 myself,master - 0 0 1 connected 0-5460
8112354eecd7e65ef50ab74a43382edfa2757e87 192.168.116.137:6382 master - 0 1512304447379 0 connected
69a0af5017c0e5adc51de29c9a022530aac886c8 192.168.116.137:6381 master - 0 1512304446357 3 connected 10923-16383
127.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这个节点了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值