本文作者阿里云高级技能专家木洛,有优化和修订。
1、前言
IM全称是“Instant Messaging”,中文名是即时通讯。在这个高度信息化的移动互联网期间,生存中IM类产物已经成为必备品,比力闻名的如钉钉、微信、QQ等以IM为核心功能的产物。固然现在微信已经发展为一个生态型产物,但其核心功能照旧IM。另有一些非以IM体系为核心的应用,最范例的如一些在线游戏、外交应用,IM也是其紧张的功能模块。可以说,带有外交属性的应用,IM功能肯定是必不可少的。
IM体系在互联网初期即存在,其根本技能架构在这十几年的发展中更新迭代多次,从早期的CS、P2P架构,到如以背景已经演变为一个复杂的分布式体系,涉及移动端、网络、安全和存储等技能的方方面面。其支持的规模也从早期的少量日活,到现在微信这个巨头最新公布的到达9亿的日活的体量。
IM体系中最核心的是消息体系,消息体系最核心的是消息的同步和存储:
1)消息的同步:将消息完备的、快速的从发送方通报到吸收方,就是消息的同步。消息同步体系最紧张的衡量指标就是消息通报的及时性、完备性以及能支持的消息规模。从功能上来说,一样寻常至少要支持在线和离线推送,高级的IM体系还支持“多端同步”;
2)消息的存储:消息存储即消息的恒久化生存,这里不是指消息在客户端当地的生存,而是指云端的生存,功能上对应的就是“消息环游”。“消息环游”的利益是可以实现账号在恣意端登岸检察全部汗青消息,这也是高级IM体系特有的功能之一。
本文内容紧张涉及IM体系中的消息体系架构,探究一种实用于大用户量的消息同步以及存储体系的架构实现,可以大概支持消息体系中的高级特性“多端同步”以及“消息环游”。在性能和规模上,可以大概做到全量消息云端存储,百万TPS以及毫秒级耽误的消息同步本事。
2、架构计划
本章紧张会先容基于TableStore的当代IM消息体系的架构计划,在具体先容架构计划之前,会先先容一种Timeline逻辑模子,来抽象和简化对IM消息同步和存储模子的明白。明白了Timeline模子后,会先容怎样基于此模子对消息的同步以及存储举行建模。基于Timeline模子,在实现消息同步和存储时还会有各方面的技能衡量,比方怎样对消息同步常见的读扩散和写扩散两种模子举行对比和选择,以及针对Timeline模子的特性怎样来选择底层数据库。
▲ 上图是消息体系传统架构与当代架构的简朴对比
传统架构下,消息是先同步后存储:
对于在线的用户,消息会直接及时同步到在线的吸收方,消息同步乐成后,并不会举行恒久化。而对于离线的用户大概消息无法及时同步乐成时,消息会恒久化到离线库,当吸收方重新毗连后,会从离线库拉取全部未读消息。当离线库中的消息乐成同步到吸收方后,消息会从离线库中删除。传统的消息体系,服务端的紧张工作是维护发送方和吸收方的毗连状态,并提供在线消息同步和离线消息缓存的本事,包管消息肯定可以大概从发送方通报到吸收方。服务端不会对消息举行恒久化,以是也无法支持消息环游。
当代架构下,消息是先存储后同步:
先存储后同步的利益是,如果吸收方确认吸收到了消息,那这条消息肯定是已经在云端生存了。而且消息会有两个库来生存,一个是消息存储库,用于全量生存全部会话的消息,紧张用于支持消息环游。另一个是消息同步库,紧张用于吸收方的多端同步。
消息从发送方发出后,颠末服务端转发,服务端会先将消息生存到消息存储库,后生存到消息同步库。完成消息的恒久化生存后,对于在线的吸收方,会直接选择在线推送。但在线推送并不是一个必须路径,只是一个更优的消息通报路径。
对于在线推送失败大概离线的吸收方,会有别的一个同一的消息同步方式。吸收方会主动的向服务端拉取全部未同步消息,但吸收方何时来同步以及会在哪些端来同步消息对服务端来说是未知的,以是要求服务端必须生存全部须要同步到吸收方的消息,这是消息同步库的紧张作用。对于新的同步装备,会有消息环游的需求,这是消息存储库的紧张作用,在消息存储库中,可以拉取恣意会话的全量汗青消息。
以上是传统架构和当代架构的一个简朴的对比,当代架构上整个消息的同步和存储流程,并没有变复杂太多,但是其能实现多端同步以及消息环游。当代架构中最核心的就是两个消息库“消息同步库”和“消息存储库”,是消息同步和存储最核心的根本。而本篇文章接下来的部门,都是围绕这两个库的计划和实现来睁开。
3、Timeline模子
在分析“消息同步库”和“消息存储库”的计划和实现之前,在本章会先先容一个逻辑模子-Timeline。Timeline模子会资助我们简化对消息同步和存储模子的明白,而消息库的计划和实现也是围绕Timeline的特性和需求来睁开。
▲ Timeline模子
如图是Timeline模子的一个抽象表述,Timeline可以简朴明白为是一个消息队列,但这个消息队列有如下特性:
1)每个消息拥有一个序次ID(SeqId),在队列反面的消息的SeqId肯定比前面的消息的SeqId大,也就是包管SeqId肯定是增长的,但是不要求严格递增;
2)新的消息永久在尾部添加,包管新的消息的SeqId永久比已经存在队列中的消息都大;
3)可根据SeqId随机定位到具体的某条消息举行读取,也可以恣意读取某个给定范围内的全部消息。
有了这些特性后,消息的同步可以拿Timeline来很简朴的实现。图中的例子中,消息发送方是A,消息吸收方是B,同时B存在多个吸收端,分别是B1、B2和B3。A向B发送消息,消息须要同步到B的多个端,待同步的消息通过一个Timeline来举行交换。A向B发送的全部消息,都会生存在这个Timeline中,B的每个吸收端都是独立的从这个Timeline中拉取消息。每个吸收端同步完毕后,都会在当地记载下最新同步到的消息的SeqId,即最新的一个位点,作为下次消息同步的起始位点。服务端不会生存各个端的同步状态,各个端均可以在恣意时间从恣意点开始拉取消息。
消息环游也是基于Timeline,和消息同步唯一的区别是,消息环游要求服务端可以大概对Timeline内的全部数据举行恒久化。
基于Timeline,从逻辑模子上可以大概很简朴的明白在服务端怎样去实现消息同步和存储,并支持多端同步和消息环游这些高级功能。落地到实现的难点紧张在怎样将逻辑模子映射到物理模子,Timeline的实现对数据库会有哪些要求?我们应该选择何种数据库去实现?这些是接下来会讨论到的题目。
4、消息存储模子
▲ 基于Timeline的消息存储模子
如图是基于Timeline的消息存储模子,消息存储要求每个会话都对应一个独立的Timeline。如图例子所示,A与B/C/D/E/F均发生了会话,每个会话对应一个独立的Timeline,每个Timeline内存有这个会话中的全部消息,服务端会对每个Timeline举行恒久化。服务端可以大概对全部会话Timeline中的全量消息举行恒久化,也就拥有了消息环游的本事。
5、消息同步模子
消息同步模子会比消息存储模子稍复杂一些,消息的同步一样寻常有读扩散和写扩散两种差别的方式,分别对应差别的Timeline物理模子。
▲ 读扩散和写扩散两种差别同步模式下对应的差别的Timeline模子
如图是读扩散和写扩散两种差别同步模式下对应的差别的Timeline模子,按图中的示例,A作为消息吸收者,其与B/C/D/E/F发生了会话,每个会话中的新的消息都须要同步到A的某个端,看下读扩散和写扩散两种模式下消息怎样做同步。
读扩散:
消息存储模子中,每个会话的Timeline中生存了这个会话的全量消息。读扩散的消息同步模式下,每个会话中产生的新的消息,只须要写一次到其用于存储的Timeline中,吸收端从这个Timeline中拉取新的消息。
优点是消息只须要写一次,相比写扩散的模式,可以大概大大低沉消息写入次数,特别是在群消息这种场景下。但其缺点也比力显着,吸收端去同步消息的逻辑会相对复杂和低效。吸收端须要对每个会话都拉取一次才气获取全部消息,读被大大的放大,而且会产生很多无效的读,由于并不是每个会话都会有新消息产生。
写扩散:
写扩散的消息同步模式,须要有一个额外的Timeline来专门用于消息同步,通常是每个吸收端都会拥有一个独立的同步Timeline,用于存放须要向这个吸收端同步的全部消息。
每个会话中的消息,会产生多次写,除了写入用于消息存储的会话Timeline,还须要写入须要同步到的吸收端的同步Timeline。在个人与个人的会话中,消息会被额外写两次,除了写入这个会话的存储Timeline,还须要写入加入这个会话的两个吸收者的同步Timeline。而在群这个场景下,写入会被更加的放大,如果这个群拥有N个加入者,那每条消息都须要额外的写N次。
写扩散同步模式的优点是,在吸收端消息同步逻辑会非常简朴,只须要从其同步Timeline中读取一次即可,大大低沉了消息同步所需的读的压力。其缺点就是消息写入会被放大,特别是针对群这种场景。
在IM这种应用场景下,通常会选择写扩散这种消息同步模式。
IM场景下,一条消息只会产生一次,但是会被读取多次,是范例的读多写少的场景,消息的读写比例大概是10:1。若利用读扩散同步模式,整个体系的读写比例会被放大到100:1。
一个优化的好的体系,必须从计划上去平衡这种读写压力,制止读或写恣意一维触碰到天花板。以是IM体系这类场景下,通常会应用写扩散这种同步模式,来平衡读和写,将100:1的读写比例平衡到30:30。
固然写扩散这种同步模式,还须要处理处罚一些非常场景,比方万人大群。针对这种非常写扩散的场景,会退化到利用读扩散。一个简朴的IM体系,通常会在产物层面限定这种大群的存在,而对于一个高级的IM体系,会采取读写扩散混淆的同步模式,来满足这类产物的需求。采取混淆模式,会根据数据的差别范例和差别的读写负载,来决定用写扩散照旧读扩散。
6、范例架构计划
如上图所示,是一个范例的消息体系架构。
该范例的消息体系架构中包罗几个紧张组件:
1)端:作为消息的发送和吸收端,通过毗连消息服务器来发送和吸收消息。
2)消息服务器:一组无状态的服务器,可程度扩展,处理处罚消息的发送和吸收哀求,毗连后端消息体系。
3)消息队列:新写入消息的缓冲队列,消息体系的前置消息存储,用于削峰填谷以及异步斲丧。
4)消息处理处罚:一组无状态的斲丧处理处罚服务器,用于异步斲丧消息队列中的消息数据,处理处罚消息的恒久化和写扩散同步。
5)消息存储和索引库:恒久化存储消息,每个会话对应一个 Timeline 举行消息存储,存储的消息创建索引来实现消息检索。
6)消息同步库:
写扩散情势同步消息,每个用户的收件箱对应一个 Timeline,同步库内消息不须要永世生存,通常对消息设定一个生命周期。
新消息会由端发出,通常消息体中会携带消息 ID(用于去重)、逻辑时间戳(用于排序)、消息范例(控制消息、图片消息大概文本消息等)、消息体等内容。
消息会先写入消息队列,作为底层存储的一个暂时缓冲区。消息队列中的消息会由消息处理处罚服务器斲丧,可以允许乱序斲丧。消息处理处罚服务器对消息先存储后同步,先写入发件箱 Timeline(存储库),后写扩散至各个吸收端的收件箱(同步库)。
消息数据写入存储库后,会被近及时的构建索引,索引包罗文本消息的全文索引以及多字段索引(发送方、消息范例等)。
对于在线的装备,可以由消息服务器主动推送至在线装备端。对于离线装备,登录后会主动向服务端同步消息。每个装备会在当地生存有最新一条消息的序次 ID,向服务端同步该序次 ID 后的全部消息。
7、消息库计划
基于Timeline模子,以及Timeline模子在消息存储和消息同步的应用,我们看下消息同步库和消息存储库的计划。
▲ 基于Timeline的消息库计划消息同步库:
消息同步库用于存储全部用于消息同步的Timeline,每个Timeline对应一个吸收端,紧张用作写扩散模式的消息同步。
这个库不须要永世生存全部须要同步的消息,由于消息在同步到全部端后其生命周期就可以竣事,就可以被接纳。但是如前面所先容的,一个实现简朴的多端同步消息体系,在服务端不会生存有全部端的同步状态,而是依靠端本身主动来做同步。
以是服务端不知道消息何时可以接纳,通常的做法是为这个库里的消息设定一个固定的生命周期,比方一周大概一个月,生命周期竣事可被镌汰。
消息存储库:
消息存储库用于存储全部会话的Timeline,每个Timeline包罗了一个会话中的全部消息。这个库紧张用于消息环游时拉取某个会话的全部汗青消息,也用于读扩散模式的消息同步。
消息同步库和消息存储库,对数据库有差别的要求,怎样对数据库做选型,在下面会讨论。
8、数据库选型
消息体系最核心的两个库是消息同步库和消息存储库,两个库对数据库有差别的要求:
总结下来,对数据库的要求有如下几点:
- 1)表布局计划可以大概满足Timeline模子的功能要求:不要求关系模子,可以大概实现队列模子,并可以大概支持天生自增的SeqId;
- 2)可以大概支持高并发写和范围读,规模在十万级TPS;
- 3)可以大概生存海量数据,百TB级;
- 4)可以大概为数据界说生命周期。
9、本文小结
本文紧张先容了当代IM体系中消息推送和存储架构的实现,基于逻辑的Timeline模子,我们可以很清楚明白的明白整个消息推送和存储的架构。而基于Timeline的消息存储和推送模子,实在不但可以应用在IM消息体系中,还可应用在比方Feeds流、及时消息同步、直播弹幕等场景。
10、参考资料
[1] 浅谈IM体系的架构计划
[2] 简述移动端IM开辟的那些坑:架构计划、通讯协媾和客户端
[3] 一套海量在线用户的移动端IM架构计划实践分享(含具体图文)
[4] 一套原创分布式即时通讯(IM)体系理论架构方案
[5] 从零到良好:京东客服即时通讯体系的技能架构演进进程
[6] 蘑菇街即时通讯/IM服务器开辟之架构选择
[7] 腾讯QQ1.4亿在线用户的技能寻衅和架构演进之路PPT
[8] 移动端IM中大规模群消息的推送怎样包管服从、及时性?
[9] 子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技能实践
[10] 微信技能分享:微信的海量IM谈天消息序列号天生实践(算法原理篇)
[11] 一套高可用、易伸缩、高并发的IM群聊、单聊架构方案计划实践
[12] 外交软件红包技能解密(一):全面解密QQ红包技能方案——架构、技能实现等
[13] 外交软件红包技能解密(二):解密微信摇一摇红包从0到1的技能演进
[14] 从游击队到正规军(一):马蜂窝旅游网的IM体系架构演进之路
[15] 瓜子IM智能客服体系的数据架构计划(整理自现场演讲,有配套PPT)
[16] 阿里钉钉技能分享:企业级IM王者——钉钉在后端架构上的过人之处
[17] IM开辟根本知识补课(十):大型IM体系有多难?万字长文,搞懂异地多活!
[18] 阿里技能分享:电商IM消息平台,在群聊、直播场景下的技能实践
[19] 一套亿级用户的IM架构技醒目货(上篇):团体架构、服务拆分等
[20] 重新手到专家:怎样计划一套亿级消息量的分布式IM体系
[21] 企业微信的IM架构计划揭秘:消息模子、万人群、已读回执、消息撤回等
[22] 融云技能分享:全面揭秘亿级IM消息的可靠投递机制
[23] IM开辟技能学习:揭秘微信朋侪圈这种信息推流背后的体系计划
[24] 阿里IM技能分享(三):闲鱼亿级IM消息体系的架构演进之路
[25] 基于实践:一套百万消息量小规模IM体系技能要点总结
[26] 跟着源码学IM(十):基于Netty,搭建高性能IM集群(含技能思绪+源码)
[27] 一套十万级TPS的IM综合消息体系的架构实践与思索
[28] 直播体系谈天技能(八):vivo直播体系中IM消息模块的架构实践
[29] 得物从0到1自研客服IM体系的技能实践之路
[30] 海量用户IM谈天室的架构计划与实践
[31] 企业微信针对百万级构造架构的客户端性能优化实践
[32] 一套分布式IM即时通讯体系的技能选型和架构计划
[33] 陌陌技能分享:陌陌IM在后端KV缓存架构上的技能实践
[34] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗
[35] 携程技能分享:亿级流量的办公IM及开放平台技能实践
[36] 转转平台IM体系架构计划与实践(一):团体架构计划
[37] 支持百万人超大群聊的Web端IM架构计划与实践
[38] 一年撸完百万行代码,企业微信的全新鸿蒙NEXT客户端架构演进之路
[39] 转转客服IM谈天体系背后的技能寻衅和实践分享
[40] B站IM消息体系的新架构升级实践
[41] 怎样保障分布式IM谈天体系的消息有序性(即消息不乱)
[42] 新手入门一篇就够:从零开辟移动端IM
[43] 移动端IM开辟者必读(一):普通易懂,明白移动网络的“弱”和“慢”
[44] 零根本IM开辟入门(一):什么是IM谈天体系?
即时通讯技能学习:
- 移动端IM开辟入门文章:《新手入门一篇就够:从零开辟移动端IM》
- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地点点此)
(本文内容引用自:http://www.52im.net/thread-1230-1-1.html)
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |