为什么?
从单体的redis到高可用的master-slaver结构,不过这都是redis的单体,并不能称之为分布式。这样的redis架构并不能实现水平扩展。
为了加强redis的稳定性,增加灾备和容灾的处理能力,需要对redis进行集群搭建。
结构:
- 多个master对外进行服务。
- 每个master都是高可用的master-slaver结构
集群就是对外界提供提一的服务,这些master个自分工(slot槽形式 后面会讲)
集群搭建
注意:集群搭建并不需要配置sentinel的相关东西。
单台的配置内容:
----------------------------------------单机配置---------------------------------------
port 8001 #配置端口号
daemonize yes #后台启动
bind 0.0.0.0 #公网访问
pidfile /var/run/redis_8001.pid #pid设置
logfile "redis-8001.log" #日志文件
dir /usr/local/bin/cluster-redis-conf/8001 #目标位置
requirepass 123456 #设置密码
masterauth 123456 #由于不能确定任意时刻的主从关系 所以都要配置上密码
----------------------------------------注意---------------------------------------------
#集群创建会自动搭建主从关系,所以不要手工配置replicaof
----------------------------------------注意---------------------------------------------
-----------------------------------------集群配置---------------------------------------
cluster-enabled yes # 开启集群配置
cluster-config-file nodes-8001.conf # 集群每个节点都需要的配置文件
cluster-node-timeout 3000 # master超时时间,超过后主备切换
appendonly yes # 开启AOF
-----------------------------------------复制配置---------------------------------------
# 批量修改文件端口
.,$ s/8001/8002/g #将8001 改成 8006
# 整个批处理文件 建立一个脚本就行
chmod 777 cluster.sh
redis-server cluster-redis-conf/8001/redis.conf
redis-server cluster-redis-conf/8002/redis.conf
redis-server cluster-redis-conf/8003/redis.conf
redis-server cluster-redis-conf/8004/redis.conf
redis-server cluster-redis-conf/8005/redis.conf
redis-server cluster-redis-conf/8006/redis.conf
集群配置
# Redis 3.x开始有集群,redis-trib.rb
# Redis 5.x使用redis-cli就可以了
# 集群创建的命令
# --cluster-replicas 1 每个master有几个slave
redis-cli -a 123456 --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
# 查看集群信息
redis-cli -a 123456 --cluster check 127.0.0.1:8001
# 查看集群命令帮助
redis-cli -a 123456 --cluster help
结果为:
通过redis-cli -a 123456 --cluster check 127.0.0.1:8001
查看集群信息
随便看看一个节点的信息进入8004.
这时候我们随便设置一个值,会发现有些值set不进去。如下图:
set只有一些值能放到8001中其他的应该放在其他的节点上。这个和redis集群的槽点分配有关系。
我们这个是单机登录,现在需要使用集群登录。
redis-cli -c -a 123456 -p 8001
槽点
redis集群创建16384个槽点,会根据master的数量平均分配给master。所有的数据都存在槽点中。
数据放入的时候会用crc16(key)mod16384计算,然后对16384取余。将数据划归到对应槽点的节点上。
存:
- 通过对数据的key进行crc16(key)mod16384取16384的余即可。
- 存取的核心就是16384个槽点进行存储,一个不多一个不少。
- 当放不下的时候,只要扩展槽点的大小,不改变槽点的数量,就可以保证位置的唯一性。
取:
- 对key进行crc16mod16384进行计算,得到的值一定是最初存档数据的位置。
- 这个16384不被破话,redis集群就不会失效。
- 每次添加节点,只要分出槽点就可以保证数据一致性。
集群的搭建建议
- 建议是奇数个,至少3个master几点
- 主从切换:节点间会相互通信,一半以上的节点ping不通某个节点,就认为这个master挂了,这个时候从节点顶上
- 什么时候整个集群不可用
- 如果集群中任意master挂掉,且没有slave顶上,集群就进入fail状态
- 如果超半数以上的master挂掉,无论是否有slave,集群都进入fail状态
添加节点与删除节点
添加节点
先准备好要添加节点。(8007 8008节点)
新增节点
#add-node new_host:new_port existing_host:existing_port
# --cluster-slave
# --cluster-master-id <arg>
# 新增主节点 密码 加入节点 要添加的节点 要挂在的位置
redis-cli -a 123456 --cluster add-node 127.0.0.1:8007 127.0.0.1:8001
通过cluster nodes
查看节点信息
加入集群(分配槽点)
# 给8007分配slot
# --cluster-from 从哪个节点来分配slot,这里只能写node_id,就是cluster nodes获得id,from可以是一个节点也可以是多个节点 --cluster-to id 到id上去
#这里是我们制定分配槽点的策略 下面为三个 也就是平均分
redis-cli -a 123456 --cluster reshard 127.0.0.1:8001 --cluster-from ef0576395c13e8b875a1ae8f6730e18f8ed35dd9,a98dac2e6d119d17080437ed606e812da27b1607,d37886e5c5027bf12737259dd97944381d2e0c85 --cluster-to 7a897d87de93a20b6dd372417ae40ef962b1f3bc --cluster-slots 4096 --cluster-yes
# --cluster-to 到8007节点,同样是node_id
# --cluster-slots 从from节点一共分多少slot,并且from中的node是平均分这个总数的 4096/3
# --cluster-yes 不用提示直接执行
分配过程
将8008变成8007的slaver
# 给8007增加8008的slave节点
redis-cli -a 123456 --cluster add-node 127.0.0.1:8008 127.0.0.1:8001 --cluster-slave --cluster-master-id ef0576395c13e8b875a1ae8f6730e18f8ed35dd9
删除节点
首先收回槽点
# 下线节点,现有考虑把slots分给其他节点,这就是在做数据迁移
# 我这一次分配,也可以分批移动给多个节点,我要下架8001/8008
redis-cli -a 123456 --cluster reshard 127.0.0.1:8001 --cluster-from ef0576395c13e8b875a1ae8f6730e18f8ed35dd9 --cluster-to 7a897d87de93a20b6dd372417ae40ef962b1f3bc --cluster-slots 4106 --cluster-yes
# 检查一下8001的slot是否全部转移走
127.0.0.1:8001> cluster nodes
删除节点
# 删除8001节点,这里的节点建议写成删除节点
redis-cli -a 123456 --cluster del-node 127.0.0.1:8001 ef0576395c13e8b875a1ae8f6730e18f8ed35dd9
# 删除8006节点,这里的节点建议写成删除节点
redis-cli -a 123456 --cluster del-node 127.0.0.1:8008 944c91c058e69996836070b68f1513be7265fbad
8001节点删除成功
测试
我们kill掉一个节点测试数据是否可以存储。