3.0以前的redis需要借助哨兵进行监控redis主节点的状态 如果主节点宕机重新选举主节点时会有几秒甚至十几秒的时间无法访问redis

以上的缺点在redis cluster集群中虽然也存在这个问题但是触发的几率变小了 redis集群是由多个主从节点组合 cluster没有中心节点 它会根据我们的配置 自动选择主节点跟从节点 可以扩展上万个节点 官方推荐不超过1000个节点

搭建集群的配置步骤

第一步:在第一台机器的/usr/local下创建文件夹redis-cluster,然后在其下面分别创建2个文件夾如下
(1)mkdir -p /usr/local/redis-cluster
(2)mkdir 8001 8004

第一步:把之前的redis.conf配置文件copy到8001下,修改如下内容:
(1)daemonize yes
(2)port 8001(分别对每个机器的端口号进行设置)
(3)pidfile /var/run/redis_8001.pid # 把pid进程号写入pidfile配置的文件
(4)dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
(5)cluster-enabled yes(启动集群模式)
(6)cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上)
(7)cluster-node-timeout 10000
(8)# bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)
(9)protected-mode no (关闭保护模式)
(10)appendonly yes
如果要设置密码需要增加如下配置:
(11)requirepass redis(设置redis访问密码)
(12)masterauth redis (设置集群节点间访问密码,跟上面一致)

第三步:把修改后的配置文件,copy到8004,修改第2、3、4、6项里的端口号,可以用批量替换:
:%s/源字符串/目的字符串/g

第四步:另外两台机器也需要做上面几步操作,第二台机器用8002和8005,第三台机器用8003和8006

第五步:分别启动6个redis实例,然后检查是否启动成功
(1)/usr/local/redis-5.0.3/src/redis-server /usr/local/redis-cluster/800*/redis.conf
(2)ps -ef | grep redis 查看是否启动成功

第六步:用redis-cli创建整个redis集群(redis5以前的版本集群是依靠ruby脚本redis-trib.rb实现)
#下面命令里的1代表为每个创建的主服务器节点创建一个从服务器节点
#执行这条命令需要确认三台机器之间的redis实例要能相互访问,可以先简单把所有机器防火墙关掉,如果不关闭防火墙则需要打开redis服务端口和集群节点gossip通信端口16379(默认是在redis端口号上加1W)
#关闭防火墙
#systemctl stop firewalld # 临时关闭防火墙
#systemctl disable firewalld # 禁止开机启动
#注意:下面这条创建集群的命令大家不要直接复制,里面的空格编码可能有问题导致创建集群不成功
(1)/usr/local/redis-5.0.3/src/redis-cli -a redis --cluster create --cluster-replicas 1 192.168.0.61:8001 192.168.0.62:8002 192.168.0.63:8003 192.168.0.61:8004 192.168.0.62:8005 192.168.0.63:8006

第七步:验证集群:
(1)连接任意一个客户端即可:./redis-cli -c -h -p (-a访问服务端密码,-c表示集群模式,指定ip地址和端口号)
如:/usr/local/redis-5.0.3/src/redis-cli -a redis -c -h 192.168.0.61 -p 800*
(2)进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)
(3)进行数据操作验证
(4)关闭集群则需要逐个进行关闭,使用命令:
/usr/local/redis-5.0.3/src/redis-cli -a redis -c -h 192.168.0.60 -p 800* shutdown

redis集群原理

redis cluster将所有数据划分为16384个slots(槽位) 每个主节点负责一部分默认会均匀的分配给每个主节点 也可以手动设置

当我们使用redis的cluster启动集群之后 我们再访问主节点的时候 使用redis命令 比如set命令 它会给我们把key进行运算 运算之后在决定把这个数据放到哪个主节点上就是分到槽位中

槽位的定位算法

CRC16(key) mod 16384

跳转重定位

就是在我们添加数据时 redis会自动给我们跳转到存储数据的主节点上

redis集群中节点的通信
redis cluster节点采取gossip协议进行通信 就是告诉每个节点自己的状态还有各种信息比如主从角色、节点数量等

gossip

当一个节点想要给每个节点发送信息时会先告诉附近的节点 然后附近的节点再告诉它附近的节点
gossip协议包含多种消息 比如ping、pong、meet、fall等

meet:当有一个新节点要加入集群时 集群里的节点会给新节点发送meet消息邀请新节点让它加入进来
   ping:每个节点之间都会频繁的给其他节点发送ping 利用这个消息告诉其他节点自己的一些状态信息和其他信息
   pong:对ping个meet消息的返回 包含自己的状态和其他信息 也可以用于信息广播和更新
   fall:某个节点判断另一个节点宕机了就会发送fall给其他的节点 通知它们这个节点宕机了

gossip更新节点状态信息会有延迟 但是它可以降低压力 因为它是陆陆续续的通知其他的节点

gossip通信的端口

每个节点的端口加上一万

redis集群选举原理

当一个主节点宕机变为fall状态时 它的从节点会发现 然后从节点发送AILOVER_AUTH_REQUEST信息给其他的主节点 当主节点收到这个信息之后就会返回ack 如果多个从节点发送这个信息 哪个主节点只会给第一个发送到这个信息的从节点返回ack 当返回完 从节点会判断它收到的ack是否超过当前集群主节点个数的一半 如果超过了就就广播pong信息通知其它集群中的节点就告诉它们我的ack以及超过了你们不用再返回了 然后这个从节点就会变成主节点 如果多个从节点拿到的ack都是一样的那么会重新选举 还是上面的流程 为了避免这种情况它有一个延迟计算的机制 当发现主节点宕机了并不是直接发送AILOVER_AUTH_REQUEST信息而是通过延迟计算之后再发送

延迟计算公式

500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
•SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举(理论上

redis脑裂问题

主节点因为网络波动 让从节点无法访问 当无法访问超过我们设置的毫秒数之后 会选举新的主节点 选举完了就有两个主节点这两个主节点都可以进行删除局添加数据 这时两边的数据都不一样 网络波动好了因为重新选举了主节点 集群的配置都更新为最新的了 之前的主节点集群就不认识了 那么之前的主节点就会变成新选举的主节点的从节点 变为从节点就会复制数据 复制数据会清空当前的所有数据 这时因为网络波动两个主节点的数据不一样 这样就发生因为脑裂问题造成的数据丢失
可以通过 min-replicas-to-write 1 这个参数配置redis避免脑裂问题 设置了这个参数之后 当我们添加了数据只有当给一个从节点同步过数据了才给客户端返回添加成功 否则就报错 1就表示1个从节点同步成功

设置了这个参数之后 当因为网络波动主节点无法被从节点检测到 那么就表示主节点也无法检测到从节点 当往主节点添加数据时因为配置了要把主节点的数据同步给从节点才能返回成功 很显然当前无法实现同步 所以就会报错那么就能解决脑裂问题丢失数据了 一般不设置这个参数因为redis是用来当缓存的 缓存丢一两个数据没问题 到时候往数据库查就行了 redis目的是为了减少访问数据库的次数

集群是否完整才能对外提供服务
当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,如果为yes则集群不可用。

集群对批量操作命令的支持

mset {user1}:1:name redis {user1}:1:age 18 // 就写一个大括号里面写上一样的值就好了

关于运维方面的操作

查看集群状态 随便连接一个主节点就可以

cluster nodes

redis的–cluster命令

1.create:创建一个集群环境host1:port1 … hostN:portN
2.call:可以执行redis命令
3.add-node:将一个节点添加到集群里,第一个参数为新节点的ip:port,第二个参数为集群中任意一个已经存在的节点的ip:port
4.del-node:移除一个节点
5.reshard:重新分片
6.check:检查集群状态

redis-cli -a aa // -a后面跟着redis的密码

redis cluster架构图

3节点搭建 cluster redis redis cluster集群搭建_redis

gossip示意图

3节点搭建 cluster redis redis cluster集群搭建_3节点搭建 cluster redis_02