GNU parallel을 활용한 작업 오케스트레이션
GNU parallel, 작업 슬롯 및 결과 순서를 활용하여 대규모 입력 집합을 여러 코어에 분산합니다.
GNU parallel을 활용한 작업 오케스트레이션은(는) CoddyKit의 무료 Linux Command Line & Bash Scripting Mastery 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Linux Command Line & Bash Scripting Mastery 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Linux Command Line & Bash Scripting Mastery 강의에는 총 4개의 강의가 포함되어 있습니다.
GNU parallel이란 무엇이며 왜 사용해야 할까요?
GNU parallel은 하나 이상의 컴퓨터에서 작업을 병렬로 실행할 수 있게 해 주는 셸 도구입니다. for 반복문에서 큰 항목 목록을 하나씩 처리하는 대신, parallel은 사용 가능한 모든 CPU 코어에 작업을 동시에 분산합니다.
- 속도: 순차적으로 8분이 걸리는 작업을 8코어 컴퓨터에서는 약 1분 만에 완료할 수 있습니다.
- 간편함: 표준 입력, 파일 또는 인수 목록에서 입력을 받을 수 있으므로 프로세스를 직접 관리할 필요가 없습니다.
- 안전성: 서로 다른 작업의 출력이 분리되어 유지되므로 결과가 서로 뒤섞이지 않습니다.
sudo apt install parallel(Debian/Ubuntu) 또는 brew install parallel(macOS)로 설치하십시오. parallel --version으로 확인할 수 있습니다.
첫 번째 parallel 명령
parallel의 가장 간단한 형태는 표준 입력에서 항목을 읽고 각 항목에 대해 명령을 실행합니다. 자리 표시자 {}는 현재 입력 항목을 나타냅니다.
아래 예제에서는 gzip을 사용해 로그 파일 5개를 동시에 압축합니다. parallel이 없으면 각 파일을 차례로 압축해야 합니다. parallel을 사용하면 최대 N개의 파일(CPU 코어 수가 N)이 동시에 압축됩니다.
#!/usr/bin/env bash
# Create sample files first
for i in 1 2 3 4 5; do
dd if=/dev/urandom bs=1M count=2 of="log_${i}.txt" 2>/dev/null
done
# Compress all of them in parallel
ls log_*.txt | parallel gzip {}
echo "Done. Compressed files:"
ls log_*.txt.gz-j로 작업 슬롯 제어
기본적으로 parallel은 CPU 코어당 하나의 작업을 실행합니다. -j(또는 --jobs) 플래그로 이 값을 변경할 수 있습니다.
-j 4— 작업 4개를 정확히 동시에 실행합니다.-j 0— 입력 수만큼 작업을 실행합니다(주의해서 사용하십시오!).-j 200%— CPU 코어 수의 2배에 해당하는 작업을 실행합니다(입출력 중심 작업에 유용합니다).-j 50%— 사용 가능한 코어의 절반만 사용합니다.
CPU 중심 작업에서는 -j $(nproc)가 대체로 최적입니다. 네트워크 또는 디스크 입출력 작업에서는 작업이 대부분의 시간을 대기하므로 코어 수를 초과해도 안전합니다.
#!/usr/bin/env bash
# Show how many cores are available
echo "CPU cores: $(nproc)"
# Run 8 sleep jobs but limit to 3 at a time
# -j 3 means at most 3 jobs run simultaneously
seq 1 8 | parallel -j 3 'echo "Starting job {}"; sleep 1; echo "Done job {}"'
echo "All jobs finished."파일과 인수에서 입력 읽기
parallel은 입력 목록을 읽는 위치를 유연하게 선택할 수 있습니다. 표준 입력에서 파이프로 전달하는 방식만 사용할 필요는 없습니다.
- 파일에서:
parallel -a urls.txt wget {} - 인라인 인수 목록:
parallel echo ::: apple banana cherry - 여러 인수 소스(카테시안 곱):
parallel echo {1}-{2} ::: a b c ::: 1 2— a-1, a-2, b-1, b-2, c-1, c-2를 생성합니다. - 표준 입력에서 명시적으로:
cat list.txt | parallel -j4 process {}
::: 구분자는 parallel에 뒤따르는 값을 표준 입력 대신 인수 소스로 사용하도록 지시합니다.
#!/usr/bin/env bash
# Inline list with :::
parallel echo 'Hello from {}' ::: Alice Bob Carol Dave
echo '---'
# Cartesian product: combine two lists
# Generates: dev-v1, dev-v2, prod-v1, prod-v2
parallel echo 'Deploy {1} to env {2}' ::: v1 v2 ::: dev prod자리 표시자: 입력 토큰 조작
parallel은 입력 문자열의 일부를 자동으로 추출할 수 있는 여러 자리 표시자 치환 기능을 제공합니다. 입력이 파일 경로일 때 특히 유용합니다.
{}— 전체 입력 항목{.}— 파일 확장자를 제외한 입력(report.csv → report){/}— 기본 이름만(디렉터리 경로 제거){//}— 디렉터리 경로만{/.}— 확장자를 제외한 기본 이름
이를 사용하면 작업 명령 안에서 basename / dirname을 호출할 필요가 없어 파이프라인을 더 깔끔하고 빠르게 만들 수 있습니다.
#!/usr/bin/env bash
# Demonstrate placeholder substitutions
parallel --dry-run 'convert {} -resize 800x600 {.}_thumb.jpg' \
::: /photos/vacation/beach.png /photos/work/team.png
# {.} strips extension: /photos/vacation/beach
# Result command shown (--dry-run does NOT execute):
# convert /photos/vacation/beach.png -resize 800x600 /photos/vacation/beach_thumb.jpg
# convert /photos/work/team.png -resize 800x600 /photos/work/team_thumb.jpg
echo 'No files were changed (dry run)'--keep-order로 출력 순서 유지
작업이 서로 다른 시간에 완료되면 표준 출력 결과가 완료된 순서대로 표시됩니다. 이 때문에 로그를 읽기 어려워지고 후속 구문 분석의 신뢰성이 떨어질 수 있습니다.
출력 순서를 제어하는 두 플래그는 다음과 같습니다.
--keep-order(-k) — 나중 작업이 먼저 완료되더라도 각 작업의 출력을 입력과 같은 순서로 표시합니다. 앞선 작업이 완료될 때까지 출력이 버퍼링됩니다.--line-buffer— 중간 방식입니다. 작업 완료를 기다리지 않고 도착하는 즉시 완전한 줄을 출력하지만, 작성 중인 줄이 서로 섞이지는 않습니다.
후속 소비자가 입력 순서대로 결과를 예상할 때(예: 정렬된 보고서 작성) -k를 사용하십시오. 순서가 중요하지 않고 가능한 한 빨리 결과를 확인하려면 생략하십시오.
#!/usr/bin/env bash
# Without -k: output order is unpredictable
echo '--- Without --keep-order ---'
seq 5 1 1 | parallel 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'
echo
# With -k: output always appears as 5, 4, 3, 2, 1
echo '--- With --keep-order (-k) ---'
seq 5 1 1 | parallel -k 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'뒤섞임을 방지하기 위한 출력 그룹화
출력이 순서대로 표시되더라도 작업에서 여러 줄을 출력하면, 해당 줄이 동시에 실행 중인 다른 작업의 줄과 뒤섞일 수 있습니다. parallel은 각 작업의 전체 표준 출력과 표준 오류를 버퍼에 저장한 다음, 작업이 완료되면 이를 하나의 원자적 블록으로 출력하여 이 문제를 자동으로 해결합니다.
이 동작은 기본적으로 활성화되어 있습니다. 실시간 스트리밍 출력이 필요한 경우(예: 진행률 표시줄을 사용하는 장시간 실행 작업) --ungroup으로 비활성화할 수 있지만, 그러면 다시 출력이 뒤섞일 수 있습니다.
- 기본값: 작업별로 출력이 그룹화되어 구문 분석에 안전합니다.
--ungroup: 출력이 실시간으로 스트리밍되어 대화형 모니터링에 적합합니다.--line-buffer: 절충안으로, 줄이 분할되지는 않지만 줄 경계에서 작업 간 출력이 뒤섞일 수 있습니다.
셸 함수 안에서 인수 전달하기
병렬로 실행하려는 작업이 단일 명령보다 복잡하고 여러 단계로 이루어진 셸 함수인 경우가 있습니다. export -f와 env_parallel을 함께 사용하거나, bash -c를 직접 호출하여 함수를 parallel에 전달할 수 있습니다.
복잡한 작업에 가장 안전하고 이식성이 높은 방법은 bash -c '...' 패턴입니다. _ {}으로 끝내면 {} 자리 표시자가 $1로 전달됩니다.
#!/usr/bin/env bash
# Define a multi-step processing function
process_item() {
local item="$1"
echo "[START] $item"
# Simulate two steps
sleep 0.2
local result=$(echo "$item" | tr '[:lower:]' '[:upper:]')
echo "[END] $item -> $result"
}
export -f process_item
# Run the function in parallel for each input
echo 'alpha beta gamma delta epsilon' | tr ' ' '\n' \
| parallel -j 3 process_item {}--delay 및 --retries를 사용한 제한과 재시도
외부 서비스(API, 원격 서버, 데이터베이스)에 병렬로 연결할 때는 속도 제한과 장애 허용 기능이 필요한 경우가 많습니다.
--delay N— 새 작업을 시작할 때마다 N초씩 기다립니다(0.5와 같은 소수 값도 허용됩니다). 서비스에 요청이 몰리는 것을 방지합니다.--retries N— 작업이 0이 아닌 상태로 종료되면 포기하기 전에 최대 N번 다시 시도합니다. 각 재시도는 새로운 작업 슬롯을 차지합니다.--timeout N— 작업이 N초보다 오래 실행되면 종료합니다.--retries와 함께 사용하면 멈춘 작업도 안전하게 처리할 수 있습니다.
예: 동시에 최대 4개의 연결을 사용하고, 시작 사이에 0.5초의 점진적 지연을 두며, 실패 시 3번 재시도하면서 URL 50개를 다운로드합니다.
#!/usr/bin/env bash
# Simulate downloading URLs with throttling and retries
# (using echo instead of curl so this is self-contained)
download_url() {
local url="$1"
# Randomly fail ~30% of the time to demo --retries
if (( RANDOM % 10 < 3 )); then
echo "FAIL: $url" >&2
return 1
fi
echo "OK: $url downloaded"
}
export -f download_url
printf 'https://example.com/file%d\n' $(seq 1 10) \
| parallel -j 4 --delay 0.2 --retries 3 download_url {}
echo 'All downloads attempted.'--sshloginfile을 사용하여 원격 호스트에 작업 분산하기
parallel은 SSH를 통해 원격 시스템에 작업을 투명하게 분산할 수 있으므로, 별도의 클러스터 소프트웨어 없이도 가벼운 클러스터 계산 도구로 사용할 수 있습니다.
--sshlogin user@host— 지정한 원격 호스트에서 작업을 실행합니다.--sshloginfile machines.txt— 파일에서 호스트 목록을 읽습니다(한 줄에 하나). 로컬 시스템도 함께 사용하려면:을 특수 항목으로 사용합니다.--transfer— 처리하기 전에 입력 파일을 원격 호스트로 복사합니다.--return {}— 작업이 완료된 후 결과 파일을 다시 복사합니다.--cleanup— 가져온 후 원격 호스트에서 전송된 파일을 삭제합니다.
원격 호스트에는 parallel이 설치되어 있고 SSH 키 기반 인증이 구성되어 있어야 합니다(비밀번호 입력 요청 없음).
진행 상황 보고 및 로그 기록
장시간 실행되는 작업에서는 진행 상황을 모니터링하고 나중에 장애 원인을 진단하는 것이 매우 중요합니다.
--progress— 실행 중인 작업, 완료된 작업, 남은 작업의 수를 보여 주는 요약 줄을 실시간으로 출력합니다.--eta— 지금까지의 평균 작업 시간을 기준으로 완료까지 걸리는 시간을 추정합니다.--joblog results.log— 완료된 각 작업마다 한 행씩 기록하는 탭 구분 로그 파일을 작성합니다. 종료 코드, 실행 시간, 실행한 명령이 포함되므로 장애를 감사하는 데 매우 유용합니다.--resume --joblog results.log— 로그 파일에 이미 나타나며 종료 코드가 0인 작업은 건너뜁니다. 일괄 실행이 중단되어도 성공한 작업을 다시 수행하지 않고 재개할 수 있습니다.
--joblog와 --resume의 조합은 안정적인 운영 파이프라인을 구축하기 위한 GNU parallel의 가장 강력한 기능 중 하나입니다.
#!/usr/bin/env bash
LOGFILE="/tmp/parallel_demo_$$.log"
# Run jobs and record results to a log
seq 1 12 | parallel \
--jobs 4 \
--progress \
--joblog "$LOGFILE" \
'sleep 0.1; echo "Processed item {}"'
echo
echo '=== Job Log (first 5 entries) ==='
head -6 "$LOGFILE"
# Show only failed jobs (exit value != 0)
echo '=== Failed jobs ==='
awk 'NR>1 && $7 != 0 { print $0 }' "$LOGFILE" || echo '(none)'
rm -f "$LOGFILE"지식 확인: 작업 슬롯 플래그
parallel이 동시 실행을 제어하는 방식을 제대로 이해했는지 확인해 보세요.
레슨 요약: GNU parallel로 작업 부하 조정하기
GNU parallel을 사용하여 대규모 입력 집합을 CPU 코어에 분산하는 핵심 도구를 살펴보았습니다. 다음 내용을 기억해 두세요.
- 기본 사용법: 목록을
parallel command {}로 파이프에 전달하면{}가 각 입력 항목으로 바뀝니다. - 작업 슬롯(
-j): 동시 실행 수를 정밀하게 제어합니다. CPU를 많이 사용하는 작업에는 코어 수를 사용하고, 입출력을 많이 사용하는 작업에는 더 높은 백분율을 사용합니다. - 자리 표시자(
{.},{/},{//},{/.})를 사용하면 추가 명령 없이 경로 구성 요소를 깔끔하게 추출할 수 있습니다. - 출력 제어:
-k는 입력 순서를 유지하고, 기본 그룹화는 줄이 뒤섞이는 것을 방지하며,--ungroup은 실시간 스트리밍을 제공합니다. - 복원력:
--retries,--timeout,--delay를 사용하면 불안정한 작업과 속도 제한에 대응하는 견고한 병렬 파이프라인을 만들 수 있습니다. - 감사 가능성:
--joblog은 모든 작업의 결과를 기록하고,--resume은 중단된 지점부터 다시 시작할 수 있게 합니다. - 확장:
--sshloginfile은 클러스터 관리 오버헤드 없이 SSH를 통해 원격 시스템에 작업을 분산합니다.
이 옵션들을 익히면 셸에 바로 내장된 parallel이 운영 환경 수준의 작업 부하 조정 도구가 됩니다.
자주 묻는 질문
“GNU parallel을 활용한 작업 오케스트레이션” 강의는 무료인가요?
네 — “GNU parallel을 활용한 작업 오케스트레이션” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Linux Command Line & Bash Scripting Mastery 강의 전체를 잠금 해제할 수 있습니다. Linux Command Line & Bash Scripting Mastery 강의에는 총 4개의 강의가 포함되어 있습니다.
“GNU parallel을 활용한 작업 오케스트레이션”에서 뭘 배우나요?
GNU parallel, 작업 슬롯 및 결과 순서를 활용하여 대규모 입력 집합을 여러 코어에 분산합니다. 브라우저에서 직접 실행하는 실습 코드로 Linux Command Line & Bash Scripting Mastery을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Linux Command Line & Bash Scripting Mastery을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Linux Command Line & Bash Scripting Mastery은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“GNU parallel을 활용한 작업 오케스트레이션” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Linux Command Line & Bash Scripting Mastery 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Linux Command Line & Bash Scripting Mastery 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 스크립트 프로파일링 및 불필요한 서브셸 방지
- xargs -P와 백그라운드 작업을 활용한 병렬 처리
- GNU parallel을 활용한 작업 오케스트레이션
- 처리량을 높이는 스트리밍 파이프라인과 명명된 파이프