一、redis为什么需要实现分布式
redis作为高速存取的内存数据库,有效地解决了关系型数据库读写慢的问题。但随着数据量越来越大,单机的redis已经不能满足内存、并发、流量的要求,造成使用时的瓶颈。Redis Cluster作为Redis的分布式解决方案应运而生。
Redis Cluster有效地解决了以上的问题,它把整个数据集按照哈希分区规则以虚拟槽的形式将数据集映射到多个节点,把数据集划分到多个节点上,每个节点负责整体数据的一个子集,从而实现负载均衡。
二、Redis Cluster的数据分区
Redis Cluser采用虚拟槽分区,将所有的键根据哈希函数映射到0~16383整数槽内,每一个节点负责维护一部分槽及其所映射的键值数据。
Redis虚拟槽分区的特点: ·
解耦数据与节点之间的关系,简化了节点扩容和收缩的难度。 ·
节点自身维护槽的映射关系,不需要客户端或代理服务维护槽分区元数据。 ·
支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。
集群相对于单机功能的限制:
1.key批量操作支持有限 只支持具有相同slot值的key执行批量操作
2.key事务操作支持有限 只支持多key在同一节点上的事务操作
3.key作为数据分区的最小粒度,大的键值对象如hash、list等不能映射到不同的节点。
4.不支持多数据库空间,只能使用db0
5.复制结构只支持一层,从节点只能复制主节点不支持嵌套 。当设置一个从节点复制另一个从节点时会报如下错误:
三、集群的搭建
redis集群的搭建分为如下3步:
1.准备节点相关配置信息并启动。
2.节点握手,加入集群。
3.分配槽
为了熟悉这3步,先手动搭建一个集群。
<一>、手动搭建集群
搭建一个最简单的6节点3主3从集群,集群结构类似如下:
1.准备集群相关配置并启动
(1)新建一个配置文件目录,将默认配置文件redis.conf移入
(2)修改移入的配置文件redis.conf,去掉集群相关配置项的注释。
cluster-enabled yes #开启集群模式
cluster-config-file nodes-6379.conf #指定集群内部配置文件,每一个节点都有一个对应的集群配置文件,无需手动配置
cluster-node-timeout 15000 #节点超时时间
cluster-replica-validity-factor 10 #从节点有效因子,用于判断从节点是否具备故障转移资格。
将该配置复制5份,修改其中的端口信息,得到6份配置文件,如下:
(3).配置准备完成后就可以启动了,启动命令类似如下:
redis-server redis-6379.conf
如果觉得单独启动每一个节点比较麻烦,也可以写一个小脚本批量启动所有节点。脚本内容类似如下:
将所有节点的daemonize配置都修改为yes,让节点以守护进程方式启动。
find ./ -type f -name "redis*.conf" |xargs sed -i "136 s/no/yes/g"
执行脚本,启动所有节点,如下:
查看节点进程是否启动成功:
如果想停止所有节点服务,可以使用如下命令:
pgrep -f redis-server |sudo xargs kill -9
2.节点握手
在任意客户端发起cluster meet命令将某个节点加入集群中,异步握手通信,握手状态通过消息在集群中传播,其他节点自动发现新节点并发起握手流程。
可以执行cluster nodes命令查看节点是否彼此感知并组成了集群如下:
继续执行 cluster meet命令将6个节点都加入到集群:
3.为节点分配槽
新创建的集群还无法正常工作,处于下线状态,不能进行数据的读写。
使用cluster info命令可以查看节点当前的状态信息,如下:
执行读写操作报错,提示集群处于下线状态需要分配槽。
可以通过cluster addslots命令为节点分配槽,如下:
redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0..5461}
槽的分配必须覆盖所有16384个槽,再次进入客户端窗口查看 :
使用cluster info命令可以查看节点当前的状态为OK,即集群已经可以提供服务了,如下:
但此时的集群一旦有一个节点出现问题,整个集群就会下线,缺少高可用性。下面使用cluster replicate命令为每个分配了槽的节点都添加一个从节点。
该命令的参数为主节点id,执行以上操作后就搭建成了一个3主3从的Redis Cluster集群。
尝试在集群里存取数据,看看是否能正常工作:
可以看到,存取数据时,如果映射的slot不在当前客户端对应节点,将会重定向到持有该slot的节点执行。某个键会映射到哪个槽可以通过cluster keyslot命令查看,如下:
需要注意,只有连接客户端时加上-c选项才会自动进行重定向执行命令,否则会报moved重定向错误。
至此,一个简单的集群搭建完成。
可以看到,手动搭建一个集群还是比较复杂的。redis提供了集群管理工具,可以很方便地搭建集群。在5.0之前使用redis-trib.rb工具搭建集群,该工具是使用Ruby编写,需要安装Ruby依赖。5.0之后可以使用redis-cli命令即可搭建一个集群,方便又快捷。
<二>、redis-cli命令搭建集群
搭建类似上面集群的redis-cli命令如下:
redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 \
127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 \
--cluster-replicas 1
其中--cluster create选项表示创建一个集群,"\"表示换行,可忽略,--cluster-replicas选项表示主节点下从节点个数。
启动需要的节点后,执行以上命令,即可自动实现节点握手、槽分配、从节点分配等操作,成功搭建一个集群,其中主节点按照参数顺序设定,从节点随机指派给主节点,如下:
从任意客户端进行查看节点情况:
查看集群是否正常:
存取数据:
可以正常存取数据,集群搭建完毕。