燃爆上海 5·23-24,AICon 大模型实战风暴,50+ 干货一网打尽,即将开幕~ 了解详情
写点什么

现代 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:007396

评论

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

神经网络攻防:03.使用API修改神经网络参数

P小二

AIPwn AI安全 P小二 神经网络攻防

15 分钟部署一个 CAS 服务并对接 Shibboleth-IdP 3.4.6

冯骐

CAS 认证 Shibboleth 统一身份认证

史上最全整合第三方登录的开源库

happlyfox

OAuth 2.0 28天写作 3月日更

神经网络攻防: 02.攻击模型的输出层

P小二

AIPwn AI安全 P小二 神经网络攻防

GitHub上获赞10万star的高并发神级进阶资料,面试官再问高并发问题请你把这篇文章发给他!

Java架构之路

Java 程序员 架构 面试 编程语言

beego + nginx 实现反向代理统一认证

冯骐

nginx 开发 ldap auth_request Go 语言

世界经济论坛:四大区块链趋势将在今年绽放异彩

CECBC

区块链

白话Go内存模型&Happen-Before

Gopher指北

Go 语言

科学的互联网思想 指引我国网络强国建设稳步前行

CECBC

网络安全

2021年最新京东技术岗现场三面:jvm调优+高并发+算法+网络+数据库+设计模式

Java架构之路

Java 程序员 架构 面试 编程语言

Shibboleth-IdP 的 OAuth2 对接方案详解

冯骐

OAuth2 SAML Shibboleth CARSI

5 分钟部署一个 OAuth2 服务并对接 Shibboleth-IdP 3.4.6

冯骐

运维 开发 OAuth2 Shibboleth Go 语言

四面阿里成功斩获offer,在此分享我的复盘经验总结!

Java架构之路

Java 程序员 架构 面试 编程语言

Semaphore实战

叫练

CountDownLatch CyclicBarrier Semaphore 线程协作

git 教程 --git cherry-pick 命令

生之欢愉,时间同行

git 程序员 git cherry-pick

手把手教学,如何使用低代码快速构建应用程序步骤详解!

优秀

低代码

程序员之禅(二)

每天读本书

读书笔记 每天读本书

Mysql安装

Sakura

一桶食用油的数字化

吴俊宇

数字化转型 鲁花

Docker的三言两语-基础篇

一个大红包

Docker 28天写作 3月日更

牛掰,阿里P8这份笔记不就相当于金三银四中的原子弹吗?已经帮助13位同行拿到了一线大厂的offer!

Java架构师迁哥

【科创人】Testin云测总裁徐琨:创业必须要创造出肉眼可见的价值

科创人

Promise原理及常用操作

花明

一场关于代码注释的争执,引发的三点思考

架构精进之路

编码 经验分享 七日更 3月日更

园区网中 IPv6 地址的终端 mac 地址追溯

冯骐

Python 运维 日志 网络 ipv6

Python学习心得

张鹤羽

28天写作 3月日更

区块链产业革命:解决融资租赁之谜

CECBC

区块链

区块链电子合同--电子合同区块链签约平台

13530558032

APICloud Avm.js前端框架的优势

YonBuilder低代码开发平台

小程序 大前端 移动开发 跨端开发 多端开发

怎样在自己的 Web 中加入强大的日志系统?slf4j 的日志插件必须要知道!

老王说编程

slf4j java 日志 日志管理 日志框架

智慧党建平台解决方案--高效开展党建工作

13530558032

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