默认
打赏 发表评论 5
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议
微信扫一扫关注!

本文正文部分引用了58同城架师沈剑的文章,非常感谢他的分享。


1、前言


IM应用从服务端数据的角度来看,它是一种很特殊的应用场景,抛开基础数据、增值业务和附属功能不谈,单从IM聊天工具的立身之本——聊天数据来说,理论上是不需要在服务端存储的(或者说只需要短暂存储——比如离线消息,上线即拉走),这也是为什么微信在前段时间号称绝不存储用户聊天数据的原因(从技术上说这不是没有道理的,但到底有没有存储,这已经超越技术范畴了,不在此文讨论之列 ^_^)。

那么为什么说IM系统的服务端从技术上说,是不需要存储聊天数据的呢?

原因很简单,我们知道IM的聊天数据分两种:

  • 一种是实时消息(就是你在线,对方也在线情况下的聊天数据交互);
  • 一种是离线消息(就是你在线,对方不在线时,你发过去的消息,对于对方而言就是离线消息了)。

实时消息的收发:服务端只作为中转角色(关于中转的技术问题,很多人可能还在结纠老思维为何不用P2P,我已经论坛说烂了,说白了跟技术无关,其实一个很重要的原因就是为了运营的可控性:比如用户P2P去了,违法的锅你运营方来背好不好?),聊天消息在此时就相当于左手倒右手——即聊天数据的本质就是从A用户经过服务端到达B用户就完了,服务端完全没必要存储(当然,我们讨论的是技术理想情况,实际上抛开技术因素来说,这么多丰富的用户行为数据你是运营方你会放过吗?但,这跟技术无关对吧)。

离线消息的收发:当接收方不在线时,发送方的聊天数据在服务端只需要作短因果报应存储,因为接收方一旦上线就拉走了,服务器删除即可(注意:从技术上来说就是这样的哦)。对用户而言聊天消息的社会学的本质来说就像两个人在对话,我已经听见你说的就好了,干吗老像复读机一样一遍一遍一说给我听?

正如上述所言,IM系统中最重要的聊天数据从技术上不说其实是没有存储的必要的。不过话虽如此,但一个大型的IM系统的方方面面数据量也是很可观的,所以开发IM系统时讨论服务端数据库的读写分离、水平分表等,是很有必要的。因而通过本文快速理解服务端数据库的读写分离原理你不应错过,本文也同时建议您在正确理解它的前提下再慎重决定您的服务端架构方案是否需要数据库读写分离,因为很多时候增加缓存策略就能解决的问题,就没有必在大炮打蚊子了。

好了,费话多说了几句,我们开始阅读正文。

2、相关文章


跟IM数据存储架构有关的文章,有如下几篇,或许对你有用:


IM开发干货系列文章适合作为IM开发热点问题参考资料(本文是其第12篇):


如果您是IM开发初学者,强烈建议首先阅读《新手入门一篇就够:从零开发移动端IM》。

3、什么是数据库读写分离?


1.png

如上图所示,一主多从、读写分离、主动同步,是一种常见的数据库架构。

一般来说:

  • 主库——提供数据库写服务;
  • 从库——提供数据库读服务。

主从库之间,通过某种机制同步数据,例如mysql的binlog。

像上述图中这样,一个主从同步集群通常被称为一个“分组”。

那么,数据库“分组”架构究竟解决什么问题?

大部分互联网业务读多写少,数据库的读往往最先成为性能瓶颈,如果希望:

  • 线性提升数据库读性能;
  • 通过消除读写锁冲突提升数据库写性能;
  • 此时可以使用分组架构。

一句话总结:“分组”主要解决“数据库读性能瓶颈”问题,在数据库扛不住读的时候,用“分组”架构实现读写分离,通过增加从库线性提升系统读性能。

4、什么是数据库水平切分?


2.png

如上图所示,跟数据库“分组”架构实现读写分离一样,水平切分(也称大表拆分、分表),也是一种常见的数据库架构手段。

一般来说:

  • 每个数据库之间没有数据重合,没有类似binlog同步的关联;
  • 所有数据并集,组成全部数据;
  • 会用算法,来完成数据分割,例如“取模”;

一个水平切分集群中的每一个数据库,通常称为一个“分片”。

水平切分架构究竟解决什么问题?

大部分互联网业务数据量很大,单库容量容易成为瓶颈,如果希望:

  • 线性降低单库数据容量;
  • 线性提升数据库写性能;
  • 此时可以使用水平切分架构。

一句话总结:数据库水平切分架构主要解决“数据库数据量大”(或者更细一点说是单表数据量太大)问题,在数据库容量扛不住的时候,通常水平切分。

5、数据库读写分离虽好,但不应滥用


对于互联网大数据量、高并发量、高可用要求高、一致性要求高、前端面向用户的业务场景,如果数据库读写分离:

  • 数据库连接池需要区分:读连接池,写连接池;
  • 如果要保证读高可用,读连接池要实现故障自动转移;
  • 有潜在的主库从库一致性问题。

3.png

实际上,如果您的系统面临的是“读性能瓶颈”问题,增加缓存可能来得更直接,更容易一点。

另外,从成本上说,从库的成本比缓存高不少。而且对于云上的架构,以阿里云为例,主库提供高可用服务,从库不提供高可用服务,实现方案上更主流。

所以,上述业务场景下,建议使用缓存架构来加强系统读性能,替代数据库主从分离架构。

当然,使用缓存架构的潜在问题:如果缓存挂了,流量全部压到数据库上,数据库会雪崩。不过幸好,云上的缓存一般都提供高可用的服务。

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是如何实现海量用户图片的无损压缩的?
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?下一篇:请问有 IM 的tcp网关服务器这个说法吗?方案是怎样?

本帖已收录至以下技术专辑

推荐方案
评论 5
赞群主!
签名: 秋天到了,终于凉快了
分片也可以提高性能,主要是通过减小数据表锁的粒度来达到的吗?对于分组,不仅仅可以提高读写性能,容灾也是很重要的一项,
对于读性能,以上两者都不及增加缓存,毕竟缓存是直接读内存,分组还是直接去读数据库,读磁盘。
不过数据库内部也是有读缓存的吧?不太了解,如果数据有缓存,那么缓存是多大,和自己做的前置缓存有什么区别呢?
感谢楼主指教!
引用:x931609201 发表于 2018-01-31 20:09
分片也可以提高性能,主要是通过减小数据表锁的粒度来达到的吗?对于分组,不仅仅可以提高读写性能,容灾也 ...

说白了就是让你能用redis、memcache 这些的就尽量用,就是这个意思
精辟
签名: 心情好
群主厉害啊 写的很详细
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部