一分钟多进程百万数据导出到csv并上传到oss

需求

  1. 产品要导出某个团队某些用户的步行日志到csv文件里,并且要在一个文件内,而且速度要快不能太耗时间。

问题

  1. 日志往往意味着数据量大。
  2. 要导在一个文件内,数据量虽然大也能解决,无非就是分页查询并写入csv。
  3. 速度快时间短,也能解决无非就是多进程导出多个文件,没有什么难的,但是需求是一个文件!

解决思路

  1. 先查询出要导出的数据总量
  2. 投入到批次队列里面启动多个消费者查询并写入到多个csv里面。
  3. 投递队列时记录每个队列写入的csv具体路径和文件名称。
  4. 利用批次队列的特性在执行完毕时,把上一步记录的多个csv按照顺序合并到一个csv里面
  5. 合并完成之后,删除合并前的多个csv,保留合并的csv并上传到oss

结果

经过测试50多万数据,批次队列里面每个队列分配5万条数据去处理,走完一个流程耗时不到一分钟,这种方式有多快取决于服务器能启动多少个消费者多少个进程,我测试时用的是自动策略,最高是同时8个消费者在执行。

一分钟多进程百万数据导出到csv并上传到oss

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 31

其实还有一个优化点。那就是OSS不是支持字符串上传嘛。你直接将本地合并的功能,通过OSS来实现,这样不就把本地文件合并的时间给省下来了么。就是不知道这玩意能省下几秒钟了。 :joy:

1年前 评论
LXK (楼主) 1年前
mowangjuanzi (作者) 1年前

或许可以换个思路,用python(其他语言也可以,总之是运行在本地电脑)写个客户端脚本实现这个功能。 通过 laravel 广播, 或者 python 直接连线上 Redis 然后通过发布订阅接收消息(不推荐, 这样服务器安全组需要放行 6379 端口, 有一定安全隐患 )。 当导出事件触发时,laravel队列直接发送消息给 python 客户端, 然后 python 处理完之后 通过 ossutil64 或者 OSS python SDK 上传。 这样的好处就是不受服务器性能限制。 而且可以很方便的在客户端再搞一个多线程。 并且办公室加一台电脑的成本比线上加一台服务器成本低的多。

1年前 评论
徵羽宫 (作者) 1年前
LXK (楼主) 1年前
24K大白羊 1年前
徵羽宫 (作者) 1年前

放代码或者写个文档来大家学习一下嘛

1年前 评论
LXK (楼主) 1年前
西巴以及 (作者) 1年前
LXK (楼主) 1年前
CodingHePing

用swow哇

1年前 评论
LXK (楼主) 1年前
CodingHePing (作者) 1年前

你的需求真这么简单的话,我觉得 MySQL 自己的 select into outfile 更简单和直接。虽然没测过,但应该效率不会差。

1年前 评论
LXK (楼主) 1年前

好吧,还有一个方案就是,查询数据的sql 也可以在 go func 中执行。 多启几个 go func ,按 id 制去查。每个 go func 查 5万行或者10万行。一般我们的 id 都是顺序的,这样能查全也不会重。 这样分布式的查写传效率应该还能高一点。

1年前 评论
LXK (楼主) 1年前

用的哪个消息队列,我看官方的queue里面没有开启多消费者一说...代码在码云或者Github分享一下 :joy: :joy:

1年前 评论
LXK (楼主) 1年前
LXK (楼主) 1年前
laravelphp_game (作者) 1年前
laravelphp_game (作者) 1年前
sanders 1年前

只能swoole了,redis队列也不行的,也会慢

1年前 评论
LXK (楼主) 1年前

楼主有没有尝试 xlswriter 这个扩展, 可以对比一下 用时对比 我也是百万数据导出 直接用游标查询 + xlswriter 百万数据也是30s

1年前 评论
LXK (楼主) 1年前
派大旺 (作者) 1年前
LXK (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!