사전 배치 처리
개념

배치 처리

gabury1고친 사람 github-actions[bot]

배치 처리는 일을 한 건씩 바로 처리하지 않고 여러 건을 모아 두었다가 한꺼번에 끝냅니다. 모아서 한 번에 돌리면 같은 시간에 더 많은 일을 끝냅니다. 대신 먼저 들어온 일은 묶음이 찰 때까지 기다립니다. 밤마다 하루치 주문을 몰아서 정산하는 일도, 주문 백 건을 데이터베이스에 한 번에 넣는 일도 이 이름으로 부릅니다.

쉽고 빠른 이해

무슨 일을 하는 방식인가 — 여러 건을 한 묶음으로 만들어 한 번에 처리합니다. 주문 백 건을 데이터베이스에 한 건씩 백 번 넣는 대신 한 번에 넣는 것이 배치 처리입니다.

왜 이렇게 하나 — 일 한 건을 처리할 때마다 준비가 따로 붙습니다. 연결을 잡고, 요청을 보내고, 답을 기다립니다. 백 건이면 그 준비를 백 번 치릅니다. 묶으면 한 번으로 줄어듭니다.

어떻게 도나

  1. 들어온 일을 바로 처리하지 않고 모읍니다
  2. 묶음이 정해 둔 크기에 닿거나 정해 둔 때가 되면 출발시킵니다
  3. 모인 것을 한 번에 처리하고 결과를 함께 냅니다

대가 — 먼저 온 일이 기다립니다. 묶음이 클수록 기다림이 길어집니다. 묶음 하나가 도중에 깨지면 어디까지 처리됐는지 가려내는 일도 따라옵니다.

상세

양말 한 짝이 나올 때마다 세탁기를 돌리는 사람은 없습니다. 빨래통에 모아 두었다가 통이 차면 한 번 돌립니다. 물과 전기와 돌아가기를 기다리는 시간은 한 번 돌릴 때마다 드는 값이라, 모아서 돌릴수록 빨래 한 장에 돌아가는 값이 줄어듭니다. 대신 오늘 당장 입어야 하는 셔츠는 통이 찰 때까지 못 입습니다.

이 절은 그 셈을 그대로 따라갑니다. 먼저 묶으면 왜 값이 줄어드는지를 데이터베이스에 행을 넣는 예로 보고, 묶음 크기가 무엇을 사고 무엇을 파는지를 봅니다. 그다음 「모아 두었다가 정해진 때에 도는 작업」이라는 또 하나의 뜻을 짚고, 묶음이 깨졌을 때와 이 방식을 안 쓰는 때로 끝냅니다.

건마다 드는 값과 묶음마다 드는 값

일 하나를 처리하는 값은 두 몫으로 갈립니다. 하나는 건마다 드는 값입니다. 주문 한 건을 저장하려면 그 한 줄을 디스크에 쓰는 일은 어차피 해야 합니다. 다른 하나는 한 번 처리할 때마다 드는 값입니다. 연결이 살아 있는지 확인하고, 요청을 보내고, 답이 올 때까지 기다리는 몫이 여기 듭니다.

배치 처리는 뒤쪽 몫을 여러 건이 나눠 지게 만듭니다. 주문 백 건을 저장하는 두 방식을 견줘 봅니다.

Java
for (건 : 주문들) insert(건); // 왕복 100번
insertAll(주문들);            // 왕복 1번

위쪽은 주문 한 건마다 데이터베이스와 한 번씩 주고받습니다. 아래쪽은 백 건을 한 요청에 실어 보내니 주고받기가 한 번입니다. 디스크에 백 줄을 쓰는 몫은 양쪽이 같지만, 주고받는 몫은 백분의 일로 줄어듭니다. 이 차이가 배치 처리가 주는 이득의 전부입니다.

그래서 건마다 드는 값에 견줘 한 번 처리할 때마다 드는 값이 클수록 묶는 이득이 큽니다. 원격 서버와 주고받기, 디스크 접근, 운영체제에 일을 맡기려고 부르는 시스템 콜이 그런 일입니다. 셋 다 한 번 부를 때마다 값을 치르므로, 부르는 횟수를 줄이는 것이 곧 값을 줄이는 것입니다.

묶음 크기가 사는 것과 파는 것

묶음을 키우면 처리량이 오릅니다. 처리량은 정해진 시간 동안 끝낸 일의 개수입니다. 한 번 주고받을 때마다 딸려 오는 준비를 여러 건이 나눠 지니, 같은 시간에 끝내는 건수가 늘어납니다.

같은 만큼 지연은 늘어납니다. 지연은 일 한 건이 들어와서 끝나기까지 걸린 시간입니다. 묶음에 먼저 담긴 일은 묶음이 찰 때까지 아무 일도 안 하고 기다립니다. 묶음이 클수록 그 기다림이 길어집니다.

기다림이 끝없이 길어지는 것을 막으려고 대개 조건을 둘 겁니다. 묶음이 정해 둔 크기에 닿거나, 첫 건이 들어온 뒤 정해 둔 시간이 지나면 묶음을 출발시킵니다.

flowchart TD
    A["일이 들어온다"] --> B["묶음에 담는다"]
    B --> C{"묶음이 정한 크기에 닿았나"}
    C -->|닿았다| E["한 번에 처리한다"]
    C -->|아직| D{"첫 건이 들어온 뒤 정한 시간이 지났나"}
    D -->|지났다| E
    D -->|아직| B

두 번째 조건이 지연의 윗선을 정합니다. 일이 드물게 들어와 묶음이 안 차는 때에도 그 시간만 지나면 출발하니, 한 건이 하염없이 갇히지 않습니다. 묶음 크기와 기다리는 시간, 이 둘이 배치 처리를 굴릴 때 손으로 잡는 손잡이입니다.

묶음을 무작정 키우지 못하는 까닭은 하나 더 있습니다. 모아 둔 일은 처리되기 전까지 메모리에 들고 있어야 합니다. 묶음이 클수록 들고 있는 양이 늘고, 도중에 깨졌을 때 다시 해야 하는 양도 늘어납니다.

모아 두었다가 정해진 때에 도는 작업

같은 이름이 조금 다른 뜻으로도 쓰입니다. 하루치 주문을 밤에 몰아서 정산하거나, 어제 쌓인 기록을 아침에 집계하는 작업을 배치 작업이라고 부릅니다. 여러 건을 묶는다는 뼈대는 같고, 묶는 단위가 「요청 백 건」이 아니라 「하루치」라는 것이 다릅니다.

이런 작업이 다루는 데이터는 끝이 정해져 있습니다. 어제 하루의 주문은 오늘 아침에는 더 늘어나지 않습니다. 끝이 정해진 데이터를 유계 데이터라고 부릅니다. 끝이 정해져 있으니 전체를 한 번에 훑어 정렬하거나 합계를 낼 수 있습니다.

여기서 흔히 만나는 이름이 ETL(Extract, Transform, Load)입니다. 여러 곳에 흩어진 데이터를 뽑아내고, 쓸 모양으로 바꾸고, 분석용 저장소에 싣는 작업을 말합니다. 하루에 한 번씩 도는 배치 작업으로 돌리는 것이 오랜 방식입니다. 이런 작업을 정해진 때에 띄우는 일은 스케줄러가 맡습니다.

작업이 끝나야 하는 시간에도 이름이 있습니다. 밤 한 시에 시작해 아침 여섯 시까지는 끝나야 한다면 그 사이가 배치 창입니다. 데이터가 불어나 작업이 배치 창을 넘기기 시작하면, 다음 날 작업이 앞 작업과 겹칩니다.

끝이 없는 데이터를 들어오는 대로 처리하는 쪽은 스트림 처리라고 따로 부릅니다. 배치 처리와 스트림 처리를 가르는 것은 데이터에 끝이 있느냐입니다.

묶음이 도중에 깨지면

한 건씩 처리할 때는 깨진 건만 다시 하면 됩니다. 묶음으로 처리하면 「어디까지 됐나」를 먼저 가려야 합니다. 백 건 중 마흔 건째에서 실패했다면 앞의 서른아홉 건은 이미 반영돼 있을 수 있습니다.

가장 단순한 답은 묶음 하나를 트랜잭션 하나로 처리하는 것입니다. 트랜잭션은 여러 작업을 한 덩이로 묶어 전부 반영되거나 전부 없던 일이 되게 하는 단위입니다. 실패하면 묶음 전체를 되돌리고 처음부터 다시 합니다. 대신 묶음이 클수록 되돌리는 양이 많고, 트랜잭션이 오래 열려 있는 동안 다른 작업이 기다립니다.

오래 도는 배치 작업은 대신 중간 지점을 남깁니다. 어디까지 처리했는지를 적어 두고, 다시 시작할 때 그 뒤부터 잇는 방식입니다. 이 표시를 체크포인트라고 부릅니다.

어느 쪽이든 같은 일을 두 번 처리하게 될 여지가 남습니다. 그래서 배치 작업은 멱등성을 갖추도록 짜는 것이 보통입니다. 멱등성은 같은 입력으로 여러 번 돌려도 결과가 한 번 돌린 것과 같은 성질입니다. 멱등하면 재시도가 안전해집니다. 실패한 작업을 통째로 다시 돌려도 값이 두 번 더해지지 않습니다.

언제 안 쓰나

사용자가 화면 앞에서 답을 기다리는 요청에는 안 맞습니다. 묶음이 찰 때까지 기다리게 하는 것이 이 방식의 전제인데, 그 기다림을 사람이 그대로 겪습니다.

데이터가 끝없이 들어오고 결과를 곧바로 봐야 하는 일도 맞지 않습니다. 이상 거래를 잡아내거나 실시간 순위를 매기는 일이 그렇습니다. 하루에 한 번 도는 작업으로는 답이 하루 늦습니다.

일의 성격을 봐도 갈립니다. 한 건을 처리하는 값 자체가 크고 준비에 드는 값이 작다면, 묶어도 줄어드는 몫이 거의 없습니다. 계산량이 많아 한 건에만 몇 분씩 매달리는 작업이 여기 해당합니다.

관련 항목

배치 처리와 맞세워지는 처리 방식

스트림 처리 · 실시간 처리 · 마이크로 배치 · 온라인 처리 · 대화형 처리

배치 처리가 저울질하는 성능 지표

처리량 · 지연 · 꼬리 지연 · 응답 시간 · 자원 사용률

배치 처리가 다루는 데이터의 갈래

유계 데이터 · 무계 데이터 · 데이터 엔지니어링 · 파이프라인 · ETL · 데이터 웨어하우스

배치 작업을 때맞춰 띄우는 도구

스케줄러 · cron · Apache Airflow · 작업 큐 · 워크플로우 오케스트레이션

배치 처리를 떠받치는 분산 처리 기술

MapReduce · Apache Spark · Hadoop · 샤딩 · 병렬 처리

여러 건을 묶어 값을 줄이는 다른 기법

벌크 삽입 · 버퍼링 · 파이프라이닝 · 벡터 입출력 · 시스템 콜 · 네이글 알고리즘

묶음이 깨졌을 때 기대는 성질과 장치

멱등성 · 체크포인트 · 재시도 · 트랜잭션 · 롤백 · 부분 실패

배치 처리에서 자주 나는 장애

배치 창 초과 · 데이터 쏠림 · 중복 처리 · 장기 실행 트랜잭션 · 메모리 부족

다른 이름: batch processing · 일괄 처리 · 배칭