使用 xargs 并行模式安全地将输出重定向到单个文件

使用 xargs 并行模式安全地将输出重定向到单个文件

我有一堆 bzipped JSON 文件,我使用 xargs 并行读取这些文件,进行一些简单处理jq并将输出重定向到文件,如下所示:

# Number of workers is one less than the number of cores
NUM_WORKERS=$(($(nproc) - 1))
NUM_WORKERS=$((NUM_WORKERS > 0 ? NUM_WORKERS : 1))

# List all bzipped files and process them with xargs in parallel
ls *.jsonl.bz2 | \
xargs -n 1 -P ${NUM_WORKERS} -I {} sh -c "bzcat | jq -c '{id,name}'" > output.jsonl

我有一个 12 核处理器,当我运行命令时它们都处于工作状态。但是,我注意到不同工作人员的输出在输出文件中混合在一起:

head -5 output.jsonl
{"id": "0", "name": "Name0"}
{"id": "1", "name": "Name1"}
{"id": "2", {"id": "3", "name": "Name3"}"name": "Name2"}
{"id": "4", "name": "Name4"}
{"id": "5", "name": {"id": "7", "name": "Name7"}"Name5"}
{"id": "6", "name": "Name6"}
{"id": "8", "name": "Name8"}
{"id": "9", "name": "Name9"}

我知道我可以将每个工作人员的输出写入一个单独的临时文件,然后稍后将它们连接起来,但是有没有办法避免上述情况而不需要创建多个临时文件?

谢谢!

答案1

GNU Parallel 创建临时文件,但立即取消它们的链接。

实际上,这意味着如果数据量很小并且每个作业的时间很短,那么这些数据永远不会到达磁盘(您可以使用它iostat -dkx 1来查看它是否发生)。

由于如果机器崩溃,未链接的文件将无法恢复,因此智能文件系统可以选择不浪费时间来确保这些数据以一致的方式安全地同步到磁盘。这也可以使其更快。

--tmpdir如果您有足够的 RAM,您还可以指向/dev/shm。

parallel "bzcat {} | jq -c '{id,name}'" *.jsonl.bz2 > output.jsonl

如果您有足够的 CPU,但没有太多的 RAM 并且磁盘速度较慢,则压缩临时文件可能会更快:

parallel --compress "bzcat {} | jq -c '{id,name}'" *.jsonl.bz2 > output.jsonl

您不需要所有输出的临时空间 - 您只需要当前运行的作业的临时空间。因此,如果并行运行 12 个作业,则只需要 12 个文件的空间。

相关内容