请教一下聊天消息应该用什么数据库存储?

2022-09-29 10:06:43 +08:00
 monkeydream

公司要开发运营聊天功能,估计用户 10w 左右,在线 1w 人,消息每天 100w 以上,需要存储 6 个月左右的消息,差不多 2 亿条,而且考虑到不同终端之间的消息同步,客户端需要频繁的查询聊天数据。 请问针对这样的场景应该选择哪种数据库? 目前考虑 Mongodb 或 Clickhouse ;考虑 mongodb 主要是 mongodb 的分片模式适合存储大量数据、查询也比较快,考虑 clickhouse 主要是其能存储大数据并且查询性能也比较好(但是听说并发不太好,不知道是否适合并发查询要求)。

10482 次点击
所在节点    数据库
88 条回复
paouke
2022-09-29 15:34:33 +08:00
公司有搭好的 hbase 就用 hbase ,没有用 mysql ,mongo 也能撑得住,ck 肯定是不太行,ES 用来全文索引还行,主存储不太行吧
aitaii
2022-09-29 16:21:26 +08:00
clickhouse 1000 个并发撑死了
ThinkCat
2022-09-29 17:02:01 +08:00
前公司用的是 mysql ,后面数据量实在过大,用了阿里的 OTS ,但是这个东西太贵了。IM 的热数据不多的话,可以用 mysql ,做好分表和冷热隔离。其实最好的,是楼上讲的时序数据库,较适合 IM 特性,不过这个没用过。
binge921
2022-09-29 17:21:46 +08:00
查询肯定 es 存储肯定 hbase
flycloud
2022-09-29 17:31:27 +08:00
说用 ES 的真是人才,还全文索引。。。

“客户端需要频繁的查询聊天数据” 意思是用户需要拉取和其他用户会话的聊天消息,而不是去全文索引查询某个关键字。
mongodb shard 再适合不过了,设计好 shard key ,保证两个用户之间的会话消息落入某一个分片中,不同的会话消息均匀分布到各个分片。比如 {sessionId: "hashed", msgId: 1},如果有群聊天也是一样的,分配一个 sessionId ,msgId 递增,以支持按会话批量按序拉取消息。

再设置一个字段自动过期删除。
Huelse
2022-09-29 17:39:14 +08:00
@flycloud #65 搜索聊天记录中的关键词是有这种需求的
flycloud
2022-09-29 17:39:42 +08:00
“频繁的查询聊天数据”

其实很多是无效请求,根本没有新增消息,可以在 redis 中设置标记,真正有新消息时才去读取 DB ,可以很大成都降低 DB 压力。
podel
2022-09-29 17:46:03 +08:00
不如所有的消息都是日志 /FILE 。以时间递增序列进行保存。
服务器只存储。
所有消息查询功能都要根据时间戳,从服务器下载下来 SYNC 后。在本地进行计算。比如说搜索之类的。
(服务器只承担存储功能,不承担任何查询功能)
flycloud
2022-09-29 17:47:23 +08:00
@Huelse 是有这种需求,但是注意审题啊,是客户端查询。
第一种:本地有存储消息,直接客户端本地搜索啊。
第二种:客户端本地不存储消息,应该是没有什么 IM 应用会在所有会话中查询某个关键字吧,而是在某个会话里查询,直接拉取某个会话的历史消息来搜索,不就可以了?

当然也会有在后台查询关键字的情况,多半也是会指定某两个用户之间消息查询。
实在想不出来在所有用户的所有会话里查询关键字这种需求的意义,所以觉得 ES 没有适用场景。
playtomandjerry
2022-09-29 17:55:20 +08:00
@Smilencer 也信
jitongxi
2022-09-29 19:02:39 +08:00
说 es 的确实扯淡的,es 的缓存对于非公用的内容查询, 缓存空间估计就炸裂了。
查询确实只是给客户端做的事,服务端只负责存储。
sunmacarenas
2022-09-29 19:24:32 +08:00
公司有钱就上 SAP HANA
hopingtop
2022-09-29 20:39:50 +08:00
1.如果在都能满足功能的情况下,一定要选择团队熟悉的!!!
2.这里 2 亿数据确实不多,而且也不用依赖 mongodb 本身的分片,可依据时间自行管理分片,这样在扩容很有优势
3.mongodb 在查询方面性能还是很不错的,你的查询场景一般还带有时间限制。
4.楼上也说了参考 头部 ,Discord 当初在 2015 年就选择了 mongodb ,(2022 年的 mongodb 更强大了) 为什么不选择其他?当你数据量真的到达扛不住的量级了,我想肯定是很赚钱的了,这个时候人手和资源又不一样了!很多事情本就不可一步到位。
5.需要频繁查询聊天数据,这个需求一般只是 存在运营这个角色, 如果真到 DB 性能不够,那么你完全可以经过角色同步数据的概念到本地进行查询,然后,如果有必要再去服务器去获取上下文。
WOLFRAZOR
2022-09-29 20:52:05 +08:00
@c332030 这是没做优化的问题吧。优化之后不可能这样的。
zmzeng12
2022-09-29 21:19:14 +08:00
写多读少,又不涉及修改消息。
数量不大用 SQLite ,数量大用 RocksDB 。
RocksDB 的话,服务器存全量 sstable 作为 single of truth ,客户端按需拉取查询时间范围内的 sstable 文件,Client 本地完成查询。
remember5
2022-09-29 22:12:44 +08:00
个人猜测,本地查询 sqllite + 后台 hbase
changdy
2022-09-29 22:59:51 +08:00
clickhouse 去掉 .不是干这个的
其次 时序数据库 了解的不多 .但是 也比较赞同 @joesonw 的说法

es 我觉得有几个问题吧.基于分词,无法保证查询结果 数据难分表. 不分表冷热数据混在一起也有点小问题.


感觉 im 这个场景还是挺大的 ,最好还是和产品一起商量下如何优化 使用体验.
documentzhangx66
2022-09-29 23:08:05 +08:00
淘宝这么多年现成的方案,都不用?

直接按用户进行分库。

首先按用户热度,分为冷热用户集群。

热集群高配置,大内存,SSD 。冷集群低配置,小内存,HDD 。

每个集群由一大堆 Mysql 节点组成,每个 Mysql 节点负责一部分用户。节点散列策略按用户 IO 数量来进行负载均衡。

这样实现了几个好处:

1.对于一个用户,所有数据集中在一台 Mysql 里。

2.实现了基于性价比的冷热数据分离。

3.如果一些 Mysql 节点坏了,只会影响一小部分用户,不会影响整体业务。

4.如果一些用户的冷热度发生变化,方便做自动迁移。

5.每个 Mysql 节点的数据量小,能够支持 LIKE 进行高精度搜索。
djoiwhud
2022-09-29 23:39:50 +08:00
@monkeydream #30 。你的需求选 mysql 或者 pg 就可以了。

热数据放 redis 里面。

实在想折腾新方案,想永久保存聊天记录,考虑 hbase 或者 hive 。本人做过 IM 类的需求产品,我负责的说,这个需求用 es 是个错误。
akira
2022-09-30 00:14:34 +08:00
凡是发帖问方案的 ,一律推荐 用 三方的,例如腾讯的聊天服务 .

光是在线 1w 人这个事情 估计你们就已经要头大了。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/883731

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX