Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

每日百万数据量的订单表如何导出到excel

需求是这样的:系统每日会产生上百万的成交订单,客户需要每天导出一份给他们,因此需要每天生成一份大数据量的excel。

首先想到的就是在定时任务中通过for循环分页访问数据库,然后分批导出到excel。但是for循环中访问数据库,如果测试不充分或者程序有bug会导致频繁访问数据库,会严重影响数据库的性能。其实在循环中访问数据库本来就是一种不好的习惯。

不知道各位大佬有什么好的方案或者建议吗?在这里先感谢了。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

其实看了题主的问题以及其他回答下面题主的回答,我貌似get到了题主的想法

总得来说就是觉得数据已经存进去了,但由于导出excel,需要再循环查询数据读出来,感觉有点"多此一举",这个多此一举导致了循环访问数据库,对此感到不安

那我提供一种思路,不一定能解决你的问题,但是或多或少是一种思路叭

即:能不能在插入订单数据的同时也能发个通知,也就是做个消息中间件,这样消费者就是execl导出服务,读取消息直接此时就写入到excel

当然那肯定要准备一个消息中间件了,看你百万的数据量,肯定kafka没跑了,至于如何往kafka里扔消息,这里面有两种方案可以提供给你

  1. 在插入订单的代码中新增一个消息发布
  2. 做数据库的CDC(Change data capture)处理,也就是数据库的数据变更捕捉处理

方案1 那就是很简单啦,直接加代码,但是呢由于要在之前的逻辑里加东西,那就不好说了,毕竟开闭原则嘛,修改以前的逻辑势必会带来一些风险

方案2 这就基本不用改以前的代码了,毕竟做的是CDC,当然不知道你们用的什么数据库,那CDC的具体方案就不一样了,如果以mysql举例,当然是基于它的binlog来做处理咯,随便搜一搜一大堆,你可以自己造轮子,也可以用别人早已经造好的,当然造好的确实需要花一些代价去学习啦。不过呢不用硬生生修改之前的逻辑,主要就是去解析增量的数据库日志就可以了

当然也许你会问,主动去解析日志文件跟去循环查询数据库不是还是差不太多么?

no no no,有些数据库是支持响应式的操作的,就是你主动查和数据库主动推送给你的区别,比如解析mysql binlog的工具Maxwell,好家伙,它就是伪装成Slave,这不就可以从Master节点获取到binlog了嘛,从而再发出来,如果发给kafka,你再做一个消费者服务,不就可以了么

总之CDC是一种数据集成方法吧,不同数据库实现CDC的方法并不相同,当然其实早已经有一个库整合了不少主流数据库,然后集成了自己一套CDC的接口,你可以去看看debezium,不过这玩意儿,我自己装起来很头大,后面公司最终的方案也没有用debezium,还是找到了我们自己使用的数据库的官方响应API完成的

仅做参考吧,我也不知道对你有没有帮助,不过最后提一嘴,题主你提到:"频繁访问数据库,会严重影响数据库的性能"
影响性能根本原因就是读写操作是一个库嘛,所以你也可以考虑分库啊,读写分离啊,是吧,就是导出专门是一个只读从库就可以了嘛,和主库分开部署,这样即使你现在这样做,频繁访问数据库其实影响也不大,如果还有很大影响,说明你从库的机器配置太低了。。。叭


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...