xargs 병렬 모드를 사용하여 출력을 단일 파일로 안전하게 리디렉션

xargs 병렬 모드를 사용하여 출력을 단일 파일로 안전하게 리디렉션

jqxargs를 사용하여 병렬로 읽고, 몇 가지 간단한 처리를 수행 하고 출력을 다음과 같은 파일로 리디렉션하는 bzipped JSON 파일이 많이 있습니다 .

# 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발생 여부를 확인할 수 있습니다).

링크되지 않은 파일은 시스템이 충돌할 경우 복구할 수 없으므로 지능형 파일 시스템은 이 데이터가 일관된 방식으로 디스크에 안전하게 동기화되도록 보장하는 데 시간을 낭비하지 않도록 선택할 수 있습니다. 이것은 또한 더 빠르게 만들 수 있습니다.

--tmpdirRAM이 충분하다면 /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개의 파일을 위한 공간만 필요합니다.

관련 정보