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

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

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

10476 次点击
所在节点    数据库
88 条回复
fengjianxinghun
2022-09-29 11:37:33 +08:00
实时查询用 ES ?都是 ppt 架构师?
fengjianxinghun
2022-09-29 11:38:00 +08:00
@fengjianxinghun 还是都是个位数并发?
hahasong
2022-09-29 11:43:27 +08:00
肯定用 hbase 我之前就做过这个。消息都是时序写入,hbase 轻松无压力。只有硬盘到位,永久存都行
microxiaoxiao
2022-09-29 11:47:07 +08:00
2 亿条消息也不大吧,直接存内存相关的数据库吧。持久化随便选一个。200000000*1k/1024/1024/1024=190GB 。图片,视频另外存
tt67wq
2022-09-29 11:51:05 +08:00
热 tidb + 冷 hbase
helloxiaofan
2022-09-29 12:01:12 +08:00
MySQL 不行吗,我们之前每天 400w 左右,可以分库分表
shot
2022-09-29 12:25:50 +08:00
建议参考头部玩家的技术选型,比如 Discord 的数据库迁移历程:MongoDB → Cassandra → ScyllaDB

《 How Discord Stores Billions of Messages 》
> In July, we announced 40 million messages a day, in December we announced 100 million, and as of this blog post we are well past 120 million.
> The messages were stored in a MongoDB ……, we reached 100 million stored messages and…… see the expected issues appearing: the data and the index could no longer fit in RAM and latencies started to become unpredictable.
https://discord.com/blog/how-discord-stores-billions-of-messages

《 Discord Chooses ScyllaDB as Its Core Storage Layer 》
https://www.scylladb.com/press-release/discord-chooses-scylla-core-storage-layer/
cp19890714
2022-09-29 12:37:57 +08:00
首先排除 clickhouse 。clickhouse 主要用于 OLAP ,不适合 OLTP 。并发能力很弱,不适合你的场景。
mongodb 分片、写入并发、数据压缩、数据过期自动清理 都挺适合你的场景。数据量 2 亿真不多。
ES 我只是简单使用过,没有太多了解。不过,实时查询好像不是太快,而且服务器成本比 mongodb 高。
cp19890714
2022-09-29 12:39:22 +08:00
@cp19890714
不过,如果要做聊天记录查询,那么全文索引又必然是用 ES 了
defage
2022-09-29 13:01:28 +08:00
clickhouse 肯定是不合适的,这种端上的场景不是 clickhouse 的场景。
数据量级一大,要考虑综合做法,不一定是单个存储。 比如 db 分表+hbase 存详情,用户维度的列表从 db 查,详情回表用 hbase 构建出来。
liuhan907
2022-09-29 13:12:09 +08:00
@monkeydream 所以你是要做 IM 消息存储和消息本身的检索?那这个 2E 的量基本随便了吧,拿个 pgsql 硬件规格拉高一些单机大概都够。不放心就找一个分布式数据库一把梭。
guanhui07
2022-09-29 13:38:11 +08:00
tidb
polardb
NoString
2022-09-29 13:40:06 +08:00
hbase

上 clickhouse 不可能的,你可以试试 ck 对并发支持。聊天记录你查详情又不聚合去重计算,选他干啥
lmmlwen
2022-09-29 13:50:26 +08:00
hbase 这些没现成的就没必要,毕竟你一天也就 100w ,只存 6 个月
wellsc
2022-09-29 13:58:58 +08:00
映射存就行了,kv 存消息尸体和 id ,量不大
dog82
2022-09-29 13:59:19 +08:00
IM 要做好非常难,存储只是难点之一

有条件的就买吧,腾讯云、网易云都有 IM 产品
yty2012g
2022-09-29 14:05:11 +08:00
CK 不太 ok ,ck 是 OLAP 引擎,QPS 不能太高,而且关联性能不太行。
第一想法是 ES
WebKit
2022-09-29 14:22:52 +08:00
@superbai 云服务厂商的消息不给保存的。保存费用更高。而且定制化太差了
wxf666
2022-09-29 15:15:59 +08:00
@monkeydream 我大概算算 MySQL 单表,受限于 IO 的读并发吧:

假设:
- B+ 树 4 层 *(若 InnoDB 、Dynamic 、16 KB 每页、8 字节主键、1 KB 一条消息,可容纳 110 亿)*
- 缓存前两层 *( 14 MB 内存代价)*
- 有 `(uid 4 字节, time 5 字节)` 索引
- 每个用户每次获取不超过 700 条消息 *(此时索引只需读一个叶节点)*
- **不缓存实际消息** *(就当所有用户都在获取历史消息吧。因为每个叶节点可能存着 15 个不同用户的消息,太散了,不会算『每次一个用户获取一堆消息时,能利用上多少缓存』,直接按最差情况算)*


设每秒有 x 人请求,平均每人有 y 条消息要获取,硬盘有 z 个 16 KB 的 IOPS ,那么:

2x (每人消耗 2 次 IO 去索引读取自某个时间以来的消息 ID 列表) + 2xy (每条消息都要 2 次 IO 去消息表读取) <= z


如,我的垃圾固态,16 KB 有 25000 IOPS (也就 400 多 MB/s )。那么:

每秒 100 人要获取消息时,平均每人能得到(不在缓存中的) 124 条历史消息?


(数据库新手,算的不对,恳请指出)
la2la
2022-09-29 15:29:00 +08:00
不考虑时序数据库么,本地缓存加线上时序数据库持久化。理论上线上存储的消息应该是加密的的吧?

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

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

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

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

© 2021 V2EX