NAS 로그 파일을 수집해 Kudu 테이블로 적재하는 NiFi 프로세스 그룹(PG) 24개를 일괄 정비하면서 겪은 부하 문제와 그 처방을 정리한다. 증상은 PutKudu 앞 큐 적체, Kudu tablet server 의 SERVICE_UNAVAILABLE, content repository 디스크 폭증, NiFi UI 지연, 그리고 primary node 한 대의 CPU 편중이었다. 3노드 NiFi 클러스터(각 노드에 Kafka broker 동거)와 Kudu tablet server 3대 환경이다.
| 항목 | 변경 전 | 변경 후 |
|---|---|---|
| NAS 수집 PG 실행 주기 | 1분 (24개가 정각에 동시 실행) | 30분 |
| PutKudu Concurrent Tasks | 최대 16 | 1 |
| ReplaceText / QueryRecord Concurrent Tasks | 1 | 큐가 쌓인 5~6개 PG 만 3~4 |
| PutKudu Batch Size / Flush Mode | 5000 / AUTO_FLUSH_BACKGROUND | 그대로 유지 |
동시 실행을 분산하려면 실행 주기를 늘리는 방법(A) 외에, 스케줄을 CRON 으로 바꿔 PG 마다 초를 어긋나게(0 * * * * ?, 5 * * * * ?, …) 두는 방법(B)도 있다. 대부분 A 로 충분하다.
파일 하나가 수백 MB 인 PG 는 RouteOnAttribute 와 ReplaceText(전환) 사이에 SplitText 를 넣어 청크 단위로 흘린다.
| SplitText 속성 | 값 |
|---|---|
| Line Split Count | 10000 (부하에 따라 50000 까지) |
| Maximum Fragment Size | 비움 |
| Header Line Count | 0 |
| Remove Trailing Newlines | true |
RouteOnAttribute → SplitText → (splits) → ReplaceText 로 배선하고 original / failure 는 auto-terminate 한다.
Repository Archive Maximum Usage Percentage 를 30% 로 낮춰 두면 Unable to write flowfile content ... waiting for archive cleanup 경고와 함께 처리가 멈춘다. 정상 운영 여유값은 60~80% 이며, 대용량 유입 방어는 이 값이 아니라 백프레셔와 수집 방식으로 잡아야 한다. 값 변경 후 NiFi 재시작이 필요하다.
노드 하나가 disconnected 상태로 남으면 해당 노드의 NiFi 역할을 정지하고 flow.json.gz 를 백업 이름으로 옮긴 뒤 다시 기동하면 클러스터에서 flow 를 내려받아 합류한다.
mv /nifi/conf/flow.json.gz /nifi/conf/flow.json.gz.bak
is not the most up-to-date revision. This component appears to have been modified 는 다른 탭이나 다른 노드에서 같은 컴포넌트가 바뀌어 화면이 옛 revision 을 들고 있는 것이다. 설정창을 닫고 브라우저를 새로고침한 뒤 다시 수정하면 된다.
PutKudu 의 동시성을 늘릴수록 Kudu 에 가해지는 동시 압력이 커져 tablet server 가 SERVICE_UNAVAILABLE 을 반환하고, 그 응답을 기다리는 스레드가 늘어 NiFi 전체가 느려지는 악순환이 생긴다. 병목은 상류(파싱)에서 풀고 하류(PutKudu)는 Kudu 가 감당하는 속도에 맞춰 1 로 두는 역할 분리가 정답이었다. Kudu 쪽은 memory_limit_hard_bytes(16GiB→48GiB)와 maintenance manager 스레드(4→8)를 늘리면 완충 여유가 생기지만 재시작이 필요하다.
이름.log.yyyymmdd 로 바뀌므로 30분 주기로 돌리면 전날 파일을 한 번 더 재수행해야 한다.ConsumeKafkaRecord 의 offset 을 리셋하되 토픽 retention(이 환경은 2~7일) 범위 안의 메시지만 돌아온다.