[Elasticsearch] Efficient Data Enrichment Using Enrich Processor

Elasticsearch를 쓰다 보면 Index document에 대량으로 새로운 필드를 추가해야 하는 상황이 생긴다.
update-by-query나 bulk update를 시도하기엔 문서 수가 너무 많거나, 문서 하나하나를 업데이트해야 해서 작업 비용이 커지는 경우도 있다.

이런 문제를 해결하기 위해 선택한 기능이 바로 Enrich Processor이다.

Enrich를 사용하면 문서를 인덱싱하는 시점에 다른 인덱스의 참조 데이터를 자동으로 병합할 수 있어서, 복잡한 업데이트 작업 없이 깔끔하게 데이터를 보강할 수 있다.

Enrich란?

Enrich Processor는 인덱싱 과정에서 들어오는 문서를 대상으로, 미리 준비된 참조 데이터(reference data) 를 자동으로 붙이는 기능이다. 한마디로 “문서 저장 전에 실시간 lookup + 자동 join” 을 수행하는 구조이다.

Enrich 기능은 다음 3가지 요소로 구성된다.

Source Index참조 데이터가 들어 있는 인덱스 (예: 제품 정보, 사용자 정보)
Enrich Policy어떤 필드로 매칭하고 어떤 필드를 보강할지 정의
Enrich IndexPolicy 실행 시 생성되는 최적화된 시스템 인덱스 (.enrich-*)

Enrich Processor는 매번 검색을 수행하지 않고, 정적·최적화된 enrich index를 조회하기 때문에 성능 손실 없이 빠르게 보강 작업을 수행한다.

동작 예시

사용자의 이메일을 기반으로 해당 사용자의 기본 정보를 문서에 자동 보강하는 상황을 살펴본다.

1) Source Index 준비

PUT users/_doc/1?refresh=wait_for
{
  "email": "alice@example.com",
  "first_name": "Alice",
  "city": "Seoul"
}

2) Enrich Policy 생성

PUT /_enrich/policy/user-policy
{
  "match": {
    "indices": "users",
    "match_field": "email",
    "enrich_fields": ["first_name", "city"]
  }
}

3) Enrich Policy 실행 → enrich index 생성

POST /_enrich/policy/user-policy/_execute

여기까지 수행하면 .enrich-user-policy-* 형태의 전용 인덱스가 생성된다.

4) Ingest Pipeline 생성

PUT /_ingest/pipeline/user_lookup
{
  "processors": [
    {
      "enrich": {
        "policy_name": "user-policy",
        "field": "email",
        "target_field": "user_info",
        "max_matches": 1
      }
    }
  ]
}

5) 문서 인덱싱

PUT /logs/_doc/1?pipeline=user_lookup
{
  "email": "alice@example.com"
}

// 결과
{
  "email": "alice@example.com",
  "user_info": {
    "first_name": "Alice",
    "city": "Seoul"
  }
}

문서가 인덱싱될 때 자동으로 참조 데이터가 붙는 구조다.
update-by-query 없이 “인덱싱 순간에 데이터가 완성되는” 형태라고 보면 된다.

제한사항

❗ 자주 변경되는 참조 데이터를 Enrich로 처리하는 경우

Enrich Processor는 source index를 직접 조회하지 않고 Enrich Index를 조회하는 구조이다. 따라서 참조 데이터가 변경되면 enrich index를 재생성하는 작업을 반복하게 된다.

참조 데이터가 자주 바뀐다면 재생성 작업을 반복해야 하고, 그만큼 시스템 부하도 증가한다.
특히 대규모 인덱스에서는 재생성 비용이 커져 전체 ingest 성능에 영향을 줄 수 있다.

따라서 Enrich는 자주 변하지 않는 데이터인 경우에 사용하는 것이 적합하다.

Azure DevOps 개요

DevOps 란?

데브옵스(DevOps)는 소프트웨어의 개발(Development)과 운영(Operations)의 합성어로서, 소프트웨어 개발자와 정보기술 전문가 간의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화를 말한다.

주로 아래 그림과 같이 개발과 운영간의 연속적인 사이클로 설명할 수 있다.

이를 통해서 얻는 장점은 다음과 같다.

  1. 신속한 제공
    • 릴리스의 빈도와 속도를 개선하여 제품을 더 빠르게 혁신하고 향상할 수 있다. 새로운 기능의 릴리스와 버그 수정 속도가 빨라질수록 고객의 요구에 더 빠르게 대응할 수 있다.
  2. 안정성
    • 최종 사용자에게 지속적으로 긍정적인 경험을 제공하는 한편 더욱 빠르게 안정적으로 제공할 수 있도록, 애플리케이션 업데이트와 인프라 변경의 품질을 보장할 수 있다.
  3. 협업 강화
    • 개발자와 운영 팀은 긴밀하게 협력하고, 많은 책임을 공유할 수 있도록, 워크플로를 결합한다. 이를 통해 비효율성을 줄이고 시간을 절약할 할 수 있다.
  4. 보안
    • 제어를 유지하고 규정을 준수하면서 신속하게 진행할 수 있다. 자동화된 규정 준수 정책, 세분화된 제어 및 구성 관리 기술을 사용할 수 있다.

그럼, DevOps를 실현하기 위해서는 어떻게 해야 하는가?

DevOps를 실현하기 위해서는 CI(Continuous Integration)/CD(Continuous Deployment(Delivery))라는 2가지 작업을 해야 한다.

CI(Continuous Integration)은 Development에 속하는 작업으로 지속적으로 프로젝트의 요구사항을 추적하며, 개발된 코드를 테스트 및 빌드를 수행한다.

  1. 프로젝트 기획 + 요구사항 추적
    • 프로젝트 시작
    • 기획(프로젝트 방법론 채택)
    • 작업관리(Backlog 관리)
    • 진행상황 추적
  2. 개발 + 테스트
    • 코드작성
    • 단위 테스트
    • 소스제어
    • 빌드
    • 빌드 확인

CD(Continuous Deployment(Delivery))는 Operations에 속하는 작업으로 CI가 완료되어 빌드된 소스를 통합 테스트(개발, QA, Staging)를 거쳐 배포를 하며, 배포된 사항들을 지속적으로 모니터링하고 프로젝트 요구사항에 피드백하는 작업을 수행한다.

  1. 빌드 + 배포
    • 자동화된 기능 테스트
    • 통합 테스트 환경(Dev)
    • 사전 제작 환경
      (QA, Load testing)
    • 스테이징 환경(Staging)
  2. 모니터링 + 피드백
    • 모니터링
    • 피드백

이제, DevOps를 하기위한 구체적인 작업을 알았으니, 실제 구성을 하도록 하는 제품들에 대해서 알아보자.

Azure DevOps vs Other Software

DevOps를 하기 위한 솔루션들은 이미 시중에 엄청나게 나와 있으며, 대게 오픈소스 형태로 많이 제공되고 있어서 바로 가져다 사용할 수 있다.

위 그림에서 볼 수 있듯이 DevOps의 각 단계에 맞추어서 원하는 (특화된)제품을 선택하여 사용하면 된다.

모든 단계를 빠짐 없이 구현한다고 가정하여, 예를 들면 다음과 같이 DevOps가 구현 될 수 있다.

  1. Slack으로 요구사항 관리를 하고
  2. Git으로 소스코드 관리를 하고
  3. Maven으로 빌드를 하고
  4. JUnit으로 테스트하고
  5. Jenkins로 Docker에 배포하고
  6. Kubernetes로 운영하며
  7. Splunk로 모니터링 한다.

그런데 이런 경우, 벌써 필요한 제품에 8개나 된다. 프로젝트에 참여하는 모든인원이 이 제품들에 대해서 이해하고 사용하기 어려우며, 각 제품에대한 담당자들있어야 제대로 운영 될 수 있을 것이다. 게다가, 각기 다른 제품이라 다음 단계로 넘어가기 위한 추가적인 관리를 해야할 것이다.

이렇게 되면, 규모가 작은 곳에서는 몇가지 단계를 건너띄고 관리를 하게 되는데 이런 부분에서 예외사항이 생기기 시작하고, 결국 프로젝트 끝에서는 DevOps를 거의하지 못하는 상황이 생길 수 도있다.

반면, Azure DevOps는 하나의 DevOps 관리 솔루션을 제공한다. 때문에 Azure DevOps 하나만 사용해도 모든 절차를 구성 할 수 있다.
그리고 만약, 기존에 사용하던 제품이 있다 하더라도 아래 그림과 같이 3rd-party를 마이그레이션 혹은 연동 설정 할 수 있도록 하기 때문에 Azure DevOps 제품안에서 하나로 통합 관리 할 수 있다.

마지막으로, Azure DevOps를 사용하는 간단한 시나리오에 대해서 알아보자.

Azure DevOps에서는 파이프라인이라는 형태로 CI/CD를 구성하도록 되어 있으며, 각 단계 구성은 아래 그림과 같다.

  1. Project (Agile) Board를 통해서 프로젝트 요구사항 추적 관리를 하고
  2. Repo에서 각 Agile Board Task에 대한 소스코드 관리를 하고
  3. 소스가 커밋이 되면 CI 파이프라인을 통해 빌드 + 테스트를 수행하고
  4. CI가 완료되면 Trigger 형태로 CD 파이프라인을 실행하고
  5. CD 파이프라인을 통해 통합 테스트 + 배포를 하고
  6. (옵션)담당자에게 최종 승인을 받고
  7. 운영 적용 및 모니터링을 한다.

Azure DevOps 이 외의 제품을 사용 했을 때와 단계는 거의 동일 하지만, 여기서 주목 할 점은 Azure DevOps 단일 제품에서 모두 제공 받고 구성 할 수 있다는 것이다.

(**여기서 다 설명 못한 부분이지만 CI/CD 과정 중에 Function(Trigger) 형태로 여러 기능들을 다양하게 엮을 수도 있다. 예를 들어 6번)

각각의 솔루션 전문가들이 있어서 운영한다면 문제가 없겠지만, DevOps를 처음 도입한다던가 규모가 작아 축소 운영을 해야하는 상황이라면 고려해 볼 수 있을 것 같다.