主从机制

基本原理

CAP原理:

  • Consistent:一致性
  • Availability:可用性
  • Partition tolerance:分区容忍性

网络分区:分布式节点网络断开的场景。

CAP基本原理是:当网络分区发生时,不能同时保证一致性和可用性。

redis支持主从同步和从从同步:

replicate
replicate
replicate
replicate
master
slave
slave
slave
slave

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的命令了。一般有多次重试的限制次数,超过抛出异常。

集群变更感知:

  1. 目标节点挂掉,客户端抛出ConnectionError,立刻随机挑选一个节点重试,重试的节点通过MOVED指令通知槽位被分配到了新的节点地址。
  2. 运维手动更改集群信息,主节点切换到其它节点,并把旧的节点移除出集群。在旧节点的指令会获取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 集群相关推荐

  1. [异常笔记] zookeeper集群启动异常: Cannot open channel to 2 at election address ……

    [异常笔记] zookeeper集群启动异常: Cannot open channel to 2 at election address -- 参考文章: (1)[异常笔记] zookeeper集群启 ...

  2. 大数据工程师工作笔记之集群节点准备

    序 大数据工程师工作笔记系列分享 2020,成为更好的自己 01 Linux 系统网络配置 在公司中,一般来说,大数据集群是不能上网的,这就需要一个跳板机,将需要的组件传到大数据集群中离线安装就可以了 ...

  3. Docker部署笔记--Redis集群主从容错切换迁移

    笔记记录两个场景: 1:数据读写存储 a:一个新key数据来了,是否会按照预设的进入槽中?集群是否生效 2:容错切换迁移 a:如果master 6381挂了.那么对应的从6384是否会补位? 数据读写 ...

  4. 数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)

    目录 集群 集群配置 单节点集群 分布式集群 故障转移 水平扩容 路由计算&分片控制 数据CRUD流程 写流程 读流程 更新流程 删除流程 分词器 IK分词器 Pinyin分词器 简繁体转换器 ...

  5. k8s学习笔记一集群部署

    k8s安装笔记 基础环境配置 修改主机名: 修改hosts配置文件 安装依赖包 关闭防火墙并未Iptables设置空规则 关闭swap分区和linux虚拟内存 调整内核参数 调整系统时区 关闭系统不需 ...

  6. LIGGGHTS笔记1——集群Centos安装编译,CFDEM耦合OpenFOAM

    1.什么是LIGGGHTS LIGGGHTS是一款开源DEM颗粒模拟软件,其基础是LAMMPS(一款分子动力学模拟软件).目前有两个版本,PUBLIC版本是为研究者们提供使用,而PREMIUM版本是提 ...

  7. Redis学习笔记:集群

    这是本人学习的总结,主要学习资料如下 B站狂神说,redis教程 马士兵教育 目录 1.集群前置知识 1.1.数据分区策略 1.1.1.哈希节点取余分区 1.1.2.一致性哈希分区 1.1.3.虚拟一 ...

  8. OpenSIPS学习笔记-cluster集群模块配置-dialog集群配置

    本章节中,笔者将进一步介绍关于OpenSIPS集群支持的另外一种常见的场景-dialog的集群.dialog集群是OpenSIPS在高并发环境中一定需要考虑的配置功能.通过集群部署方式,可以保证呼叫中 ...

  9. redis 学习笔记——redis集群

    redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...

最新文章

  1. 无法连接虚拟设备 ide1:0
  2. 同步(Synchronization)和异步(Asynchronous)
  3. [剑指offer][JAVA]面试题第[07]题[重建二叉树][递归]
  4. vue指令和特殊特性
  5. Laravel debug bar 调试利器
  6. Spring事件监听机制
  7. 模仿LordPE写了个PE解析工具
  8. 《RFID技术与应用》试题库(含答案)
  9. 文件后缀名批量修改工具
  10. IDEA同一个项目启动多个端口
  11. 本地IP地址使用域名访问
  12. 几个炫酷且实用的CSS动画效果
  13. 银保监机构保险许可证数据(2007-2022年)
  14. 关闭谷歌google右侧百度热搜(下方无偿链接),亲测有效
  15. 【spring Cloud 入门-4】简单的服务实例健康自检
  16. GitLab 小白入手教程
  17. 软件测试作业进度-2
  18. mp4格式怎么转换成gif格式?简单3步完成视频制作gif
  19. Vue 实现锚点定位
  20. 零基础学C++——黑马程序员课程笔记(C++核心编程篇)

热门文章

  1. 调用指定目录下的批处理bat_批处理(.bat)的奇技淫巧
  2. angular 控件css_Angular父组件内修改子组件的样式
  3. 基于selenium的钓鱼工具:关于ReelPhish神器的使用
  4. 机器学习入门笔记(三):K近邻算法
  5. 实验2.2编写重载函数Max1
  6. 我为啥不想用Python
  7. PREV-55 小计算器 (进制转换)
  8. 主内存和工作内存交互
  9. 第二阶段团队冲刺(六)
  10. 04_(终结版)通过App实现对数据库的增删改