前言

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个槽位?

       作者回答 https://github.com/antirez/redis/issues/2576

一、开始部署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进入下一步,看到以下内容,表示哈希槽已分配,主从构建完成

docker配置redis集群 docker搭建redis集群弊端_docker配置redis集群

 4.查看集群状态:命令cluster nodes

docker配置redis集群 docker搭建redis集群弊端_数据库_02

 5.查看集群节点数据统计redis-cli --cluster check master节点IP地址:端口号

docker配置redis集群 docker搭建redis集群弊端_docker_03


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

docker配置redis集群 docker搭建redis集群弊端_数据库_04

 使用命令我们可以看到目前6387已经加入到了集群当中,但没有数据、槽位和slave节点

2.分配槽位

命令redis-cli --cluster reshard 192.168.107.128:6381(原master节点中的某一个节点)

docker配置redis集群 docker搭建redis集群弊端_Redis_05

这里会问你想 分配多少个槽位过去,取值是1-16384,这里我输入的是4096,采取的是16384/4,4台master平均分

docker配置redis集群 docker搭建redis集群弊端_docker配置redis集群_06

 你会把槽位分配给哪个节点ID,输入6387节点的ID

docker配置redis集群 docker搭建redis集群弊端_Redis_07

它会询问你要从那个源节点中进行转移,输入 all 命令表示从所有节点中随机抽取 

docker配置redis集群 docker搭建redis集群弊端_docker_08

可以看到槽位已分配完成 

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,视自身情况而定)

docker配置redis集群 docker搭建redis集群弊端_Redis_09

可以看到6387上已经存在6388这个从节点了。 

三、Redis集群缩容

缩容流程:先将新master节点加入到集群中,分配槽位给新master节点,将新slave节点挂载到新master节点当中

1.删除6388从节点

删除集群中的指定ID的节点

redis-cli --cluster del-node 192.168.107.128:6388 822b90d5aead7685cb0500975ccebb581a5f0369

docker配置redis集群 docker搭建redis集群弊端_redis_10


2.清出6387节点的槽号,重新分配

重新分配槽号

执行 redis-cli --cluster reshard 192.168.107.128:6381

docker配置redis集群 docker搭建redis集群弊端_Redis_11

3.删除6387主节点

删除节点6387

redis-cli --cluster del-node 192.168.107.128:6387 7b61e99cfbb0f39b9daacbb249368d46b9e84e41

docker配置redis集群 docker搭建redis集群弊端_数据库_12

缩容完成