本文正文部分引用了 58 同城架师沈剑的文章,非常感谢他的分享.
1,前言
IM 应用从服务端数据的角度来看,它是一种很特殊的应用场景,抛开基础数据,增值业务和附属功能不谈,单从 IM 聊天工具的立身之本--聊天数据来说,理论上是不需要在服务端存储的(或者说只需要短暂存储--比如离线消息,上线即拉走),这也是为什么微信在前段时间号称绝不存储用户聊天数据的原因(从技术上说这不是没有道理的,但到底有没有存储,这已经超越技术范畴了,不在此文讨论之列 ^_^).
那么为什么说 IM 系统的服务端从技术上说,是不需要存储聊天数据的呢?原因很简单,我们知道 IM 的聊天数据分两种:
一种是实时消息(就是你在线,对方也在线情况下的聊天数据交互);
一种是离线消息(就是你在线,对方不在线时,你发过去的消息,对于对方而言就是离线消息了).
实时消息的收发:服务端只作为中转角色(关于中转的技术问题,很多人可能还在结纠老思维为何不用 P2P,我已经论坛说烂了,说白了跟技术无关,其实一个很重要的原因就是为了运营的可控性:比如用户 P2P 去了,违法的锅你运营方来背好不好?),聊天消息在此时就相当于左手倒右手--即聊天数据的本质就是从 A 用户经过服务端到达 B 用户就完了,服务端完全没必要存储(当然,我们讨论的是技术理想情况,实际上抛开技术因素来说,这么多丰富的用户行为数据你是运营方你会放过吗?但,这跟技术无关对吧).
离线消息的收发:当接收方不在线时,发送方的聊天数据在服务端只需要作短因果报应存储,因为接收方一旦上线就拉走了,服务器删除即可(注意:从技术上来说就是这样的哦).对用户而言聊天消息的社会学的本质来说就像两个人在对话,我已经听见你说的就好了,干吗老像复读机一样一遍一遍一说给我听?
正如上述所言,IM 系统中最重要的聊天数据从技术上不说其实是没有存储的必要的.不过话虽如此,但一个大型的 IM 系统的方方面面数据量也是很可观的,所以开发 IM 系统时讨论服务端数据库的读写分离,水平分表等,是很有必要的.因而通过本文快速理解服务端数据库的读写分离原理你不应错过,本文也同时建议您在正确理解它的前提下再慎重决定您的服务端架构方案是否需要数据库读写分离,因为很多时候增加缓存策略就能解决的问题,就没有必在大炮打蚊子了.
好了,费话多说了几句,我们开始阅读正文.
▼ 跟 IM 数据存储架构有关的文章,有如下几篇,或许对你有用:
《 腾讯原创分享 (一):如何大幅提升移动网络下手机 QQ 的图片传输速度和成功率 》
《 微信海量用户背后的后台系统存储架构 (视频 + PPT) [附件下载] 》
《 微信后台基于时间序的海量数据冷热分级架构设计实践 》
《 现代 IM 系统中聊天消息的同步和存储方案探讨 》
▼ IM 开发干货系列文章适合作为 IM 开发热点问题参考资料(本文是其第 12 篇):
《 IM 消息送达保证机制实现 (一):保证在线实时消息的可靠投递 》
《 IM 消息送达保证机制实现 (二):保证离线消息的可靠投递 》
《 如何保证 IM 实时消息的 "时序性" 与 "一致性"? 》
《 IM 单聊和群聊中的在线状态同步应该用 "推" 还是 "拉"? 》
《 IM 群聊消息如此复杂,如何保证不丢不重? 》
《 一种 Android 端 IM 智能心跳算法的设计与实现探讨(含样例代码) 》
《 移动端 IM 登录时拉取数据如何作到省流量? 》
《 通俗易懂:基于集群的移动端 IM 接入层负载均衡方案分享 》
《 浅谈移动端 IM 的多点登陆和消息漫游原理 》
《 IM 开发基础知识补课 (一):正确理解前置 HTTP SSO 单点登陆接口的原理 》
《 IM 开发基础知识补课 (二):如何设计大量图片文件的服务端存储架构? 》
《 IM 开发基础知识补课 (三):快速理解服务端数据库读写分离原理及实践建议 》(本文)
如果您是 IM 开发初学者,强烈建议首先阅读《 新手入门一篇就够:从零开发移动端 IM 》.
3,什么是数据库读写分离?
1.png (17.68 KB, 下载次数: 0)
下载附件 保存到相册
昨天 16:47 上传
如上图所示,一主多从,读写分离,主动同步,是一种常见的数据库架构.
一般来说:
主库--提供数据库写服务;
从库--提供数据库读服务.
主从库之间,通过某种机制同步数据,例如 mysql 的 binlog.
像上述图中这样,一个主从同步集群通常被称为一个 "分组".
那么,数据库 "分组" 架构究竟解决什么问题?大部分互联网业务读多写少,数据库的读往往最先成为性能瓶颈,如果希望:
线性提升数据库读性能;
通过消除读写锁冲突提升数据库写性能;
此时可以使用分组架构.
一句话总结:"分组" 主要解决 "数据库读性能瓶颈" 问题,在数据库扛不住读的时候,用 "分组" 架构实现读写分离,通过增加从库线性提升系统读性能.
4,什么是数据库水平切分?
2.png (10.03 KB, 下载次数: 0)
下载附件 保存到相册
昨天 16:52 上传
如上图所示,跟数据库 "分组" 架构实现读写分离一样,水平切分(也称大表拆分,分表),也是一种常见的数据库架构手段.
一般来说:
每个数据库之间没有数据重合,没有类似 binlog 同步的关联;
所有数据并集,组成全部数据;
会用算法,来完成数据分割,例如 "取模";
一个水平切分集群中的每一个数据库,通常称为一个 "分片".
水平切分架构究竟解决什么问题?大部分互联网业务数据量很大,单库容量容易成为瓶颈,如果希望:
线性降低单库数据容量;
线性提升数据库写性能;
此时可以使用水平切分架构.
一句话总结:数据库水平切分架构主要解决 "数据库数据量大"(或者更细一点说是单表数据量太大)问题,在数据库容量扛不住的时候,通常水平切分.
5,数据库读写分离虽好,但不应滥用
对于互联网大数据量,高并发量,高可用要求高,一致性要求高,前端面向用户的业务场景,如果数据库读写分离:
数据库连接池需要区分:读连接池,写连接池;
如果要保证读高可用,读连接池要实现故障自动转移;
有潜在的主库从库一致性问题.
3.png (13.84 KB, 下载次数: 0)
下载附件 保存到相册
昨天 16:56 上传
实际上,如果您的系统面临的是 "读性能瓶颈" 问题,增加缓存可能来得更直接,更容易一点.
另外,从成本上说,从库的成本比缓存高不少.而且对于云上的架构,以阿里云为例,主库提供高可用服务,从库不提供高可用服务,实现方案上更主流.
所以,上述业务场景下,建议使用缓存架构来加强系统读性能,替代数据库主从分离架构.
当然,使用缓存架构的潜在问题:如果缓存挂了,流量全部压到数据库上,数据库会雪崩.不过幸好,云上的缓存一般都提供高可用的服务.
6,简单小结
典型的大型互联应用架构中,服务端数据库架构主要使用以下两种:
使用 "分组" 架构实现数据库读写分离:解决 "数据库读性能瓶颈" 问题;
使用 "分片" 架构实现数据库水平切分:解决 "数据库数据量大" 问题.
但对于互联网大数据量,高并发量,高可用要求高,一致性要求高,前端面向用户的业务场景,使用微服务缓存架构,很多时候可能比数据库读写分离架构更合适.
附录:更多 IM 开发文章
[1] 有关 IM 架构设计:
《 浅谈 IM 系统的架构设计 》
《 简述移动端 IM 开发的那些坑:架构设计,通信协议和客户端 》
《 一套海量在线用户的移动端 IM 架构设计实践分享 (含详细图文) 》
《 一套原创分布式即时通讯 (IM) 系统理论架构方案 》
《 从零到卓越:京东客服即时通讯系统的技术架构演进历程 》
《 蘑菇街即时通讯 / IM 服务器开发之架构选择 》
《 腾讯 QQ1.4 亿在线用户的技术挑战和架构演进之路 PPT 》
《 微信后台基于时间序的海量数据冷热分级架构设计实践 》
《 微信技术总监谈架构:微信之道--大道至简 (演讲全文) 》
《 如何解读《微信技术总监谈架构:微信之道--大道至简》 》
《 快速裂变:见证微信强大后台架构从 0 到 1 的演进历程(一) 》
《 17 年的实践:腾讯海量产品的技术方法论 》
《 移动端 IM 中大规模群消息的推送如何保证效率,实时性? 》
《 现代 IM 系统中聊天消息的同步和存储方案探讨 》
《 IM 开发基础知识补课 (二):如何设计大量图片文件的服务端存储架构? 》
>> 更多同类文章 ......
[2] 有关 IM 安全的文章:
《 即时通讯安全篇(一):正确地理解和使用 Android 端加密算法 》
《 即时通讯安全篇(二):探讨组合加密算法在 IM 中的应用 》
《 即时通讯安全篇(三):常用加解密算法与通讯安全讲解 》
《 即时通讯安全篇(四):实例分析 Android 中密钥硬编码的风险 》
《 即时通讯安全篇(五):对称加密技术在 Android 平台上的应用实践 》
《 即时通讯安全篇(六):非对称加密技术的原理与应用实践 》
《 传输层安全协议 SSL/TLS 的 Java 平台实现简介和 Demo 演示 》
《 理论联系实际:一套典型的 IM 通信协议设计详解(含安全层设计) 》
《 微信新一代通信安全解决方案:基于 TLS1.3 的 MMTLS 详解 》
《 来自阿里 OpenIM:打造安全可靠即时通讯服务的技术实践分享 》
《 简述实时音视频聊天中端到端加密(E2EE)的工作原理 》
《 移动端安全通信的利器--端到端加密(E2EE)技术详解 》
《 web 端即时通讯安全:跨站点 WebSocket 劫持漏洞详解 (含示例代码) 》
《 通俗易懂:一篇掌握即时通讯的消息传输安全原理 》
>> 更多同类文章 ......
[3] IM 开发综合文章:
《 IM 开发基础知识补课:正确理解前置 HTTP SSO 单点登陆接口的原理 》
《 移动端 IM 中大规模群消息的推送如何保证效率,实时性? 》
《 移动端 IM 开发需要面对的技术问题 》
《 开发 IM 是自己设计协议用字节流好还是字符流好? 》
《 请问有人知道语音留言聊天的主流实现方式吗? 》
《 IM 消息送达保证机制实现 (一):保证在线实时消息的可靠投递 》
《 IM 消息送达保证机制实现 (二):保证离线消息的可靠投递 》
《 如何保证 IM 实时消息的 "时序性" 与 "一致性"? 》
《 一个低成本确保 IM 消息时序的方法探讨 》
《 IM 单聊和群聊中的在线状态同步应该用 "推" 还是 "拉"? 》
《 IM 群聊消息如此复杂,如何保证不丢不重? 》
《 谈谈移动端 IM 开发中登录请求的优化 》
《 移动端 IM 登录时拉取数据如何作到省流量? 》
《 浅谈移动端 IM 的多点登陆和消息漫游原理 》
《 完全自已开发的 IM 该如何设计 "失败重试" 机制? 》
《 通俗易懂:基于集群的移动端 IM 接入层负载均衡方案分享 》
《 微信对网络影响的技术试验及分析(论文全文) 》
《 即时通讯系统的原理,技术和应用(技术论文) 》
《 开源 IM 工程 "蘑菇街 TeamTalk" 的现状:一场有始无终的开源秀 》
《 QQ 音乐团队分享:Android 中的图片压缩技术详解(上篇) 》
《 QQ 音乐团队分享:Android 中的图片压缩技术详解(下篇) 》
《 腾讯原创分享 (一):如何大幅提升移动网络下手机 QQ 的图片传输速度和成功率 》
《 腾讯原创分享 (二):如何大幅压缩移动网络下 APP 的流量消耗(上篇) 》
《 腾讯原创分享 (二):如何大幅压缩移动网络下 APP 的流量消耗(下篇) 》
《 如约而至:微信自用的移动端 IM 网络层跨平台组件库 Mars 已正式开源 》
《 基于社交网络的 Yelp 是如何实现海量用户图片的无损压缩的? 》
>> 更多同类文章 ......
来源: http://www.52im.net/thread-1366-1-1.html