6

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

 2 years ago
source link: http://yunxin.163.com/blog/52im-13/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议 - 云信博客

> IM SDK > IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

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

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

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

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

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

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

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

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

2、相关文章(详情参见即时通讯网)

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

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议_1.png

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

一般来说:

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

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

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

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

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

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

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

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

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议_2.png

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

一般来说:

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

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

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

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

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

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

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

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

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

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议_3.png

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

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

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

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

6、简单小结

典型的大型互联应用架构中,服务端数据库架构主要使用以下两种:

  • 使用“分组”架构实现数据库读写分离:解决“数据库读性能瓶颈”问题;
  • 使用“分片”架构实现数据库水平切分:解决“数据库数据量大”问题。

但对于互联网大数据量、高并发量、高可用要求高、一致性要求高、前端面向用户的业务场景,使用微服务缓存架构,很多时候可能比数据库读写分离架构更合适。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK