Splunk Forwarder 유형
Splunk에는 여러 가지 데이터 수집 방법이 있지만, 가장 대표적인 것은 Forwarder
Forwarder는 데이터를 읽어서 인덱서로 전달하는 역할을 하며, 종류에 따라 기능 차이가 있음
1. Heavy Forwarder (HF)
- Splunk Enterprise의 모든 기능 포함
- 데이터를 파싱한 후 전달
- 인덱서 대신 Forwarder에서 파싱하므로 리소스 소모가 크다
- HF를 사용해야 하는 경우
- UI가 필요한 경우
- 이벤트 단위 라우팅이 필요한 경우
- 들어오는 이벤트의 80% 이상을 필터링해야 하는 경우
- 데이터 마스킹/익명화 필요
- 특정 Python 버전 필요
- 일부 앱/모듈 입력 필요 (예: HEC, DBX, Checkpoint 등)
2. Universal Forwarder (UF)
- 경량화된 바이너리 패키지
- 데이터를 파싱하지 않고 원본 그대로 전송
- 가장 많이 사용되는 Forwarder
3. Lightweight Forwarder (LWF) (현재는 폐지됨)
- Splunk 전체 설치 후 LWF 앱 활성화
- 데이터를 파싱하지 않고 전달
- 현재는 구버전 환경에서만 의미가 있음
파싱된 데이터 (HF)
Heavy Forwarder(HF)는 로그를 읽어 파싱 규칙을 적용한 뒤, 개별 이벤트 단위로 쪼갭니다.
그리고 각 이벤트에는 Host, Source, Sourcetype, Index 같은 메타데이터가 붙습니다.
이후 파싱된 이벤트를 인덱서로 전송하게 됩니다.
파싱된 데이터의 로드 밸런싱
여러 인덱서가 있는 환경에서는 자동 로드 밸런싱이 이루어집니다.
- autoLBFrequency (기본 30초): 30초마다 인덱서를 자동 전환
- autoLBVolume: 데이터 전송량을 기준으로 전환
- 두 옵션을 모두 설정하면 먼저 충족되는 조건이 적용됨
즉, 시간 기반 혹은 전송량 기반으로 데이터가 고르게 분산됩니다.
📂 설정 파일
- 위치: $SPLUNK_HOME/etc/system/local/outputs.conf (또는 앱 단위의 local 디렉터리)
- 대상: Forwarder (HF 또는 UF)
📌 주요 파라미터
1. autoLBFrequency
- 기본값: 30초
- 의미: forwarder가 다음 인덱서로 전환하는 주기(시간)
- 예시: 20초마다 인덱서 전환
[tcpout:my_indexers]
autoLBFrequency = 20
2. autoLBVolume
- 기본값: 0 (비활성화)
- 의미: forwarder가 특정 인덱서에 보낼 최대 데이터량(바이트)
- 예시: 100MB 전송하면 다음 인덱서로 전환
[tcpout:my_indexers]
autoLBVolume = 104857600
3. 두 옵션을 같이 쓸 경우
- forwarder는 둘 중 먼저 충족된 조건을 기준으로 인덱서를 바꿈
- 예: 50MB를 다 채우기 전에 30초가 지나면 시간 기준으로 전환
30초 전이라도 50MB를 다 채우면 용량 기준으로 전환
autoLBFrequency = 30
autoLBVolume = 50000000 (50MB)
📂 outputs.conf 샘플 (멀티 인덱서 로드밸런싱)
[tcpout]
defaultGroup = my_indexers
# 인덱서 그룹 정의
[tcpout:my_indexers]
server = idx1.company.com:9997, idx2.company.com:9997, idx3.company.com:9997
# 로드 밸런싱 방식
autoLBFrequency = 30 # 30초마다 인덱서 전환
autoLBVolume = 104857600 # 100MB 보내면 전환
# 연결 유지
connectionTimeout = 20
useACK = true # 인덱서 ACK 사용 (데이터 유실 방지)
📌 설명
- [tcpout]
- 기본 출력 그룹을 지정 (defaultGroup = my_indexers)
- server
- 인덱서 리스트. Forwarder가 여기서 자동으로 로드 밸런싱
- autoLBFrequency
- 기본 30초 (단위: 초)
- forwarder가 인덱서를 바꿀 주기
- autoLBVolume
- 기본 0 (비활성화)
- 지정하면 데이터량 기준 전환 (예: 104857600 = 100MB)
- useACK
- 인덱서로부터 수신 확인(ACK)을 받을 때까지 데이터 보관
- 신뢰성 향상, 네트워크 불안정 시 유용
파싱되지 않은 데이터 (UF)
Universal Forwarder(UF)는 데이터를 파싱하지 않는다. 대신, 최소한의 메타데이터만 붙여 보낸다.
- Host, Source, Sourcetype, Index 정보만 포함
- 데이터를 64KB 블록 단위로 쪼개서 전송
- 각 스트림에는 Forwarder의 타임존 정보가 기록됨
⏰ 타임존 정보가 기록된다는 의미
- UF가 보낸 각 데이터 스트림의 헤더 부분에는 Forwarder가 실행 중인 시스템의 타임존 정보가 포함
- 예를 들어 UF가 한국 서버에서 돌고 있다면, +0900 같은 UTC 오프셋 값이 스트림에 표시
- 원본 로그에 타임존이 없더라도, 데이터가 언제/어디서 수집되었는지를 Indexer가 알 수 있게 하기 위함임
🧩 왜 필요한가?
- 타임스탬프 추출 시 기준 제공
- Indexer는 원본 로그에서 타임스탬프를 파싱해야 하지만, 로그에 타임존이 없는 경우가 많음
- 이때 UF가 보낸 “Forwarder의 시스템 타임존”을 기본값으로 삼아 _time을 해석가능
- 분산 환경에서 시간 동기화
- 서로 다른 지역(예: 한국, 미국, 유럽)에 설치된 UF들이 같은 Indexer로 데이터를 보내더라도,
Indexer는 UF 타임존 메타데이터를 참고해서 정확히 _time을 보정할 수 있다!
- 서로 다른 지역(예: 한국, 미국, 유럽)에 설치된 UF들이 같은 Indexer로 데이터를 보내더라도,
✅ 정리하면:
“스트림에 타임존이 기록된다”
→ UF가 데이터를 보낼 때, 자기 시스템이 어떤 타임존에서 실행 중인지(UTC 오프셋)를 스트림 헤더에 담아 보낸다.
Indexer가 로그 타임스탬프를 올바른 시간대 기준으로 해석하는 데 활용!
여기서 질문?! 👉
지금 UF → Indexer로 한국(+0900) 서버랑 미국(-0800) 서버에서 동시에 로그가 들어오는 상황이라면,
타임존 정보가 없으면 어떤 문제가 생길까?
>> 서로 같은 이벤트라도 시간이 서로 다르게 검색되지 않을까??
예시 상황:
- 같은 실제 시각: 2025-08-19 10:00 (한국 시간, UTC+0900)
- 한국 서버에서 UF가 로그 생성 → 2025-08-19 10:00
- 미국 서버(LA, UTC-0800)에서 UF가 로그 생성 → 2025-08-18 18:00
❌ 타임존 정보가 없다면
Splunk Indexer는 단순히 로그에 적힌 문자열만 보고 _time을 생성
- 한국 로그: 2025-08-19 10:00
- 미국 로그: 2025-08-18 18:00
→ 사실은 같은 “UTC 기준 시각”인데, 서로 다른 시간대의 별개 이벤트로 처리됨.
✅ 타임존 정보가 있다면
UF가 자기 타임존(+0900, -0800)을 스트림 헤더에 포함해서 보내니까,
Indexer는 이걸 반영해서 UTC로 변환 후 _time을 기록!
- 한국 로그: 2025-08-19 10:00 +0900 → UTC 2025-08-19 01:00
- 미국 로그: 2025-08-18 18:00 -0800 → UTC 2025-08-19 02:00
→ 이제 Splunk에서 두 이벤트를 정확히 1시간 차이 나는 순서로 인식할 수 있음.
즉, 타임존 정보가 없으면 동일한 시각의 이벤트가 “뒤죽박죽”이 되고, 있으면 정확한 시간 축 정렬이 가능!
파싱되지 않은 데이터의 로드 밸런싱
UF 역시 동일한 로드 밸런싱 규칙(autoLBFrequency / autoLBVolume)을 따른다.
다만 중요한 점은 데이터 손실 방지!!!
- 인덱서를 전환할 때 이벤트가 잘리거나 누락되지 않도록 안전성 검증을 수행
- 안전하지 않으면 기존 인덱서 연결을 유지한 채 데이터 전송을 마무리
즉, 타이머가 "이제 새로운 인덱서로 전환해야해!!!"라고 이야기해도,
이벤트가 잘리거나 손상되지 않는다는 보장이 없을 경우에는 전환하지 않음!!
forceTimebasedAutoLB 옵션
UF는 데이터를 64KB 단위로 쪼갬! 이때 제어 키(Control Key)를 주기적으로 삽입!
- 기본 주기: 30초
- 기존 인덱서(IDX1)는 제어 키 이전 데이터를 수신
- 새로운 인덱서(IDX2)는 제어 키 이후 데이터를 수신
⚠️ 단점: 이벤트 크기가 64KB 이상일 경우, 멀티 청크로 분리되면서 일부 이벤트가 손실될 수 있습니다.
EVENT_BREAKER 기능
이 문제를 해결하기 위해 EVENT_BREAKER 설정을 사용할 수 있습니다.
- props.conf에 EVENT_BREAKER_ENABLE 활성화
- Forwarder가 이벤트 경계(Regex 패턴)를 인식하여 중간 잘림 방지
- autoLBFrequency / autoLBVolume와 함께 동작
- 대용량 멀티라인 이벤트(예: Java Stack Trace)에 특히 유용
동작 방식
- UF가 정규표현식(REGEX)을 이용해 이벤트 경계를 찾음
- forceTimebasedAutoLB의 대체 가능
- REGEX에는 캡처 그룹이 포함되어야 하며, props.conf의 LINE_BREAKER 설정에서 가져올 수 있음
- UF 6.5 이상 버전에서만 지원 (Indexers 업그레이드 불필요)
outputs.conf 로드밸런싱 예시
A. 시간기반(기본) + ACK
# $SPLUNK_HOME/etc/system/local/outputs.conf
[tcpout]
defaultGroup = idx_pool
[tcpout:idx_pool]
server = idx1.example.com:9997, idx2.example.com:9997
# 시간기반 전환 주기(초) – 기본 30
autoLBFrequency = 30
# 안전 전송 확인(강력 추천)
useACK = true
# (권장) 불필요한 강제 전환 끄기
forceTimebasedAutoLB = false
B. 볼륨기반 전환 활성화(큰 이벤트 섞일 때 추천)
[tcpout:idx_pool]
server = idx1.example.com:9997, idx2.example.com:9997
useACK = true
# 30초마다가 아니라, N바이트 보낸 뒤에 전환
autoLBVolume = 128MB # 예: 128MB 다 채우면 다음 인덱서로
autoLBFrequency = 0 # 시간기반 비활성화(선택)
forceTimebasedAutoLB = false
볼륨기반은 청크 경계/이벤트 경계 충돌 가능성을 줄여 잘림(truncate) 위험 완화에 유리.
C. “둘 다” 켠다면 동작 규칙
[tcpout:idx_pool]
server = idx1:9997, idx2:9997
useACK = true
autoLBFrequency = 30
autoLBVolume = 256MB
forceTimebasedAutoLB = false
- UF는 먼저 볼륨 기준을 우선 확인해 임계치 도달 시 즉시 전환.
- 볼륨 미도달이면 시간 임계(30초) 지났을 때 전환.
D. forceTimebasedAutoLB를 꼭 써야 할 때(권장X)
[tcpout:idx_pool]
server = idx1:9997, idx2:9997
useACK = true
autoLBFrequency = 30
autoLBVolume = 256MB
forceTimebasedAutoLB = false
- 문서에서 본 것처럼 64KB 청크 경계를 강제로 끊는 로직이라,
64KB 초과 이벤트가 섞이면 일부가 trashed 될 수 있어 현업/시험 모두 비권장.
“잘림·유실 방지” 필수 체크리스트
✅ UF 측(전송 안정성)
- useACK = true
인덱서가 “받았다” ACK 보내기 전까지 UF가 큐에서 안 지움 → 유실 방지. - 볼륨기반 LB(autoLBVolume) 고려
큰 이벤트 있을 때 시간강제보다 안전. - (네트워크 불안정 시) UF 퍼시스턴트 큐(기본 내장)로 버퍼링 → 재전송 가능.
✅ 인덱서/파서 측(파싱 안정성)
큰/멀티라인 이벤트가 잘리는 건 인덱서의 파싱(라인 브레이킹) 규칙 영향이 큼.
- 해당 sourcetype의 props.conf에 다음 검토:
- TRUNCATE 기본은 10,000자(약 10KB)라 긴 단일라인은 잘릴 수 있음 → 꼭 늘리거나 0.
- JSON/스택트레이스 등은 정확한 LINE_BREAKER가 핵심.
# $SPLUNK_HOME/etc/system/local/props.conf (또는 앱 경로)
[your_sourcetype]
SHOULD_LINEMERGE = false # 임의 병합 비활성화
LINE_BREAKER = ([\r\n]+) # 실제 줄 경계에 맞는 패턴(예시)
TRUNCATE = 0 # 기본 10,000자 제한 해제(0=무제한) 또는 충분히 크게
# 멀티라인이라면 MUST_BREAK_AFTER / MUST_NOT_BREAK_AFTER 등 정확히 지정
✅ 운영 팁
- 한 인덱서에만 몰리지 않게 indexer health/queue 모니터링(MC)로 균형 확인.
- 전환 시점에 에러가 나면 splunkd.log에서 ACK/연결/큐 상태를 먼저 확인:
tail -f $SPLUNK_HOME/var/log/splunk/splunkd.log | egrep -i "TcpOutputProc|Ack
마무리
정리하면, Splunk 환경에서 HF는 파싱 후 전송, UF는 원본 그대로 전송하며,
두 방식 모두 자동 로드 밸런싱을 통해 데이터를 여러 인덱서에 분산시킵니다.
하지만 UF에서는 이벤트 손실 가능성을 고려해 EVENT_BREAKER 기능을 활용하는 것이 좋습니다.
Splunk에는 여러 가지 데이터 수집 방법이 있지만, 가장 대표적인 것은 Forwarder입니다.
Forwarder는 데이터를 읽어서 인덱서로 전달하는 역할을 하며, 종류에 따라 기능 차이가 있습니다.
'Splunk' 카테고리의 다른 글
| [Splunk] 네트워크 입력 (Network Inputs) 완벽 가이드 (0) | 2025.08.20 |
|---|---|
| [Splunk] 데이터 입력 완벽 가이드 (0) | 2025.08.20 |
| [Splunk] Fishbucket (3) | 2025.08.15 |
| splunk 서버 설정의 일반 설정 기능 알아보기 (1) | 2023.12.11 |
| [Splunk] About Splunk (0) | 2023.04.24 |