reids笔记4 集群
主从机制
基本原理
CAP原理:
- Consistent:一致性
- Availability:可用性
- Partition tolerance:分区容忍性
网络分区:分布式节点网络断开的场景。
CAP基本原理是:当网络分区发生时,不能同时保证一致性和可用性。
redis支持主从同步和从从同步:
redis的主从数据是异步的,分布式的redis不满足一致性;主从网络断开的时候,主节点仍然可以提供服务,因此满足可用性。redis满足最终一致性,从节点会努力追赶主节点,最终两者状态一致。
同步机制
增量同步:
- 主节点有一个环形队列,用于存储改变内存状态的值
- 主节点会在队列中不断写入改变自己状态的指令
- 指令不断发送给从节点进行同步
注意:如果写入速度超过读取速度,则环形队列值会被新的数据覆盖
快照同步:
- 主节点进行
bgsave
,输出存储到磁盘 - 发送快照到对应的从节点
- 从节点继续经过增量同步来同步数据
这种方式比较常用,新节点加入redis集群时,也是全量加载一次,然后增量加载数据
增量和快照同步时,数据都经过磁盘了
无盘复制:直接遍历内存数据,然后发送给从节点,速度快但是精度太差。
快照同步会影响正在进行AOF的fsync
操作,发生快照同步会推迟fsync
的过程,影响主节点的效率。
wait
指令会让redis的异步复制变成同步复制,但是阻塞服务,而且如果网络分区,则redis节点将永远阻塞。
哨兵机制
问题背景
主从机制的缺陷:
- 主从集群依赖master的活性,如果master崩溃,则从节点无法同步数据
- 集群没有选举机制,master崩溃后,无法确定新的主节点
问题的本质原因:缺少master奔溃后的选举很同步机制
解决方案:基本思路是,引入哨兵观测master健康状态,如果检测到master崩溃,则确认新的master,并使用新的master同步集群数据。
注意,哨兵是配置提供者,而不是代理
引入哨兵后客户端处理方式:
- 遍历哨兵集群,选择一个可用哨兵服务器。哨兵服务器数据是共享同步的
- 客户端从哨兵获取redis集群的master的地址,之后与master直接通信
- 客户端连接不上master后,主动请求哨兵,获取新的地址
- master其它原因出故障,但是客户端可以与master通信时;哨兵会主动通知客户端更换
详细解决方案:
定时监控是解决问题的核心。基本步骤如下:
- 每隔10s,向主节点发送
info
命令,获取集群的拓扑结构。不需要知道从节点的地址,主节点会把信息都发来。主节点故障时,利用之前的info的信息,从从节点中选择一个获取集群信息。 - 哨兵节点订阅
__sentinel__:hello
频道,获取其它哨兵对集群节点的判断,也获取其它哨兵信息;同时也发送自己对集群节点的判断。 - 每隔1s,哨兵向主节点、从节点和其它哨兵节点做心跳检测
- 对某个节点,如果最后一次收到的回复的时间超过配置的时间,则判定为主观下线;如果master在客观下线之前回复了消息,则恢复正常状态。
- 足够多的哨兵认为master下线后,则master为客观下线。
- master客观下线后,哨兵集群选出哨兵的master,让哨兵master在redis的slave节点选出主节点,然后指定其它节点向该节点复制信息。
参考资料:
- https://zhuanlan.zhihu.com/p/44474652
- https://juejin.im/post/5c1b482d6fb9a049dd803f55
- https://hellokangning.github.io/zh/post/redis-sentinel-client-connection/
min-slaves-to-write 1 # 至少有一个从节点在写,否则停止服务
min-slaves-max-lag 10 # 10s内没有收到从节点的反馈,则认为是异常,配合上面那个
Redis Cluster 集群
Redis Cluster把所有的数据分为16384个槽位,槽位的信息存储在每个节点中,不需要其它的分布式存储空间空间来存储节点。
客户端请求redis集群的两种方式:
- 简单方式,直接把请求Key发送到连接的任一个客户端上。如果key命中了则进行读写,否则该服务器会回发MOVE指令和对应的服务器地址x,此时对x服务器操作
- Smart客户端:保留服务器的映射表,然后客户端自己计算对应的服务器地址,并发送。可以定时更新表,也可以当请求失败时更新。
redis的slot和服务的映射关系:
16384个槽有自己对应的映射关系,然后迁移的时候,只需要移动对应槽中的数据即可。使用slot=CRC16(key)/16384
来计算对应的key
属于哪个槽:
redis-trib是redis的迁移工具,迁移单位是槽,迁移的槽处于中间过渡状态。
单个key的迁移过程:
- 对当前key执行dump指令序列化
- 通过“客户端”向目标节点发送数据
- restore指令携带序列化的内容作为参数
- 目标节点反序列化参数
- 目标节点返回“客户端”OK内容
- 当前节点删除key,完成迁移
迁移的过程是同步的,执行restore指令到删除key的时候,主线程是阻塞的。如果迁移过程中出现故障,则下次重新连接工具时,会自动迁移。
集群环境下,避免产生大key,否则迁移会发生阻塞,影响线上服务。
迁移过程中,客户端访问流程:
- 先访问旧节点,数据存在则直接返回
- 旧节点数据不在,两种可能:
- 数据在新节点
- 数据根本不存在
对于第二种情况,旧节点返回一个-ASK targetNoodeAddr
的重定向指令,客户端收到该指令后,去目标节点执行一个不带参数的ASKING
指令,然后再在目标节点执行原来的查询指令。
迁移没完成的时候,新节点无法管理有关的key
,如果此时直接发送查询指令,新节点不认可该指令,会向客户端发送-MOVE
指令,让客户端再去源节点查询,如此会形成重定向循环。ASKING
指令是告诉目标节点,必须执行下面的指令。因此迁移影响效率,原来只需要一个ttl,现在需要3个ttl了。
Redis Cluster提供了cluster-node-timeout
,表示节点持续对应的时间失联时,才认定节点出现故障,并进行主从切换,如果没有该参数,则网络抖动可能引起主从频繁切换。
Redis Cluster是去中心化的,不支持事务,mget
等命令会慢,因为这是拆分到多个集群执行的。rename
等方法也不是原子的,会从源节点转移到目标节点。
槽位变化感知:
MOVED
指令修正槽位,如果客户端请求的数据不在当前节点,则当前节点返回给客户端MOVE
指令,并带有目标节点的地址,此时客户端会刷新自己的映射表。
ASKING
指令临时修正槽位,发生再迁移时候,返回给客户端asking error
。上面提到了,客户端不会刷新映射表。
2次重试:收到MOVED
指令,去新节点时,新节点正在迁移,返回给客户端ASKING
的命令了。一般有多次重试的限制次数,超过抛出异常。
集群变更感知:
- 目标节点挂掉,客户端抛出
ConnectionError
,立刻随机挑选一个节点重试,重试的节点通过MOVED
指令通知槽位被分配到了新的节点地址。 - 运维手动更改集群信息,主节点切换到其它节点,并把旧的节点移除出集群。在旧节点的指令会获取
ClusterDown
错误,并通知不可用。客户端关闭所有的连接,清空映射表,向上层报错。下一条指令来时,会重新初始化信息。
集群的高可用性
集群中的每个节点,增加至少一个slave节点作为备份。当某个节点的master不可用时,添加对应的slave作为master节点即可。
参考文档
- https://www.javazhiyin.com/22957.html
- https://www.infoq.cn/article/sIRPs21lbMvDAJtqQRJE
- https://zhuanlan.zhihu.com/p/72056688
- https://medium.com/@pubuduboteju95/deep-dive-into-redis-clustering-1d71484578a9 (推荐)
总结
- redis主从:主从是为了备份数据,意外情况下可快速恢复
- redis哨兵:为了保证集群的可用性
- redis集群:解决单机容量不够的问题
reids笔记4 集群相关推荐
- [异常笔记] zookeeper集群启动异常: Cannot open channel to 2 at election address ……
[异常笔记] zookeeper集群启动异常: Cannot open channel to 2 at election address -- 参考文章: (1)[异常笔记] zookeeper集群启 ...
- 大数据工程师工作笔记之集群节点准备
序 大数据工程师工作笔记系列分享 2020,成为更好的自己 01 Linux 系统网络配置 在公司中,一般来说,大数据集群是不能上网的,这就需要一个跳板机,将需要的组件传到大数据集群中离线安装就可以了 ...
- Docker部署笔记--Redis集群主从容错切换迁移
笔记记录两个场景: 1:数据读写存储 a:一个新key数据来了,是否会按照预设的进入槽中?集群是否生效 2:容错切换迁移 a:如果master 6381挂了.那么对应的从6384是否会补位? 数据读写 ...
- 数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)
目录 集群 集群配置 单节点集群 分布式集群 故障转移 水平扩容 路由计算&分片控制 数据CRUD流程 写流程 读流程 更新流程 删除流程 分词器 IK分词器 Pinyin分词器 简繁体转换器 ...
- k8s学习笔记一集群部署
k8s安装笔记 基础环境配置 修改主机名: 修改hosts配置文件 安装依赖包 关闭防火墙并未Iptables设置空规则 关闭swap分区和linux虚拟内存 调整内核参数 调整系统时区 关闭系统不需 ...
- LIGGGHTS笔记1——集群Centos安装编译,CFDEM耦合OpenFOAM
1.什么是LIGGGHTS LIGGGHTS是一款开源DEM颗粒模拟软件,其基础是LAMMPS(一款分子动力学模拟软件).目前有两个版本,PUBLIC版本是为研究者们提供使用,而PREMIUM版本是提 ...
- Redis学习笔记:集群
这是本人学习的总结,主要学习资料如下 B站狂神说,redis教程 马士兵教育 目录 1.集群前置知识 1.1.数据分区策略 1.1.1.哈希节点取余分区 1.1.2.一致性哈希分区 1.1.3.虚拟一 ...
- OpenSIPS学习笔记-cluster集群模块配置-dialog集群配置
本章节中,笔者将进一步介绍关于OpenSIPS集群支持的另外一种常见的场景-dialog的集群.dialog集群是OpenSIPS在高并发环境中一定需要考虑的配置功能.通过集群部署方式,可以保证呼叫中 ...
- redis 学习笔记——redis集群
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
最新文章
- 无法连接虚拟设备 ide1:0
- 同步(Synchronization)和异步(Asynchronous)
- [剑指offer][JAVA]面试题第[07]题[重建二叉树][递归]
- vue指令和特殊特性
- Laravel debug bar 调试利器
- Spring事件监听机制
- 模仿LordPE写了个PE解析工具
- 《RFID技术与应用》试题库(含答案)
- 文件后缀名批量修改工具
- IDEA同一个项目启动多个端口
- 本地IP地址使用域名访问
- 几个炫酷且实用的CSS动画效果
- 银保监机构保险许可证数据(2007-2022年)
- 关闭谷歌google右侧百度热搜(下方无偿链接),亲测有效
- 【spring Cloud 入门-4】简单的服务实例健康自检
- GitLab 小白入手教程
- 软件测试作业进度-2
- mp4格式怎么转换成gif格式?简单3步完成视频制作gif
- Vue 实现锚点定位
- 零基础学C++——黑马程序员课程笔记(C++核心编程篇)