钉钉架构设计
钉钉作为一款业界熟知的企业级IM产品,数据量大、业务场景多,其架构设计方案必然有着非常多值得借鉴的地方。比如对于高可用、安全性、数据一致性、差异化产品支持等关键设计,网上找到了一篇钉钉架构师的分享一起来学习下。
万人群
IM场景下万人群的高流量支撑是非常有挑战的事情,为解决这种问题,有的时候是从产品功能上做切割,比如微信群这种只允许500人,其技术挑战就小了很多。但是钉钉是一个ToB的产品,很难控制群人数,所以万人群是需要支持的一个IM场景。
那钉钉做了哪些优化呢?
1. 降低存储扩散量
最早的IM使用的是写扩散模型,这种模式也是在推特和微博常用的一种方案,很多IM早期时间都是借鉴这种方式。在一个万人群,如果是写扩展,一条消息需要写一万次收件箱。而优化成读扩散模型后,一条消息只需要写一次收件箱即可,扩散量降低到万分之一。
2. 智能限流
当总体消息量超过系统阈值后,智能限流机制可以根据当时流量情况,对消息发送频率高的群进行限制,传统的限流如果不智能的话,就不可以做精细化控制,误杀程度高。
3. 万人群成员多级缓存
万人群联系人列表也是一个性能点,在钉钉客户端、服务端做群成员的多级缓存,提高了at列表、查看群成员等场景的体验。同时可以降低对于DB的读写压力,提高了系统稳定性。
4. 端到端体验保障
客户端定期做极限压测,在群消息大规模刷屏时,保障用户体验流畅不卡顿。
历史消息可回溯
在ToB场景下,数据是企业的资产,企业对于历史消息有查询需求,这和ToC产品的消息又不太一样,比如微信的离线消息是存在客户端的,清空就没有了。
如何做好庞大历史消息的查询需求呢?需要解决低流量且消息不遗漏。
可以分成近时消息和历史消息。近时消息推送到客户端本地,历史消息在服务端。用户进入会话后,先看客户端本地是否有消息,如果没有或者不完整,从服务端拉取差异消息。采用这种offset和推拉结合的方式,保证消息可以无遗漏的从服务端同步下来。
消息存储是典型的冷热属性存储,用户访问的大部分消息都是最近的消息,钉钉自研了一套冷热分离存储架构,在冷库使用低成本高压缩率的存储引擎,大幅降低存储成本。
为保障历史消息的安全性,钉钉达到了金融级安全加密,钉钉使用全链路加密算法,不留死角,保证没有任何人可以非法窃取历史消息。
场景化支持
ToC IM产品场景化都比较通用,比如微信群,每个人使用起来都是相同的。但钉钉针对于不同场景体验做了不同支持。
这对于系统挑战来源于两方面:
系统模型必须扩展性强:可以灵活、快速的支持业务场景化需求;
在保障支持业务快速的情况下,保持IM核心系统高可用;
以钉钉班级群为例,使用小程序开发,可以不发版做bugfix,实现业务需求迭代。服务端切分为业务层和Im Core层,做到了新需求不改动Im Core层。迭代速度快,系统稳定性强,达到了业务、技术共同迭代,互不影响的目的。
单元化
单元化可以满足多层需求:
高可用:钉钉保障vip用户的地域级别容灾能力,钉钉设计了一套基于单元化异地容灾方案,当中心机房宕机,两分钟内一键把vip用户调度到容灾单元,保障用户正常使用IM;
国际化:海外地区对于数据有合规要求,钉钉在当地部署应用,给海外用户提供了流畅的用户体验。
支持大客户及特殊行业:钉钉不仅承接了中小企业沟通办公需求,还承接不少政企用户,他们有私有化部署的需求,需要钉钉具备云部署能力。
容量:随着业务发展,所有流量在中心机房处理,扩展性差,把流量分散到多个地域是一个必然选择。
钉钉通过一套代码部署、一套运维体系实现了单元化,满足了上层多种需求。技术团队开发了单元化基础组件,动态路由,业务层数据同步组件等一系列基础设计,可以将钉钉部署在任一国家、地区,甚至用户的自有机房。