Elasticsearch 입문 24편 Ingest Pipeline. Processor 종류·grok·set·remove·conditional·_simulate·default vs final pipeline.
이 글은 Elasticsearch 입문에서 운영까지 시리즈 38편 중 24편이에요. 직전 23편에서 Bulk API 로 한 번에 수만 건을 꽂아 넣는 법을 익혔는데, 그때 "색인 전에 데이터를 살짝 가공해야 하는 자리" 가 자꾸 튀어나왔을 거예요. 타임스탬프 포맷이 다르거나, IP 주소를 파싱해야 하거나, 민감 필드를 지워야 하거나 — 이런 자리를 클라이언트가 아니라 ES 가 직접 잡는 길이 Ingest Pipeline 이에요.
Elasticsearch 8.x 공식 docs 의 Ingest pipelines · Processors 섹션을 참고해 한국어 학습 노트로 풀어 쓴 자료예요.
로컬 Docker 클러스터에서 _ingest/pipeline/_simulate 한 번만 직접 두드려 보면 본문이 한층 잘 박혀요.
색인 전에 문서를 가공하는 ES 내장 ETL
옛날에는 Logstash 가 이 자리를 거의 독점했어요. "소스에서 읽어 → 필드 가공 → ES 로 색인" 흐름의 가운데 자리에 Logstash 가 들어가서 grok·mutate·date 같은 필터를 쭉 걸어주는 구조였죠. 그런데 Logstash 한 대를 따로 띄우는 운영 비용이 만만치 않아요. JVM 한 통, 설정 파일 한 뭉치, 모니터링 한 세트가 추가로 붙거든요.
Ingest Pipeline 은 그 가운데 자리 를 ES 클러스터 안으로 옮긴 기능이에요. 색인 직전에 문서가 거치는 전처리 파이프라인 을 정의해 두고, 클라이언트는 평소처럼 PUT /index/_doc 만 하면 ES 가 알아서 가공해 색인해 줘요. "Logstash 없는 ELK" 를 가능하게 만든 핵심 기능 자리.
핵심 비유 한 줄로 풀면 — Ingest Pipeline 은 PG 의 BEFORE INSERT 트리거 와 비슷한 자리예요. 들어오는 행을 그대로 받지 않고, 정의된 가공 단계를 거쳐서 최종 형태로 변환된 행 이 테이블에 박히는 식. 차이가 있다면 ES 는 이 변환을 JSON 문서 단위로, 분산 노드에서 병렬로 돈다는 점.
세 가지 자리에서 거의 항상 등장해요. 로그 수집 자리 — Filebeat 가 raw 로그 라인을 그대로 보내면 grok 으로 파싱해 필드로 쪼개요. 클라이언트 단순화 자리 — 앱이 보내는 JSON 에 @timestamp 가 없으면 set processor 로 자동 추가. 데이터 정제 자리 — PII 필드(주민번호·전화번호) 를 remove · script 로 마스킹하거나 지워요.
작성 시점(2026-05-19) 기준 ES 8.x 에서는 40개 이상의 내장 processor 가 제공돼요. 본문에서는 자주 쓰이는 핵심 8개(grok · set · remove · rename · convert · date · split · script) 를 깊게 보고, 나머지는 "필요할 때 docs 뒤져서 찾는다" 정도로만 짚을게요.
Ingest Node — 8.x 에서는 거의 모든 노드가 ingest
ES 7.x 까지는 ingest 역할 을 가진 노드만 파이프라인을 실행할 수 있었어요. master·data·ingest·coordinating 식으로 노드 역할이 명확히 분리돼서, "전용 ingest 노드를 따로 두느냐 마느냐" 가 운영 토픽이었거든요.
8.x 부터는 기본값이 바뀌었어요. 노드 설정에서 역할을 명시하지 않으면 master · data · ingest · ml · remote_cluster_client · transform 을 모두 갖는 all-rounder 가 돼요. 즉, 별 설정 없이 클러스터를 띄우면 모든 노드가 ingest 가능 해요. 그래서 작은 클러스터에서는 ingest 노드를 따로 신경 쓸 일이 거의 없어요.
다만 대규모 운영 환경 에서는 ingest 부하가 데이터 노드 검색 성능을 갉아먹는 사고가 잦아서, 전용 ingest 노드 2~3대 를 따로 둬요. elasticsearch.yml 에 node.roles: [ingest] 만 박은 노드를 별도로 띄우고, 클라이언트의 _bulk 요청을 coordinating 노드 → ingest 노드 → data 노드 순서로 라우팅하는 구조.
작은 팁 한 줄 — 데이터 노드만 따로 두고 ingest 를 끄고 싶다 면 node.roles: [data, master] 처럼 ingest 를 명시적으로 빼야 해요. 8.x 기본값은 역할을 빼지 않으면 자동으로 켜진다 가 핵심.
Pipeline 생성 — _ingest/pipeline/{name} PUT
파이프라인은 클러스터 단위 리소스 라서 한 번 만들어 두면 모든 인덱스가 공유해서 써요. 생성 API 는 단순.
PUT _ingest/pipeline/access-log-pipeline
{
"description": "nginx access log 파싱 + 타임존 보정",
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{IP:client_ip} - - \\[%{HTTPDATE:ts}\\] \"%{WORD:method} %{URIPATHPARAM:path} HTTP/%{NUMBER}\" %{NUMBER:status:int} %{NUMBER:bytes:int}"]
}
},
{
"date": {
"field": "ts",
"formats": ["dd/MMM/yyyy:HH:mm:ss Z"],
"timezone": "Asia/Seoul",
"target_field": "@timestamp"
}
},
{
"remove": { "field": ["ts", "message"] }
}
],
"on_failure": [
{ "set": { "field": "_ingest_failed", "value": true } },
{ "set": { "field": "_ingest_error", "value": "{{ _ingest.on_failure_message }}" } }
]
}
세 가지 항목만 짚으면 끝이에요. description 은 사람이 읽는 메모. processors 는 위에서 아래로 순차 실행 되는 가공 단계 배열. on_failure 는 어느 processor 가 실패하면 호출되는 백업 핸들러로, 실패한 문서를 dead-letter 인덱스 로 빼거나 에러 메시지를 필드로 박아 두는 자리예요.
조회·수정·삭제도 REST API 로 간단해요. GET _ingest/pipeline/access-log-pipeline 으로 조회, PUT 으로 덮어쓰기, DELETE _ingest/pipeline/access-log-pipeline 으로 삭제. 운영에서는 버전 관리 를 위해 version 필드를 박아 두는 패턴이 표준 — pipeline 자체에 정수 버전을 부여해서 잘못 덮어쓴 사고를 추적 하는 자리.
주요 Processor 8개
40개 넘는 processor 중에서 실무 자리의 80% 를 잡는 8개만 우선 정리해요. 나머지는 공식 docs · _ingest/processor/grok 같은 introspection API 로 그때그때 찾으면 됩니다.
grok — 정규식 기반 파싱
raw 텍스트를 구조화 필드로 쪼개는 자리에 가장 자주 등장해요. Logstash 의 grok 필터 와 완전히 같은 패턴 문법 을 써서 — 기존 Logstash 설정을 거의 그대로 옮겨올 수 있어요. %{IP:client_ip} 같이 %{PATTERN_NAME:field_name[:type]} 구문이 핵심.
내장 패턴이 100개 이상 있어요. IP · IPV4 · IPV6 · HTTPDATE · URIPATHPARAM · LOGLEVEL · WORD · NUMBER · GREEDYDATA 정도가 가장 자주 쓰여요. 사용 가능한 모든 패턴 은 GET _ingest/processor/grok 로 확인 가능.
set — 필드 채우기
상수 또는 다른 필드의 값을 새 필드에 박는 자리. @timestamp 가 없는 문서에 색인 시각을 박는다 · 데이터 출처를 source: "nginx" 로 표기한다 같은 자리에 자주 등장해요.
{ "set": { "field": "ingest_time", "value": "{{_ingest.timestamp}}" } }
{ "set": { "field": "source", "value": "nginx", "override": false } }
override: false 옵션은 이미 그 필드가 있으면 건드리지 않는다 는 안전장치예요. 클라이언트가 일부러 박아 둔 값을 덮어쓰는 사고를 막는 자리.
remove — 필드 삭제
PII 마스킹·임시 필드 청소·용량 절약 자리에 등장. 단순.
{ "remove": { "field": ["password", "ssn", "_raw_message"] } }
배열로 여러 필드를 한 번에 지울 수 있고, 없는 필드를 지우려고 하면 실패 가 기본 동작이라 ignore_missing: true 를 같이 박아 두는 게 안전해요.
rename — 필드 이름 변경
소스 시스템마다 같은 데이터를 다른 이름 으로 부를 때 정규화하는 자리. src_ip → client_ip · usr → user_id · ts → @timestamp 같은 자리.
{ "rename": { "field": "src_ip", "target_field": "client_ip", "ignore_missing": true } }
convert — 타입 변환
문자열로 들어온 숫자·불린을 매핑에 맞는 타입으로 바꿔요. grok 으로 파싱한 직후 %{NUMBER:status} 같은 필드가 문자열 로 들어오기 때문에 자주 같이 묶여요.
{ "convert": { "field": "status", "type": "integer" } }
{ "convert": { "field": "bytes", "type": "long" } }
type 으로 integer · long · float · double · boolean · string · ip · auto 를 지원해요. auto 는 값을 보고 적당히 추론 하는 옵션인데, 운영에서는 명시적으로 타입을 박는 쪽이 사고가 적어요.
date — 타임스탬프 파싱
다양한 포맷의 시각 문자열을 ES 가 이해하는 ISO-8601 datetime 으로 변환해서 @timestamp 같은 필드에 박는 자리. 로그 ingest 의 99% 자리에 등장해요.
{
"date": {
"field": "ts_raw",
"formats": ["dd/MMM/yyyy:HH:mm:ss Z", "ISO8601", "UNIX_MS"],
"timezone": "Asia/Seoul",
"target_field": "@timestamp"
}
}
formats 배열에 여러 포맷을 순서대로 박아 두면 가장 먼저 매칭되는 포맷 으로 파싱해요. UNIX · UNIX_MS · TAI64N · ISO8601 같은 표준 약어도 지원.
split — 문자열 → 배열
CSV 라인이나 tag1,tag2,tag3 같은 구분자 기반 문자열 을 진짜 배열 필드 로 쪼개는 자리.
{ "split": { "field": "tags", "separator": "," } }
원본 필드를 그대로 덮어써서 배열로 바꾸는 게 기본 동작이라 — 원본이 필요하면 target_field 를 따로 지정해야 해요.
script — Painless 스크립트
위 7개로 안 되는 진짜 임의 로직 은 script processor 가 받아요. Painless (ES 가 만든 script 전용 언어, Java 비슷한 문법) 코드를 박을 수 있고, ctx 변수 가 현재 문서 전체 를 가리켜요.
{
"script": {
"source": "ctx.full_name = ctx.first_name + ' ' + ctx.last_name; ctx.remove('first_name'); ctx.remove('last_name');"
}
}
복잡한 로직을 줄여줄 수 있는 강력한 도구지만 — 비용이 비싸요. 본문 후반 사고 섹션에서 script processor 폭주 자리를 따로 다룰게요.
grok 깊게 — Logstash 호환 정규식 파싱
ingest 의 가장 자주 만지는 processor 한 자리 라서 한 번 더 깊이.
grok 의 핵심은 "복잡한 정규식을 짧은 이름으로 부르는 alias 시스템" 이라는 점이에요. %{IP} 라는 짧은 표기 뒤에 실제로는 IPv4·IPv6 까지 잡는 긴 정규식 이 숨어 있어요. 이 alias 들을 조합 해서 한 줄을 통째로 파싱하는 식.
기본 문법은 세 가지 자리만 외우면 끝.
| 문법 | 의미 | 예 |
|---|---|---|
%{PATTERN} |
매칭만 (필드 생성 X) | %{IP} |
%{PATTERN:name} |
매칭 + name 필드로 추출 | %{IP:client_ip} |
%{PATTERN:name:type} |
추출 + 타입 변환 | %{NUMBER:bytes:int} |
자주 헷갈리는 자리 — %{NUMBER:bytes:int} 처럼 grok 안에서 :int 로 타입을 박아도 별도의 convert processor 가 필요 한 경우가 있어요. 이유는 grok 의 타입 변환이 문자열을 숫자로 캐스팅 하는 정도라서, long·double 같은 명시적 타입 이 필요하면 convert 를 따로 걸어야 해요.
복잡한 라인은 여러 패턴을 배열 로 던지면 grok 이 위에서 아래로 시도 하다 첫 번째 매칭에서 멈춰요. Apache · nginx · Tomcat · 자체 앱 로그 포맷이 섞여 있을 때 자주 쓰이는 패턴.
{
"grok": {
"field": "message",
"patterns": [
"%{COMBINEDAPACHELOG}",
"%{COMMONAPACHELOG}",
"%{IP:client_ip} %{GREEDYDATA:rest}"
]
}
}
custom pattern 도 인라인으로 박을 수 있어요. pattern_definitions 에 내가 만든 이름 을 등록해 두면 %{MY_PATTERN} 처럼 호출 가능.
Conditional Processor — if 절로 분기
모든 문서에 같은 가공을 거는 게 아니라 "이 문서가 이 조건이면 이 processor 만 돌린다" 자리는 if 옵션이 잡아요. 모든 processor 에 공통으로 들어가는 옵션 이라서 — 별도 if processor 가 따로 있는 게 아니에요.
{
"set": {
"if": "ctx.log_level == 'ERROR'",
"field": "alert",
"value": true
}
}
if 표현식은 Painless script 라서 ctx.필드명 · ctx.containsKey('key') · && · || 같은 자바 비슷한 문법이 다 들어와요. 복잡한 분기 는 script processor 안에 if-else 로 묶는 게 더 깔끔.
자주 쓰이는 자리 — "민감 데이터가 있는 인덱스에만 마스킹 처리를 한다", "특정 환경(prod) 만 추가 메타데이터 박는다", "에러 로그만 알람 필드 박는다" 같은 자리.
Pipeline 적용 — index·document·default·final
만든 파이프라인을 어떻게 호출하느냐 가 두 갈래로 갈려요.
단일 요청에 박기 — ?pipeline=<name>
가장 단순한 자리. _bulk 또는 _doc 요청 URL 에 쿼리 파라미터 로 박으면 그 요청에 한해 파이프라인이 돌아요.
POST nginx-logs/_doc?pipeline=access-log-pipeline
{ "message": "192.168.1.1 - - [19/May/2026:10:00:00 +0900] \"GET / HTTP/1.1\" 200 1234" }
장점은 명시적. 어느 요청이 어느 pipeline 을 거치는지 클라이언트 코드에서 한눈에 보여요. 단점은 클라이언트마다 다 박아야 한다 는 점.
인덱스 기본값 — index.default_pipeline
인덱스 settings 에 기본 pipeline 을 박아 두면 그 인덱스로 들어오는 모든 요청 이 자동으로 그 pipeline 을 거쳐요. 클라이언트가 몰라도 적용되는 자리.
PUT nginx-logs/_settings
{ "index.default_pipeline": "access-log-pipeline" }
운영에서 가장 자주 쓰는 패턴이에요. Filebeat·Logstash 클라이언트는 평소대로 색인만 하면 ES 가 알아서 가공해요.
Final pipeline — index.final_pipeline
final_pipeline 은 default_pipeline 이 끝난 뒤 마지막으로 한 번 더 도는 후처리 자리예요. 공통 메타데이터(@cluster · @env) 박기 · PII 마스킹 일괄 적용 같은 모든 인덱스에 공통으로 걸어야 하는 후처리 자리에 적합.
PUT _template/all-indices-final
{
"index_patterns": ["*"],
"settings": { "index.final_pipeline": "global-meta-pipeline" }
}
요청·default·final 의 우선순위는 — 요청의 ?pipeline= 이 default 를 덮어쓰고, final 은 항상 마지막에 한 번 더 돌아요.
_simulate API — 색인 전에 검증
ingest pipeline 의 진짜 가치 가 여기에 있어요. 실제 색인 전 에 지정한 문서가 pipeline 을 거치면 어떻게 변하는지 미리 시뮬레이션할 수 있어요. grok 정규식 수정하고 한 번 시뮬, 또 수정하고 또 시뮬 — 이 반복이 ingest 개발 워크플로의 90%.
두 가지 모드가 있어요.
기존 pipeline 시뮬
이미 클러스터에 등록한 pipeline 으로 샘플 문서 만 흘려 보내는 자리.
POST _ingest/pipeline/access-log-pipeline/_simulate
{
"docs": [
{
"_source": {
"message": "192.168.1.1 - - [19/May/2026:10:00:00 +0900] \"GET / HTTP/1.1\" 200 1234"
}
}
]
}
새 pipeline 미리 시뮬
아직 등록하지 않은 pipeline 정의 자체 를 요청 본문에 같이 던지는 자리. PUT 으로 박기 전에 검증 하는 패턴.
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{ "grok": { "field": "message", "patterns": ["%{IP:client_ip}"] } }
]
},
"docs": [
{ "_source": { "message": "192.168.1.1 - test" } }
]
}
?verbose=true 옵션을 같이 박으면 각 processor 단계마다 문서가 어떻게 변했는지 단계별 로그까지 돌려줘요. 디버깅 자리에 가장 강력한 무기.
자주 만나는 사고
사고 1 — Pipeline 실패 시 색인 중단
원인 — 어느 processor 가 실패하면 기본 동작 으로 문서 색인 자체가 거부 되고 _bulk 응답에 pipeline_processor_exception 이 박혀요. Filebeat·Logstash 가 retry 폭주 → 메모리 폭주.
해결 — pipeline 에 on_failure 블록을 박아서 실패해도 색인은 계속 가게 만들어요. 실패한 문서는 _ingest_failed: true 필드를 박아서 별도 인덱스로 reroute 하거나, dead-letter 인덱스 로 빼는 패턴이 표준. 개별 processor 에도 ignore_failure: true 를 박을 수 있어요.
사고 2 — grok 정규식 폭주 (catastrophic backtracking)
원인 — grok 안의 정규식이 .` 같은 탐욕 quantifier 와 중첩 alternation 이 섞이면 backtracking 폭주 로 한 줄 파싱에 수 초~수 분 걸리는 사고. ingest 노드 CPU 100%, 클러스터 마비.
해결 — GREEDYDATA (.*) 대신 %{DATA} (.*? non-greedy) 를 우선 검토. 복잡한 라인 은 grok 한 줄로 안 풀고 dissect processor (구분자 기반 빠른 파서) 를 먼저 걸어서 큰 단위로 쪼갠 뒤 grok 으로 작은 단위 만 파싱. timeout_millis 옵션을 grok 에 박아서 한 줄 파싱이 N ms 넘으면 중단 시키는 안전장치도 있어요.
사고 3 — script processor 비용 폭주
원인 — 운영에서 문서 하나당 Painless 스크립트가 100줄 같은 자리는 비교적 가벼운 작업도 ingest 노드 CPU 를 갉아먹어요. 초당 만 건 ingest 자리에서 script processor 한두 개 가 지연 10ms → 200ms 로 폭증.
해결 — 내장 processor 조합 으로 풀 수 있으면 무조건 그쪽. 문자열 변환은 gsub · 타입 변환은 convert · 필드 추출은 grok · 분기는 if 식으로 script 를 마지막 카드 로 남겨 둬요. 정말 script 가 필요하면 stored_script 로 미리 컴파일 해 두는 게 매번 inline parse 보다 빨라요.
사고 4 — Ingest queue 폭주
원인 — 전용 ingest 노드 가 2대뿐인데 Filebeat 클라이언트 가 200대 붙어서 초당 50만 건을 쏟아 부으면, ingest 큐가 queue capacity (기본 10000) 를 넘으면서 es_rejected_execution_exception 으로 색인이 깨져요.
해결 — ingest 노드 수평 확장 이 1순위. 노드 추가 + node.roles: [ingest] 만 박은 전용 ingest 노드 2~3대 더 추가. 클라이언트 측에서는 bulk 요청 사이즈를 줄이고 백오프 로 압력 조절. 모니터링은 _nodes/stats/thread_pool 의 write · search 큐 카운트를 Grafana 알람 으로 박아 둬요. 28편(Performance) 에서 깊이.
사고 5 — default_pipeline 무한 루프
원인 — pipeline A 안의 reindex processor 가 다른 인덱스로 쓰고, 그 인덱스의 default_pipeline 이 다시 A 를 호출 하는 식의 순환 참조. ES 클러스터가 자기 자신을 호출하다 OOM·CPU spike 로 죽어요.
해결 — default_pipeline 으로 가공한 인덱스 안에서 reindex 나 cross-pipeline 호출 을 철저히 피하기. 정 필요하면 target 인덱스의 default_pipeline 을 명시적으로 다른 것으로 바꿔서 순환을 끊어 둬요. pipeline 안에 다른 pipeline 호출 (pipeline processor) 도 깊이 제한 이 있어서 — 3단계 이상 중첩 X 가 안전한 가이드.
사고 6 — _simulate 결과와 실제 색인이 다름
원인 — _simulate 는 pipeline 만 돌려요. 인덱스 mapping 검증·analyzer 적용은 실제 색인 시 에 별도로 진행돼서 — simulate 는 통과했는데 실제 색인은 mapper_parsing_exception 같은 자리가 가끔 등장.
해결 — _simulate 통과 + 테스트 인덱스에 실제 색인 1건 까지 두 단계로 검증하는 게 표준 워크플로. staging 클러스터 에 prod 인덱스 mapping 그대로 복사한 인덱스 를 만들어 두고 거기서 한 번 더 테스트해요.
사고 7 — Final pipeline 누락으로 메타 빠짐
원인 — final_pipeline 으로 박은 공통 메타데이터 가 재색인(reindex) 자리 에서 기본적으로 적용 X 되는 경우. prod → staging reindex 후에 @cluster · @env 같은 메타가 통째로 빠져서 Kibana 대시보드가 깨져 보이는 사고.
해결 — reindex 요청에 dest.pipeline 을 명시적으로 박아 줘요. 또는 target 인덱스의 final_pipeline 이 모든 인덱스 템플릿 에 일관되게 적용되도록 cluster-level 템플릿 으로 박아 두는 게 안전.
운영 권장 패턴 4가지
운영에서 ingest pipeline 을 처음부터 그렇게 박아 두면 사고가 줄어드는 자리 네 곳을 골랐어요.
(1) on_failure 는 무조건 박는다 — 모든 운영 pipeline 의 최상위 on_failure 에 _ingest_failed: true 박기 + 에러 메시지 보존 + dead-letter 인덱스 reroute 세 가지를 박아 둬요. 재처리 가능한 형태 로 실패 문서를 살려 두는 게 데이터 손실 0 의 첫걸음.
(2) _simulate 가 곧 테스트 코드 — pipeline 정의를 git 으로 관리하고, 각 pipeline 마다 샘플 문서 + 예상 결과 를 JSON 파일 로 같이 두는 패턴. CI 에서 _simulate 호출 → 예상 결과와 비교 로 pipeline 회귀 테스트 를 자동화. grok 정규식 수정 같은 자리에서 사고를 80% 줄여 줘요.
(3) script 보다 내장 processor — 처음에는 script 로 빠르게 짜 두고, 운영 1~2주 안에 내장 processor 조합으로 리팩토링 하는 흐름이 표준. 내장 processor 가 같은 일을 10배 가볍게 처리해요. 정 script 가 필요하면 stored_script + cache: true 로 캐싱 부담을 줄이세요.
(4) 인덱스 템플릿 + final_pipeline 으로 전사 표준 메타 — @cluster · @env · @ingest_at 같은 모든 문서에 공통으로 박혀야 하는 메타 는 cluster-level 인덱스 템플릿 + final_pipeline 으로 한 자리에 박아 둬요. 새 인덱스가 생겨도 자동으로 같은 메타가 박힘. Kibana 대시보드·알람 룰의 공통 필터 자리가 깨질 일이 없어요.
시험 직전 한 번 더 — 압축 노트
- Ingest Pipeline = 색인 전에 문서를 가공하는 ES 내장 ETL. Logstash 의 가운데 자리 를 클러스터 안으로 옮긴 기능.
- 8.x 기본값 으로 모든 노드가 ingest 가능. 대규모면 전용 ingest 노드 2~3대 분리.
- 생성 =
PUT _ingest/pipeline/{name}+description · processors · on_failure. - 자주 쓰는 processor 8개 =
grok · set · remove · rename · convert · date · split · script. - grok = Logstash 호환 정규식 alias.
%{IP:client_ip}문법. 내장 패턴 100+ 개.GET _ingest/processor/grok로 목록. - conditional = 모든 processor 의
if옵션. Painless 표현식. 별도 if processor X. - 적용 = 요청
?pipeline=· 인덱스default_pipeline· 전사final_pipeline세 갈래. - _simulate = 색인 전 검증 도구. 기존 pipeline 시뮬과 새 pipeline 정의 시뮬 두 모드.
?verbose=true단계별 로그. - 7대 사고 = pipeline 실패 색인 중단 · grok 백트래킹 · script 비용 · ingest 큐 폭주 · default_pipeline 순환 · _simulate vs 실제 차이 · final_pipeline 누락.
- 운영 4 패턴 = on_failure 무조건 · _simulate 회귀 테스트 · script 보다 내장 · 인덱스 템플릿 + final_pipeline 전사 메타.
- dissect processor = grok 보다 구분자 기반 빠른 파서. 복잡한 라인은 dissect 먼저 → grok 나중.
stored_script= inline 보다 캐싱 효율. 자주 호출되는 script processor 자리.- PII 마스킹 =
remove또는script(정규식 치환) processor 자리. 운영 표준. - ingest pipeline 은 PG 의 BEFORE INSERT 트리거 와 같은 자리. 분산·JSON·여러 노드 병렬 이 차이.
시리즈 다른 편
- 이전 글 = 23편 Bulk API — 한 번에 수만 건 색인하기
- 다음 글 = 25편 Logstash·Beats — 외부 ETL 파이프라인 두 도구
- 11편 = Korean Analyzer — Nori·mecab-ko·사용자 사전
- 19편 = Search Features — search_after·scroll·deep pagination
- 28편 = Performance — bulk·refresh·thread pool 튜닝
- 32편 = Spring Data Elasticsearch — Repository·Template·POJO
- 33편 = Kibana·ELK — Logstash 와 묶은 로그 스택
- 38편 = 시리즈 마무리 — 결정 트리·체크리스트·자격증
한 줄 정리 — Ingest Pipeline = 색인 전에 ES 가 직접 돌리는 분산 ETL. grok·set·remove·rename·convert·date·split·script 8개 processor + if 분기 + _simulate 검증으로 Logstash 없는 ELK 가 가능해진 자리.