今天在某个即时通讯的群中无意看到这么一句话:
不由问自己,什么是读扩散?什么是写扩散?感觉这两个词昨天才看的,怎么今天就忘了?翻翻工作记录,原来是在去年10月份接触到的。并且确认过眼神,在群聊里,我使用的是读扩散。
所谓读扩散,就是**存储一次,多次读。
所谓写扩散,就是存储多次,各自读**。
这样说,还是有点抽象。把它们放到群聊的场景里说吧。
读扩散,群里的每条消息只存储一份,群成员读取同一份数据。
优点:
- 数据实时性高;
- 写入逻辑简单;
- 节约存储空间。
缺点:
- 数据读取会存在热点问题;
- 需要维护离线群成员与未读消息的关系。
写扩散,群里发一条消息,给每个群成员都存储一份,群成员各自读自己的那一份。
优点:
- 控制逻辑与数据读取逻辑简单;
- 用户数据独立,满足更多的业务场景,比如:回执消息、云端删除等等;
- 一个数据点丢失,不影响其他用户的数据点。
缺点:
- 存储空间的增加;
- 写扩散需要专门的扩散队列;
- 先写扩散后读,实时性差。
在平时的数据存储设计中,是读扩散还是写扩散,还是非常拷问灵魂的。
例子1:
用户表不仅存储了职位的唯一标识,还冗余了职位名称,这是读扩散还是写扩散呢?毫无疑问,只要是信息的冗余,为了查询方便多写了一份,都是写扩散。查询方便了,写操作就不那么方便了,各有取舍吧。
例子2:
群聊中的信息,群信息在服务器端只存储一份,在线和离线的群成员都读这一份。除此之外,还需要维护一个群成员与消息的对应关系,给离线的群成员使用,离线的成员上线后,拉取未读消息,拉取消息后再移除群成员与消息的对应关系。这是读扩散。
例子3:
朋友圈,有着和群聊类似的问题。一个用户在朋友圈发了新消息,对于他的好友,在拉取信息时是采用读扩散呢,还是采用写扩散呢?根据朋友圈信息的偏序关系。每次拉取新的信息时,都需要把本地朋友圈的最后一条信息的时间戳提交给服务器,只拉取大于这个时间戳的信息。如果想拉取旧的信息呢,也是提交时间戳,根据时间戳进行降序排序,就可以把该时间戳之前的信息按指定条数拉取下来。这次我还是采用了读扩散。
最后总结
读扩散和写扩散,已经不是什么新鲜概念了。没有完美的解决方案,只有最合适的解决方案,在使用时需要反复衡量,各有取舍。也可以试一试读扩散和写扩散的结合,那又会是一种什么样的情况。期待下次遇到这样的业务场景。








网友评论