NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

现代 IM 系统中的消息系统架构——模型篇

  • 2019-05-17
  • 本文字数:2825 字

    阅读完需:约 9 分钟

现代IM系统中的消息系统架构——模型篇

前言

架构篇中我们介绍了现代 IM 消息系统的架构,介绍了 Timeline 的抽象模型以及基于 Timeline 模型构建的一个支持『消息漫游』、『多端同步』和『消息检索』多种高级功能的消息系统的典型架构。架构篇中为了简化读者对 Tablestore Timeline 模型的理解,概要性的对 Timeline 的基本逻辑模型做了介绍,以及对消息系统中消息的多种同步模式、存储和索引的基本概念做了一个科普。


本篇文章是对架构篇的一个补充,会对 Tablestore 的 Timeline 模型做一个非常详尽的解读,让读者能够深入到实现层面了解 Timeline 的基本功能以及核心组件。最后我们还是会基于 IM 消息系统这个场景,来看如何基于 Tablestore Timeline 实现 IM 场景下消息同步、存储和索引等基本功能。

Timeline 模型

Timeline 模型以『简单』为设计目标,核心模块构成比较清晰明了,主要包括:


  • Store:Timeline 存储库,类似数据库的表的概念。

  • Identifier:用于区分 Timeline 的唯一标识。

  • Meta:用于描述 Timeline 的元数据,元数据描述采用 free-schema 结构,可自由包含任意列。

  • Queue:一个 Timeline 内所有 Message 存储在 Queue 内。

  • Message:Timeline 内传递的消息体,也是一个 free-schema 的结构,可自由包含任意列。

  • Index:包含 Meta Index 和 Message Index,可对 Meta 或 Message 内的任意列自定义索引,提供灵活的多条件组合查询和搜索。

Timeline Store


Timeline Store 是 Timeline 的存储库,对应于数据库内表的概念。上图是 Timeline Store 的结构图,Store 内会存储所有的 Timeline 数据。Timeline 是一个面向海量消息的数据模型,同时用于消息存储库和同步库,需要满足多种要求:


  • 支撑海量数据存储:对于消息存储库来说,如果需要消息永久存储,则随着时间的积累,数据规模会越来越大,需要存储库能应对长时间积累的海量消息数据存储,需要能达到 PB 级容量。

  • 低存储成本:消息数据的冷热区分是很明显的,大部分查询都会集中在热数据,所以对于冷数据需要有一个比较低成本的存储方式,否则随着时间的积累数据量不断膨胀,存储成本会非常大。

  • 数据生命周期管理:不管是对于消息数据的存储还是同步,数据都需要定义生命周期。存储库是用于在线存储消息数据本身,通常需要设定一个较长周期的保存时间。而同步库是用于写扩散模式的在线或离线推送,通常设定一个较短的保存时间。

  • 极高的写入吞吐:各类场景下的消息系统,除了类似微博、头条这种类型的 Feeds 流系统,像绝大部分即时通讯或朋友圈这类消息场景,通常是采用写扩散的消息同步模式,写扩散要求底层存储具备极高的写入吞吐能力,以应对消息洪峰。

  • 低延迟的读:消息系统通常是应用在在线场景,所以对于查询要求低延迟。


Tablestore Timeline 的底层是基于 LSM 存储引擎的分布式数据库,LSM 的最大优势就是对写入非常友好,天然适合消息写扩散的模式。同时对查询也做了极大优化,例如热数据进缓存、bloom filter 等等。数据表采用 Range Partition 的分区模式,能提供水平扩展的服务能力,以及能自动探测并处理热点分区的负载均衡策略。为了满足同步库和存储库对存储的不同要求,也提供了一些灵活的自定义配置,主要包括:


  • Time to live(数据生命周期):可自定义数据生命周期,例如永久保存,或者保存 N 天。

  • Storage type(存储类型):自定义存储类型,对存储库来说,HDD 是最好的选择,对同步库来说,SSD 是最好的选择。

Timeline Module


Timeline Store 内能存储海量的 Timeline,单个 Timeline 的详细结构图如上,可以看到 Timeline 主要包含了三大部分:


  • Timeline Meta:元数据部分,用于描述 Timeline,包括:

  • Identifier:用于唯一标识 Timeline,可包含多个字段。

  • Meta:用于描述 Timeline 的元数据,可包含任意个数任意类型的字段。

  • Meta Index:元数据索引,可对元数据内任意属性列建索引,支持多字段条件组合查询和检索。

  • Timeline Queue:用于存储和同步消息的队列,队列中元素由两部分组成:

  • Sequence Id:顺序 ID,队列中用于定位 Message 的位点信息,在队列中顺序 ID 保持递增。

  • Message:队列中承载消息的实体,包含了消息的完整内容。

  • Timeline Data:Timeline 的数据部分就是 Message,Message 主要包含:

  • Message:消息实体,其内部也可以包含任意数量任意类型字段。

  • Message Index:消息数据索引,可对消息实体内任意列做索引,支持多字段条件组合查询和检索。

IM 消息系统建模


以一个简易版 IM 系统为例,来看如何基于 Tablestore Timeline 模型建模。按照上图中的例子,存在 A、B、C 三个用户,A 与 B 发生单聊,A 与 C 发生单聊,以及 A、B、C 组成一个群聊,来看下在这个场景下消息同步、存储以及读写流程分别如何基于 Tablestore Timeline 建模。


消息同步模型


消息同步选择写扩散模型,能完全利用 Tablestore Timeline 的优势,以及针对 IM 消息场景读多写少的特性,通过写扩散来平衡读写,均衡整个系统的资源。写扩散模型下,每个接收消息的个体均拥有一个收件箱,所有需要同步至该个体的消息需要投递到其收件箱内。图上例子中,A、B、C 三个用户分别拥有收件箱,每个用户不同的设备端,均从同一个收件箱内拉取新消息。


消息同步库


收件箱存储在同步库内,同步库中每个收件箱对应一个 Timeline。根据图上的例子,总共存在 3 个 Timeline 作为收件箱。每个消息接收端保存有本地最新拉取的消息的 SequenceID,每次拉取新消息均是从该 SequenceID 开始拉取消息。对同步库的查询会比较频繁,通常是对最新消息的查询,所以要求热数据尽量缓存在内存中,能提供高并发低延迟的查询。所以对同步库的配置,一般是需要 SSD 存储。消息如果已经同步到了所有的终端,则代表收件箱内的该消息已经被消费完毕,理论上可以清理。但设计上来说不做主动清理,而是给数据定义一个较短的生命周期来自动过期,一般定义为一周或者两周。数据过期之后,如果仍要同步拉取新消息,则需要退化到读扩散的模式,从存储库中拉取消息。


消息存储库


消息存储库中保存有每个会话的消息,每个会话的发件箱对应一个 Timeline。发件箱内的消息支持按会话维度拉取消息,例如浏览某个会话内的历史消息则通过读取发件箱完成。一般来说,新消息通过在线推送或者查询同步库可投递到各个接收端,所以对存储库的查询会相对来说较少。而存储库用于长期存储消息,例如永久存储,相对同步库来说数据量会较大。所以存储库的选择一般是 HDD,数据生命周期根据消息需要保存的时间来定,通常是一个较长的时间。


消息索引库


消息索引库依附于存储库,使用了 Timeline 的 Message Index,可以对存储库内的消息进行索引,例如对文本内容的全文索引、收件人、发件人以及发送时间的索引等,能支持全文检索等高级查询和搜索。

总结

本篇文章主要对 Tablestore Timeline 模型进行了详解,介绍了 Timeline 各模块包括 Store、Meta、Queue、Data 和 Index 等,最后以一个简单的 IM 场景举例如何基于 Timeline 来建模。


本文作者:木洛


本文来源:阿里云云栖社区


来源链接:


https://yq.aliyun.com/articles/701593


2019-05-17 08:006866

评论

发布
暂无评论
发现更多内容

架构师训练营第四周作业

子豪sirius

Redis(一)分布式缓存的作用

奈何花开

Java redis 分布式缓存

「架构师训练营」学习笔记:第 4 周 系统架构知识

Amy

学习 极客大学架构师训练营 第四周 系统架构知识

Python中的浅拷贝和深拷贝

王坤祥

Python 编程 计算机

架构师训练营第四周学习总结

fenix

第四周作业

Geek_5d0795

极客大学架构师训练营

大型互联网应用系统技术方案

Geek_zhangjian

架构师训练营第四周 架构分析

suke

极客大学架构师训练营

第四周作业

王鑫龙

极客大学架构师训练营

《了不起的我》:关于「改变」的心理学

强劲九

心理 读书 书籍推荐 看书

架构师训练营 - 第四周 - 作业

韩挺

Mybatis执行过程源码分析

编号94530

Java 源码分析 mybatis

【架构师训练营】第四周作业

Mr.hou

极客大学架构师训练营

架构师训练营 Week 04 总结

Wancho

通用编程风格

顿晓

Java 学习 编程风格

架构师训练营-第四章-学习总结

而立

极客大学架构师训练营

可复用架构之分离关注点

松花皮蛋me

面试 Java 分布式 可复用架构

区块链技术打通信用壁垒赋能租赁业务

CECBC

去中心 区块链技术 防篡改 去信任

互联网架构总结

Lane

极客大学架构师训练营

架构师训练营第4周学习总结

不谈

Week 04 学习总结

卧石漾溪

极客大学架构师训练营

架构师训练营-week4-作业

晓-Michelle

极客大学架构师训练营

架构师训练营 - 第四周 - 学习总结

韩挺

假想 一个进销存软件是如何发展的

不在调上

第四周总结

不在调上

架构师训练营 No.4 作业

连增申

Week4  互联网系统的技术和手段

TiK

极客大学架构师训练营

【架构师训练营】第四周总结

Mr.hou

极客大学架构师训练营

第四周总结

赵龙

程序员如何提升自己横向能力?

Boss.Guo

团队建设 能力提升 人才培养 个人总结

架构师训练营第4周作业

不谈

极客大学架构师训练营

现代IM系统中的消息系统架构——模型篇_架构_木洛_InfoQ精选文章