前言
Redis是我们常用的非关系型数据库,但当数据量过大时,一台服务是肯定不够的,这个时候我们就要考虑分布式集群来进行分流。
一、分布式的算法有哪些?
1.哈希取余分区
介绍:假设有三台Redis服务,那么分配规则为Hash(key)/3计算出哈希值来决定分配到哪个机器上面。
优点:简单粗暴,每个节点固定负责一部分数据实现负载分流
缺点:一旦某个节点宕机,Hash(key)/3将变成Hash(key)/?,那么天下大乱,数据取余计算将重新洗牌
2.一致性哈希环
介绍:一致性哈希算法将整个哈希值空间组成一个虚拟的圆环,例如0-2^32-1,0的左侧是2^32-1,他们在零点的位置重合,形成了一个Hash圆环。第一种算法是对节点数量进行取余,而一致性哈希是对2^32取余,计算节点的IP或关键字来将节点落在圆环指定的点上。当set数据进入时,通过Hash(key)计算落入到了圆环上,顺时针向前找,第一个遇到的节点就是存储这个数据的节点。
优点:当某个节点宕机或者新增节点时,由于数据存储是顺时针向前找,所以只会影响下一个节点数据,不会使全部数据进行洗牌。
缺点:当节点的数量太少时,会造成数据的倾斜问题。
3.哈希槽分区(Redis集群所采用的方式)
介绍:哈希槽实质上就是一个数组,由0-2^14-1形成的hash slot空间,哈希槽的出现就是为了解决一致性哈希的数据倾斜问题。一个集群有固定16384个槽位,这些槽位会分配给集群中所有的master节点,每个master节点分配多少槽位可以自由设置,数据会根据已经分配好的槽位进入不同的节点当中。
题外话:为啥一个Redis集群是16384个槽位?
一、开始部署Redis集群
1.安装Redis
我采用的是docker安装(示例):
docker run 创建并运行docker容器实例
--name redis-node-1 容器名称
--net host 使用宿主机的IP和端口,默认
--privileged=true 获取宿主机root用户权限
-v /www/redis-colone/redis-node-1:/data 容器卷,宿主机地址:docker内部地址
redis镜像名称
--cluster-enabled yes 开启redis集群
--appendonly yes 开启持久化
--port 6381 redis开放的端口号
//创建多少redsi容器就执行多少次命令,记得更改容器名称、宿主机容器卷地址、开放端口号
docker run -d --name redis-node-1 --net host --privileged=true -v /www/redis-colone/redis-node-1:/data redis --cluster-enabled yes --appendonly yes --port 6381
2.构建主从关系
1.进入一个容器内部
docker exec -it redis-node-1 bash
2.执行命令(--cluster-replicas 1表示为每个master节点创建一个slave节点)
redis-cli --cluster create 192.168.107.128:6381 192.168.107.128:6382 192.168.107.128:6383 192.168.107.128:6384 192.168.107.128:6385 192.168.107.128:6386 --cluster-replicas 1
3.输入yes进入下一步,看到以下内容,表示哈希槽已分配,主从构建完成
4.查看集群状态:命令cluster nodes
5.查看集群节点数据统计redis-cli --cluster check master节点IP地址:端口号
3.节点宕机时主从关系的变更
当master宕机时,slave节点自动升级为master节点,当原master节点恢复时自动变更为slave节点,若还是想将原master节点的地位不变,则可以手动停止新master节点然后再启动。
4.集群节点的连接
单台redis的链接方式和集群的链接方式
单台:redis-cli
集群:redis-cli -p 6381 -c #6381是节点端口,不传默认是6379
二、Redis的扩容
扩容流程:先将新master节点加入到集群中,分配槽位给新master节点,将新slave节点挂载到新master节点当中
1.将新master节点加入集群中
#192.168.107.128:6387新master节点
#192.168.107.128:6381原集群master节点
redis-cli --cluster add-node 192.168.107.128:6387 192.168.107.128:6381使用命令我们可以看到目前6387已经加入到了集群当中,但没有数据、槽位和slave节点
2.分配槽位
命令redis-cli --cluster reshard 192.168.107.128:6381(原master节点中的某一个节点)
这里会问你想 分配多少个槽位过去,取值是1-16384,这里我输入的是4096,采取的是16384/4,4台master平均分
你会把槽位分配给哪个节点ID,输入6387节点的ID
它会询问你要从那个源节点中进行转移,输入
all
命令表示从所有节点中随机抽取可以看到槽位已分配完成
3.将6388挂载到6387的从节点
输入命令
redis-cli --cluster add-node 192.168.107.128:6388 192.168.107.128:6387 --cluster-slave --cluster-master-id 7b61e99cfbb0f39b9daacbb249368d46b9e84e41(6387节点ID,视自身情况而定)
可以看到6387上已经存在6388这个从节点了。
三、Redis集群缩容
缩容流程:先将新master节点加入到集群中,分配槽位给新master节点,将新slave节点挂载到新master节点当中
1.删除6388从节点
删除集群中的指定ID的节点
redis-cli --cluster del-node 192.168.107.128:6388 822b90d5aead7685cb0500975ccebb581a5f0369
2.清出6387节点的槽号,重新分配
重新分配槽号
执行 redis-cli --cluster reshard 192.168.107.128:6381
3.删除6387主节点
删除节点6387
redis-cli --cluster del-node 192.168.107.128:6387 7b61e99cfbb0f39b9daacbb249368d46b9e84e41
缩容完成