공장 설비에서 올라오는 측정 이벤트를 받아 DB에 적재하는 수집 서버가 있다. 지금은 이벤트 하나당 INSERT 한 번인데, 라인이 늘면서 유입이 초당 수천 건으로 올라갔다. 한 건씩 바로 쓸지, 모아서 배치로 쓸지(배치 크기·flush 간격) 정해야 한다. 같은 고민이 오퍼 서비스에도 있다 — 사용자가 보는 오퍼 조회 API와 밤마다 도는 시세 재산정 파이프라인은 최적화할 숫자가 다르다.
언제: 사용자가 응답을 기다리는 경로 전부 — 오퍼 조회, 결제 승인처럼 요청 한 건의 p99가 곧 제품인 곳. 적재 경로도 초당 수백 건까지는 한 건씩 써도 DB가 충분히 따라온다. 코드가 단순하고 실패가 그 한 건에서 바로 보인다.
비용: 건당 네트워크 왕복과 커밋 비용이 그대로 곱해진다. 초당 수천 건이 되면 같은 행 수를 쓰는데도 배치 대비 DB 커넥션과 CPU를 몇 배로 태우고, 처리량이 유입을 못 따라가기 시작한다.
언제: 호출자가 사람이 아니라 큐인 대량 적재 경로일 때 — 센서 이벤트 수집, 야간 정산·시세 재산정 파이프라인처럼 한 건의 지연보다 시간당 총 처리량이 중요한 곳. 커밋·왕복 오버헤드를 N건이 나눠 내서 같은 하드웨어로 몇 배를 처리한다.
비용: 모든 건의 지연이 flush 간격만큼 올라간다 — 500건 또는 200ms 중 먼저 차는 쪽으로 묶으면 최악 +200ms. 배치 중간에 죽으면 부분 실패 처리가 필요하고, 불량 한 건이 배치 전체를 막는 poison-pill 같은 새 실패 모드가 생긴다.
기본은 한 건씩 즉시 처리다. 사용자가 기다리는 경로에서는 한 건의 p99가 곧 제품이기 때문이다. 호출자가 사람이 아니라 큐인 적재 경로에서 컨슈머 랙이 피크가 지나도 계속 쌓이면, 그 경로만 배치로 바꾼다 — 이때 배치 크기와 flush 간격을 반드시 같이 건다(예: 500건 또는 200ms 중 먼저). 간격 상한이 없으면 한산한 시간대에 마지막 몇 건이 무한정 기다린다.
- 적재 경로의 컨슈머 랙(큐 깊이)이 피크가 지난 뒤에도 10분 이상 계속 증가 — 처리량이 유입을 못 이기고 있다는 신호, 배치 전환 검토
- DB 시간 대부분이 행 처리가 아니라 건당 커밋·왕복 오버헤드 — 같은 데이터를 500건 batch INSERT로 묶어 보면 처리량이 5~10배 차이로 실측됨
- 반대쪽 신호: 배치를 키운 뒤 사용자 노출 API p99가 500ms를 넘기 시작 — flush 간격을 줄이거나 그 경로만 배치에서 제외
- 파티션 하나에 키가 몰려 처리량 skew가 30%를 넘음 — 배치를 더 키워도 전체 속도는 핫 파티션 하나에 묶인다
🔧Kafka producer (batch.size + linger.ms)JDBC batch INSERT (rewriteBatchedStatements)Grafana (p99 vs consumer-lag 대시보드)k6 (throughput vs latency 부하 테스트)
“I keep user-facing paths per-request for p99, and only batch the pipelines where nobody's waiting on a single record.”
checking microphone…