티스토리 뷰
반응형
1. 장애 현상
Spark 작업 중 특정 노드에서 자주 FetchFailedException 오류가 발생하면서 작업이 지연되고 재시도 실패가 간헐적으로 발생하고 있었습니다. Hadoop 클러스터에서는 CPU / Memory / DISK / Network 등 충분한 리소스가 있었으며 별다른 이상 현상을 탐지 할 수 없었습니다. (또한, Hadoop 은 Bonding 으로 구성되어 있음)
로그 예시
FetchFailedException: Connection from <호스트네임> closed
2. 초기 진단
2.1 netstat -i 확인 결과
문제가 발생한 노드와 정상 노드 간의 인터페이스 수신 상태를 비교해보니 다음과 같은 차이를 확인할 수 있었습니다.
노드 | RX-ERR | RX-DRP | RX-OVR | 비고 |
slave0001 | 0 | 1052 | 0 | 문제 없음 |
slave0002 | 156 | 0 | 10523846 | 심각한 오버런 |
slave0003 | 5201 | 69016 | 0 | 에러 및 드롭 발생 |
→ 오버런(RX-OVR)은 커널이 네트워크 패킷을 제때 처리하지 못해 버퍼가 넘쳤다는 신호입니다.
3. 원인 분석
3.1 커널 파라미터 현황
해당 시스템의 커널 파라미터는 대부분 기본값 상태였습니다.
# 기본값
net.core.netdev_max_backlog = 1000
net.core.rmem_max = 212992
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.tcp_wmem = 4096 16384 4194304
이 값들은 일반적인 웹 서비스 수준에서는 충분할 수 있지만 Hadoop + Spark의 고트래픽 Shuffle 환경에서는 병목을 일으킬 가능성이 높습니다.
예) 1GB 데이터를 MTU 1500 기준으로 쪼개면 약 666,667개의 패킷 발생 → 수신 대기열과 버퍼가 작다면 당연히 손실 발생
4. 해결 조치
4.1 커널 파라미터 튜닝
항목 | 기존 값 | 변경 값 | 변경 이유 |
net.core.netdev_max_backlog | 1000 | 20000 | NIC 수신 대기열 증가로 빠른 수신 패킷 처리 가능 |
net.core.rmem_max | 212992 | 2097152 (2MB) | 대용량 데이터 수신 버퍼 부족 문제 해소 |
net.core.somaxconn | 1024 | 10240 | 수신 연결 큐 증가로 동시 접속 처리 향상 |
net.ipv4.tcp_max_syn_backlog | 2048 | 10240 | SYN 요청 대기 큐 증가로 접속 요청 누락 방지 |
tcp_rmem, tcp_wmem | 기본값 | 4096 87380 2097152 | 송수신 버퍼 모두 확장하여 Throughput 확보 |
기준은 Spark의 Shuffle 작업 시 초당 수십만~수백만 패킷을 처리하는 실제 트래픽 양에 맞춰 설정
4.2 NIC Ring Buffer 확장
ethtool -g로 확인한 Ring Buffer 기본 설정은 다음과 같았습니다:
항목 | 기본값 | 변경값 | 설명 |
RX Ring | 256 | 4096 | 수신 패킷을 처리할 수 있는 버퍼 공간 증가 |
TX Ring | 512 | 512 (유지) | 송신 처리에는 병목 없음 |
→ RX Ring Buffer를 최대값으로 조정하면서 RX-OVR 값이 눈에 띄게 감소했습니다.
Ring Buffer 값은 인터페이스 모델마다 기본값과 최대 값이 다릅니다.
5. 조치 이후 변화
- 커널 파라미터 조정 이후, 패킷 오류(RX-ERR) 및 오버런(RX-OVR) 감소
- Spark 작업의 재시도 빈도 0건으로 감소 (약 1 개월 모니터링)
6. 결론 및 인사이트
- 고트래픽 분산처리 시스템에서는 커널 기본 설정만으로는 안정적인 패킷 처리가 어렵습니다. (특히, 본딩된 경우에는 튜닝이 필수적)
- 단순 커널 튜닝으로 해결되지 않을 경우 NIC Ring Buffer 조정이 결정적 역할을 할 수 있습니다.
- NIC는 1계층에서 수신된 물리 신호를 처리한 후,DMA를 통해 데이터를 Ring Buffer에 적재합니다. 이때 Ring Buffer의 크기가 충분하지 않으면 패킷이 적재되지 못하고 DRP(Drop) 또는 OVR(Overrun)과 같은 문제가 발생할 수 있습니다. 본 이슈는 Ring Buffer의 크기가 작아 이러한 현상이 유발된 것으로 판단됩니다.
- 또한, 네트워크 인터페이스 모델에 따라 다릅니다. 운영 중인 Hadoop 클러스터는 입고일이 다른 서버 목록이 있는데 이 서버들의 네트워크 인터페이스 모델도 다릅니다. Ring Buffer 기본값이 200 인 모델에서는 DRP 이 증가했으며 Ring Buffer 256 모델에서는 OVR 값이 증가했습니다. DRP 이 된 인터페이스 모델을 확인했을 때 Ring Buffer 을 초과하면 DRP 된다는 이슈를 여기저기서 확인 할 수 있었습니다.
- 운영 중이라도 지속적인 모니터링과 RX-ERR, RX-OVR 값 분석을 통해 장애 전조를 감지해야 합니다.
- Prometheus Node Exporter 의 --collector.netstat 을 통해 ERR, DRP, OVR 값을 모니터링 할 수 있었습니다.
- node_network_[receive/transmit]_drop_total, node_network_[receive/transmit]_errs_total, node_network_[receive/transmit]_fifo_total
반응형
'업무 기록 > Trouble Shooting' 카테고리의 다른 글
Elasticsearch 8.12 Fielddata 해제 이슈 및 해결 방법 (0) | 2025.03.21 |
---|
댓글
공지사항
최근에 올라온 글