如何在多CPU核心上并行运行jq提升大JSON文件处理速度
NDJSON 并行处理轻量方案
你原脚本速度拉胯的核心原因根本不是jq性能差,是while read逐行读+每行单独fork一次jq进程的写法搞出了极高的额外开销——光进程创建、管道IO的消耗就占了90%以上。哪怕你不做并行,直接把脚本改成jq -c '{some-tansfomration-logic}' input.json > output.json,单进程速度都能到每秒200行左右。
配合你手上的16核vCPU,根本用不着Hadoop这类重框架,用基础shell工具就能轻松摸到每秒2000行的处理速度,远超过你要的每秒600行的要求,1700万行的文件两三个小时就能跑完,且不需要保证输出顺序。
方案1:GNU Parallel(最省事,无额外临时磁盘占用)
GNU Parallel是专门做shell任务并行的轻量工具,GCP标准系统镜像可直接通过包管理器安装:
# Debian/Ubuntu系直接执行,其他发行版换对应包管理器命令即可 sudo apt install -y parallel jq
直接执行以下命令即可,不需要修改你原有的jq转换逻辑:
cat input.json | parallel --no-notice --pipe -j 16 --block 100M 'jq -c "{some-tansfomration-logic}"' > output.json
参数说明:
--pipe:按块切分输入流,逐块喂给后面的jq命令,不会破坏NDJSON的行结构-j 16:启动16个并行进程,刚好吃满16个vCPU核心,如果跑的时候观察到有IO空闲,可以调到20-24,性能还能再提--block 100M:每个任务块大小设为100MB,6GB文件总共切60个左右的块,既不会因为块太小导致频繁fork进程增加开销,也不会因为块太大导致核心负载不均- 不需要手动用
>>追加输出,Parallel会自动收集所有子进程的输出写入目标文件,不会出现JSON行截断、混行的问题
方案2:零额外依赖方案(仅用系统自带工具)
如果不方便安装Parallel,用系统自带的split切分文件+后台多进程处理即可,缺点是需要预留约12GB的临时磁盘空间(存放切分的源文件块+临时结果块):
# 把6GB的input.json平均切为16个不拆行的分片,分片前缀为ndjson_part_ split -n l/16 input.json ndjson_part_ # 启动16个后台jq进程,同时处理分片,结果写入单独临时文件 for part in ndjson_part_*; do jq -c '{some-tansfomration-logic}' "$part" > "${part}.res" & done # 等待所有后台处理任务完成 wait # 合并所有临时结果为最终输出 cat ndjson_part_*.res > output.json # 清理临时分片文件 rm -f ndjson_part_*
性能参考
- 优化后的单进程jq直接处理NDJSON,速度约为每秒180-220行,已经比你原来的逐行fork脚本快6倍以上
- 16核并行后,实际处理速度约为每秒1800-2500行,1700万行总耗时约2小时,远高于你要求的每秒600行的目标
内容的提问来源于stack exchange,提问作者stkvtflw
相关产品推荐
相关产品推荐

