关于“海”量数据的操作的一些坑和注意事项
程序员文章站
2022-07-12 16:37:46
...
关于“海”量数据的操作的一些坑和注意事项
一、前提
说海量数据,其实不算,只是每天大概入库5万条左右,要做一个历史分析,但长期积累下来数据量还是恐怖的,跟产品争了半天最终确定下来只查询半年的数据,峰值大概600万左右,测试的时候洗进去了400万测试数据,结果还是没预计到,测试数据库干挂了,所以在此记录一下以防以后再犯,接下来主要说一下问题出在哪以及有什么样的替代方案,先上一张图来看一下效果
二、功能介绍
上图左侧以及头部是查询条件区域,右下为结果区域,查询条件大概有30个左右,结果大概40列左右,首先查询不是什么大问题,大概一天就整理写完了,问题出现在了洗数据、以及查询性能上面,首先我们来说洗数据的优化
2.1洗数据进阶
以前mongo表里面大概20列左右,我要再洗进去50列左右,数据量270万,需要从各个不同的历史表里面去拿数据,每同步一条要查6张表组合,插入到mongo里面,单条循环用时13ms,所以同步下来需要十来个小时,然后觉得时间太久,如果出错重新跑的代价太大
①首先是把6张表的历史数据缓存到redis(有些表数据量大直接缓存到redis的话也需要很久,所以就采用懒加载的模式,一边执行 一边缓存,然后再碰到相同的key则不需要再查数据库)
②把数据量小的表直接放到内存里面
③然后每次往mongo insertAll一万条数据
④然后又开了8个线程
最后把时间压缩到了2个小时。
2.2查询数据进阶
然后就到了查询的阶段,是要去mongo里面查询(不要问问什么要存到mongo,历史原因),发现查询特别慢,最后定位到了是countd的问题,于是前台在请求的时候发三次请求
①查询列表
②查询报价高估、低估条数
③查询当前条件的总数
以为这样就解决了,但是没想到问题更大了,虽然查询的时候列表返回特别快,但是剩下的两个查询真的不敢恭维 200万数据要count十几秒,但是由于左侧查询条件每次点一下就触发请求,请求堆积导致mongo压力特别大,最后整个项目需要访问mongo的功能都特别慢然后超时,于是测试环境的mongo就这样挂了,但是临近上线了,于是连夜切换到mysql,写了一晚上洗数据的查询数据的功能,使用 jpa 一次insert一万条,大概两个小时跑完,但是第二天在测试的时候由于查询条件比较多实际count还是很慢,需要10秒左右,大家商量了半天 最终使用现有技术结构是没办法的,于是老板拍板历史数据只提供一周的数据,于是数据量降低到25万左右,压测也能扛住了,挺好,最终采用的还是mongo数据库
2.3查询数据进阶
到上线的时候要从原数据里面查出最近一周的洗到新表中,于是就按天查询数据,mongo按天存储(每次存储5万),然后8线程,同时存储25万,没想到服务器直接崩了,所以又单线程跑完结束
三、总结
刚开始就是因为数据量大、要求产品只查询半年数据,不想每次查询查那么多张表影响效率然后就把数据冗余到一张表,又因为数据量大 所以按照筛选条件分成三张表,结果最后数据量还是超过预期,所以经过这一个项目,知道了 mongo 的存储性能一次insert 一万 两万 五万都没问题,mongo的count效率有多低,mysql的insert 一次一万条差不多,两万三万估计就扛不住了, 对比了mongo、mysql的查询,线程的控制 等等,非常感谢有这样的一个机会去锻炼学习,谢谢 以后再接再厉
上一篇: 致这个时代的我们 算法生活互联网
下一篇: 大数据入门基础之linux