redis cluster

Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有 节点连接。其redis-cluster架构图如下:

其结构特点:
1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2、节点的fail是通过集群中超过半数的节点检测失效时才生效。
3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。

数据分布理论
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。常见的分区规则有哈希分区和顺序分区。Redis Cluster采用哈希分区规则,因此接下来会讨论哈希分区规则。常见的哈希分区有以下几种:
1、节点取余分区
2、一致性哈希分区
3、虚拟槽分区

Redis Cluster采用虚拟槽分区,因此先介绍一下虚拟槽分区。
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。比如Redis Cluster槽的范围是0 ~ 16383。槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,每个节点负责一定数量的槽。

Redis 数据分区
Redis Cluster采用虚拟槽分区,所有的键根据哈希函数映射到0 ~ 16383,计算公式:slot = CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。

Redis虚拟槽分区的特定:
1、解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
2、节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。
3、支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。

Redis集群相对单机在功能上有一定限制:
1、key批量操作支持有限。如:MSET“MGET,目前只支持具有相同slot值的key执行批量操作。
2、key事务操作支持有限。支持多key在同一节点上的事务操作,不支持分布在多个节点的事务功能。
3、key作为数据分区的最小粒度,因此不能将一个大的键值对象映射到不同的节点。如:hash、list。
4、不支持多数据库空间。单机下Redis支持16个数据库,集群模式下只能使用一个数据库空间,即db 0。
5、复制结构只支持一层,不支持嵌套树状复制结构。

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

Redis Cluster的搭建
环境介绍:
A机器:10.0.0.1
redis1服务端口6379
redis2服务端口6380
redis3服务端口6381
B机器:10.0.0.2
redis1服务端口6379
redis2服务端口6380
redis3服务端口6381

1、在所有机器内的redis服务配置文件内增加以下配置:
cluster-enabled yes
cluster-config-file /home/admin/redis_6379/nodes_6379.conf #此配置根据相应redis服务的端口号配置,比如redis配置的端口是6380,即此处配置为cluster-config-file /home/admin/redis_6380/nodes_6380.conf
cluster-node-timeout 15000

2、安装redis-trib所需的 ruby脚本
复制redis解压文件src下的redis-trib.rb文件到redis-cluster目录
#cp /data/soft/redis/redis-3.2.4/src/redis-trib.rb ./

安装ruby环境:
#yum install ruby rubygems -y
# gem install redis-3.2.4.gem

3、使用redis-trib.rb命令创建集群
#redis-trib.rb create –replicas 1 10.0.0.1:6379 10.0.0.1:6380 10.0.0.1:6381 10.0.0.2:6379 10.0.0.2:6380 10.0.0.8:6381
##使用create命令 –replicas 1 参数表示为每个主节点创建一个从节点,其他参数是实例的地址集合。

到此redis cluster配置就已经完成了,可以使用命令测试服务了;

4、增加节点命令:
增加主节点:
#redis-trib.rb add-node 10.0.0.1:6382 10.0.0.1:6379
## add-node是加入集群节点,10.0.0.1:6382为要加入的节点,10.0.0.1:6379表示加入的集群的一个节点,用来辨识是哪个集群,理论上那个集群的节点都可以。

#redis-trib.rb check 10.0.0.1:6382
#查看节点情况

增加从节点:
#redis-trib.rb add-node –slave –master-id $[node-id] 10.0.0.1:6383 10.0.0.1:6379
##nodeid为要加到master主节点的node id,10.0.0.1:6383为新增的从节点,10.0.0.1:6379为集群的一个节点(集群的任意节点都行),用来辨识是哪个集群;如果没有给定那个主节点–master-id的话,redis-trib将会将新增的从节点随机到从节点较少的主节点上。node-id可以从cluster nodes中获得;
#redis-trib.rb check 10.0.0.1:6383

5、移除节点命令:
移除主节点命令:
#redis-trib del-node 10.0.0.1:6382 ${node-id}
##10.0.0.1:6382位集群节点,node-id为要删除的主节点。 和添加节点不同,移除节点node-id是必需的;
#在移除主节点时,会设计到slot的操作,这里不在说明;

移除从节点命令:
#redis-trib.rb del-node 10.0.0.1:6381 ${node-id}
#移除10.0.0.1:6381节点内的${node-id}从节点

注:
常见报错:[ERR] Node 10.0.0.1:6379 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决方法:
1)、将需要新增的节点下aof、rdb等本地备份文件删除;
2)、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;
3)、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行清除:10.0.0.1:6379:7001> flushdb #清空当前数据库

参考文章:
https://www.cnblogs.com/lykxqhh/p/5690923.html
https://blog.csdn.net/men_wen/article/details/72853078
https://blog.csdn.net/vtopqx/article/details/50235737

发表评论