当前位置: 首页 > article >正文

分层架构 IM 系统之 Router 架构分析

通过前面文章的分析,我们已经明确,Router 的核心职责是作为中央存储记录在线客户端的连接状态,Router 在本质上是一个内存数据库。

内存是一种易失性的存储,既如此,Router 的可用性如何保障呢?

副本是分布式存储系统容错技术的唯一手段!

所以解决 Router 的可用性问题,为其增加冗余的副本即可。

分布式存储系统的副本,有两类常用模式:主从模式和主主模式。

一、主从模式

对于主从模式来说,服务向 “主节点” 写数据,“从节点” 从 “主节点” 中同步数据;“主节点” 和 “从节点” 都是可以提供 “读数据” 服务的,不过只有主节点才能提供 “写数据” 服务,所以主从模式对于写操作来说,是单点方式,要解决 “写高可用” 是非常麻烦的。

二、主主模式

对于主主模式来说,服务可以向任何一个 “主节点” 写数据,也可以从任何一个 “主节点” 读数据,然后两个主节点之间互相同步数据,所以主主模式同时满足数据 “读高可用” 和 数据 “写高可用”;但是要注意,主主模式不适用的业务场景:对同一条数据从两个 “主节点” 同时进行写操作。

举一个例子: 主主模式集群中有一条数据为 x = 5,两个服务节点分别对两个 “主节点” 同时进行修改,一个 “主节点” 修改为 x = 7,一个 “主节点” 修改为 x = 9,此时两个 “主节点” 在互相同步时就会出现冲突。

所以,在使用主主模式时,一定要避免对相同数据的并发写。

Router 采用了 主主模式,见下图。

Logic 在写 Router 时,通过公式 uid % 2 计算要写入的 Router 节点,避免了相同用户记录在两个主 Router 节点上的并发写操作。另外,对于同一用户的操作,会由相同的 Logic 节点来处理(后面的技术文章中会详细分析),这也会避免相同用户记录的并发写入。

单个 Router 节点保存了所有在线客户端的用户数据,随着在线用户量的增多,Router 会很容易到达存储瓶颈;解决这个问题的常用方案是分片,见下图。

将所有在线用户分配到 N 个分片中,需要部署 N 组Router,每一组 Router 可以主主模式部署也可以主从模式部署; Logic 在写 Router 时,通过公式 uid % N 计算要写入的 Router 分组。这样通过分组的方式,实现了在线用户的横向线性扩容;每一组内部通过主主模式 或 主从模式实现了高可用。

这里有一个实践性很强的问题,大家思考一下: 将最开始的一组 Router 扩容为四组 Router 时,怎样将原来的数据进行迁移呢?

答案是不必迁移。一组 Router 扩容为四组 Router 后,原来这一组 Router 中大概会有四分之三的在线用户数据会被遗弃,不过不必担心,在上一篇文章(分层架构 IM 系统之 Router 能力分析)中,我们分析过,Router 的心跳扫描线程会扫描出心跳失活的用户记录进行清理;另外,其它三组 Router 最开始是空白数据,但随着在线用户客户端的心跳到来,会逐步将这空白的三组 Router 数据进行修复。

心细的同学会提出疑问:即使如此,当从这三组 Router 中读数据时,读不到怎么办呢?这就涉及到 IM 系统的容错性了。将一个在线用户,按离线方式去处理,并不会对用户造成不好的体验。当然,对 Router 进行扩容,选择在凌晨时分处理,肯定是最合适的。

将一个刚启动的 Router 节点作为 “从节点” 部署时,“主节点” 是如何进行数据同步的呢?见下图。

Router 在内存中维护了很多个 Map,当有其他 Router 节点以 “从节点” 的角色连接过来时,“主节点” Router 会将内存数据生成一个 “快照”,然后将 “快照” 数据发送到 “从节点”。

“主节点” Router 生成 “快照” 后,再接收到的所有的 “写操作” 将全部写入到 “增量数据队列” 中;Router “从节点” 消化完 “快照” 后,就会再次发请求到 “主节点”,然后不断从 “主节点” 的 “增量数据队列” 中读数据完成主从同步。

关于 “快照” 如何生成,我们在后面的技术文章中进行分析!

最后,总结文中关键:

1、 分布式存储系统的副本模式有两种实现方式:主从模式和主主模式,在使用主主模式时,需要避免相同数据记录在两个主节点上被并发写入;

2、 Router 采用了主主模式,当在线用户量达到单个 Router 的存储瓶颈时,通过分片方式实现横向扩容;

3、 在对 Router 进行横向扩容时,在 IM 这个业务场景下,不需要进行数据迁移;

4、 Router 进行主从数据同步时,先生成和同步快照,然后同步增量数据。

对 Router 的分析到这里时,会有同学提出疑问: Router 在整个 IM 系统中,特别像 Redis,Redis 是完全可以替代 Router 的 ,为什么要自研 Router 呢? 因为在早期,Redis 还没有那么成熟和普及!随着 IM 系统不断迭代,用 Redis 替换掉 Router 是必然的,因为 Redis 的扩展性和维护成本相对都是最好的!


http://www.kler.cn/a/421515.html

相关文章:

  • 云原生后端:解锁高效可扩展应用的魔法世界
  • 【Docker】Docker 容器日志过大导致磁盘爆满
  • 【closerAI ComfyUI】物体转移术之图案转移,Flux三重控制万物一致性生图,实现LOGO和图案的精准迁移
  • 初始化列表与Static成员
  • golangclean-cache, modcache sumdb等配置
  • 1.1 STM32_GPIO_基本知识
  • Elastic Cloud Serverless:深入探讨大规模自动扩展和性能压力测试
  • 重学设计模式-工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)
  • 数据结构—队列
  • 顶刊算法 | 鱼鹰算法OOA-BiTCN-BiGRU-Attention多输入单输出回归预测(Maltab)
  • Zabbix添加防火墙温度监控值实战
  • Macos用brew安装Nodejs亲手教程
  • LLM与动态符号执行生成测试用例的比较
  • C语言第十五周课——课堂练习
  • 数据结构自测题1
  • Qt 5 中的 QTextStream 使用指南
  • 接口自动化测试框架(pytest+allure+aiohttp+用例自动生成)
  • 正则表达式解析
  • ceph mon 数据重建
  • yt6801 ubuntu有线连接驱动安装
  • vue前端 下载、预览图片
  • 【Unity】【游戏开发】【VR】如何解决脚本不在同一个项目无法引用Public变量的问题
  • Epsilon2系列战术级微型惯性RTK卫星高精度组合导航系统0.5°/h
  • 开发中使用UML的流程_06 PIM-2:分析业务规则
  • Lumos学习王佩丰Excel第十九讲:Indirect函数
  • 《NGINX金典教程》读书笔记