每一分钟写入 10 万行数据,有啥好的方案吗?

2020-07-23 21:29:41 +08:00
 goodspb
这 10 万数据在接下来的 2 分钟还要操作( update )

当然 db 是 mysql,应用是 spring boot
11389 次点击
所在节点    程序员
96 条回复
lff0305
2020-07-24 11:45:09 +08:00
MQ + Prepared Statement (需要比较新的 MySQL)
securityCoding
2020-07-24 11:52:43 +08:00
字面意思拍脑袋的想法是
1:mq 做分发负载
2:batch insert
594duck
2020-07-24 11:54:10 +08:00
@qiayue 不要忽视 了还有一个 update 操作,update 操作必然要 select 。他这写入量肯定不能开索引 了,但是不开索引 就是全表扫描再 update 。其实这量级就算是开了索引也没用,因为 select update 。这 select 超过千条自动变成全表扫描( mysql 机制)。所以

阿里的 DRDS 方案是可以行,前面开 32G DRDS,后面开 20 个数据库。百库百表。一年烧掉 100 万在数据库上,保他平安。

我不是吹牛,物流企业都这么干的。结果一算 TCO,5 年 TCO 还是 Oracle 便宜了。
zzzmh
2020-07-24 11:56:47 +08:00
mysql 可以做到的,但建议批量插入,目前框架我试了都是单条插入,这种建议 jdbc 自己写 sql,一次 10W 都行。另外 mysql 有几个参数配置,具体哪几个需要百度,可以把写入 IO 提升到 100MB/S
byzf
2020-07-24 11:58:58 +08:00
查了下自己的数据库, 不看峰值的话, 只有你说的 2%-3%的数据量, 我用的腾讯云 1 核 1G 内存的数据库, cpu 峰值 4%左右.

所以我觉得你这个数据量扩大个十倍, 应该也不需要系统优化, 换个 4 核的机器就够了.
byzf
2020-07-24 12:10:45 +08:00
@594duck 我觉得可以开索引... select 超过千条自动变成全表扫描是啥机制, 该走索引的还是走索引啊.
reliefe
2020-07-24 12:30:03 +08:00
-> 有一个业务,如果用户开启了就需要每分钟给他生成一条数据。所以 10 万是我看实际用户量的预估值。
-> @MintZX 还真的是 24 小时,需求内容就是这样。不过当然了,最后每个人保留后 100 条数据,数据可以清理

这种业务通常不那么重要,数据不一定非要落库。落库也可以,当个备份。

直接用 Redis 的 list,还能保证每人 100 条数据。
hurrytospring
2020-07-24 12:31:33 +08:00
这不是 iot 的常见场景吗,,不过别人都用的时序数据库。。
love
2020-07-24 12:36:57 +08:00
每个用户只用前 100 条?那还为啥要用 mysql ?全放内存就行
947211232
2020-07-24 12:52:13 +08:00
偏题了,楼主问得不好,应该说出应用场景,全楼被楼主带歪
594duck
2020-07-24 13:22:04 +08:00
@byzf 索引 开了会严重影响写效率。

MYSQL 至少在 5.x 版本的时候索引扫描一旦超过好像 1000 个就会转为全表扫描。这个坑 之酸爽。
9684xtpa
2020-07-24 14:13:14 +08:00
那个我来说两句

其实看楼主的描述,这个场景并不清楚
首先,DB 写入 1 分钟 10W 问题不大
然后,每个用户就取 100 条,那么 100 条前面的数据怎么处理
其次,还有 update 的场景又是啥

比如说,数据不需要完全的持久化,历史数据不会再使用,我走 redis 的 zset 就能搞定

再比如说,更新计数的场景,那么你先做一下聚合,然后再去更新,这样就可以降低 DB 的写

如果是全量数据都会用到的话,估计就得做分库分表了


总而言之,在楼主一个模棱两可的需求面前,你是没法给出合适的方案的
zh1997
2020-07-24 14:17:57 +08:00
楼主是什么场景, 数据量大, 还频繁 update ?
特别想说这个需求不要接
2kCS5c0b0ITXE5k2
2020-07-24 14:20:49 +08:00
最后每个人保留后 100 条数据,数据可以清理 那为什么一定要入库呢...
csl1995
2020-07-24 14:26:07 +08:00
@594duck

应该不是固定超过 1000 个转全表扫描,而是因为索引扫描成本比全表扫描高。
查询优化器根据成本计算选择执行计划的时候,如果你不走索引覆盖或者聚簇索引,需要获取的数据比较多,每次获取都需要根据指针再去做磁盘找数据,导致索引扫描的 cost 比全表扫描的 cost 还高。所以查询优化器选用全表扫描作为执行计划。
你可以用 optimizer trace 对比不同方案的 cost 计算。
E0
2020-07-24 14:35:11 +08:00
X Y problem?
lenmore
2020-07-24 14:39:26 +08:00
我理解这应该是定时任务触发来插入数据的,
那么可以考虑将 10w 个用户的写入作为一个或几个事务来做,也还可以合并这些 insert,比如一次插入 1w 行,这样效率就高很多了。
zh1997
2020-07-24 14:43:10 +08:00
如果只是 2 分钟内才修改的话,可以用 mysql 存最近 5 分钟的数据,定时归档到时序数据库
kalista
2020-07-24 15:22:25 +08:00
我理解这么频繁更新的数据,可以先放内存里面吧
cloverzrg2
2020-07-24 15:32:31 +08:00
有点好奇为什么这么多数据,会不会 1000 条数据里面只有几条是有价值的

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

https://tanronggui.xyz/t/692634

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

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

© 2021 V2EX