엘라스틱서치: 분산 검색 엔진의 원리와 활용

1. 엘라스틱서치란 무엇인가?

Java 언어로 개발된 전문 검색 엔진으로, 사용자가 입력한 쿼리 문자열의 일부를 기반으로 해당 문자열을 포함하는 데이터를 검색할 수 있습니다. 간단히 말해, 분산 검색 및 분석 엔진으로서 분산 배포, 구조화된 검색, 그리고 데이터 분석 기능을 수행할 수 있으며, 주로 마이크로서비스 시스템에 적용됩니다.

쉬운 예로, HR 부서에서 "올해 통급인상 진짐 6666배가 될 것 같다"라는 문자열이 데이터베이스에 저장되어 있다고 가정해 봅시다. 다른 많은 공지사항과 함께 급여 인상 관련 정보를 빠르게 찾고 싶다면, 클라이언트에서 "급여 인상"이나 "진짐"을 입력하면 시스템이 해당 전체 문자열이나 유사한 문자열을 검색해 줄 것입니다. 여기서 더 구체적인 이해가 필요하다면 구글을 사용해 본 경험이 있을 겁니다. 구글에 원하는 키워드를 입력하면 관련 정보를 검색해 주죠. 이것이 바로 전문 검색의 개념입니다.

2. 엘라스틱서치의 전체 설계

엘라스틱서치에서 데이터를 조회하려면 먼저 마이크로서비스 시스템의 데이터를 엘라스틱서치와 동기화해야 합니다. 엘라스틱서치는 시스템과 데이터베이스 사이에 위치하여 고병렬 전문 검색 쿼리에 대한 지원을 제공하는 버퍼 역할을 합니다. 물론 전문 검색 및 데이터 분석 기능을 활용하는 것이 주된 목적입니다. 위에서 설명한 비즈니스 시나리오에 따르면, 관련 요구사항이 있다면 매번 데이터베이스에서 직접 모호한 매칭을 수행하는 방식은 바람직하지 않습니다. 이 방식이 설계적으로 올바른지 여부를 떠나서, 모호한 쿼리의 성능은 매우 낮으며, 높은 동시성 요청은 데이터베이스에 치명적인 위협이 될 수 있습니다. 따라서 적합한 기술로 적절한 작업을 수행하는 것이 중요합니다.

1. 데이터 쓰기 방식

먼저 아래 그림을 통해 엘라스틱서치에 데이터를 쓰는 과정에 대한 간략한 이해를 한 후, 엘라스틱서치 자체가 데이터를 어떻게 저장하는지 분석해 보겠습니다.

그림에는 Document, In-memory buffer, cache, 그리고 segment라는 핵심 키워드가 있습니다. 이 부분들이 바로 엘라스틱서치의 데이터 쓰기 흐름을 구성하는 핵심 요소입니다. 대략적인 흐름은 다음과 같습니다:

  1. 엘라스틱서치는 지속적으로 데이터 DocumentIn-memory buffer에 씁니다.
  2. 특정 조건이 충족되면 In-memory buffer의 Document들이 cache로刷新(새로고침)됩니다. 기본값은 1초에 한 번이므로, 새로 쓰인 Document는 최대 1초 내에 cache에서 검색 가능해집니다.
  3. cache에서 새로운 segment가 생성됩니다. 이 시점에는 아직 디스크에 쓰이지 않았지만, 이미 읽을 수 있습니다.
  4. cache에서 데이터가 비동기적으로 디스크로 쓰여집니다.
2. 데이터 손실 방지 방법

위 단계를 간단히 분석해 보면, cache가 클라이언트의 쓰기 및 쿼리 데이터를 지원하지만, 장애가 발생하면 데이터가 손실될 수 있습니다. 따라서 데이터 손실을 방지하기 위해 데이터를 비동기적으로(fsync) 디스크에 쓰는 영구화 전략을 사용합니다.

실제로 Document가 In-memory buffer에 쓰일 때, 엘라스틱서치는 translog을 추가로 기록합니다. translog은 5초마다 디스크로 fsync됩니다. translog이 충분히 커지거나 일정 시간이 지나면 엘라스틱서치는 flush 작업을 실행합니다.

일반적으로 translog은 5초마다 디스크에 한 번씩 새로고침되므로, 장애로 재시작 시 5초 분의 데이터가 손실될 수 있습니다. 설정 파일을 통해 디스크 쓰기 주기를 줄이도록 구성할 수 있습니다. translog은 기본적으로 30분마다 또는 데이터가 2GB 정도 커지면 flush 작업을 실행합니다.

3. 데이터 구조 설계

엘라스틱서치에는 몇 가지 핵심 개념이 있습니다.

  1. Document: ES에서 데이터의 한 형태로, JSON 형식으로 저장됩니다.
  2. Index(데이터베이스): Document를 저장하기 위한 공간으로, 데이터는 엘라스틱서치에서 2진 형식으로 .fdt 접미사를 가진 문서에 저장됩니다.
  3. Index(쿼리): Document의 인덱스를 나타내며, .fdx 접미사를 가진 문서에 저장됩니다. 인덱스 파일은 기본적으로 엘라스틱서치의 Document ID로 생성됩니다.

일반적으로 엘라스틱서치는 데이터 저장 요청을 받으면 먼저 인덱스 fdx 파일을 생성한 다음, 실제 데이터를 fdt 파일에 저장합니다. 인덱스와 문서는 일대일 대응 관계를 가지며, 조회 시 인덱스를 통해 문서 데이터를 빠르게 찾을 수 있습니다. 이러한 관계를 정방향 인덱스라고 합니다.

하지만 성능에 영향을 미치는 문제가 존재합니다. 수천 개의 데이터가 있을 때 특정 문서 데이터를 조회하려면 해당 문서 데이터를 찾기 위해 반복해야 합니다. 데이터 양이 증가함에 따라 성능 저하는 상당히 심각해집니다. 따라서 역색인을 사용해야 합니다. 역색인은 문서 내용의 단어를 인덱스로 사용하고, 해당 단어를 포함하는 문서 ID를 기록으로 하는 구조입니다.

3. 데이터 검색 원리
1. 토큰화 개념

역색인을 분석하기 전에 토큰화가 무엇인지 이해해야 합니다. 간단히 말해, 문장을 다양한 키워드 또는 핵심어로 나누는 과정입니다. 어떤 규칙으로 토큰화되는지 궁금할 수 있지만, 실제로 전문 검색에서 토큰화 방식은 토큰화기와 밀접한 관련이 있습니다. 나중에 토큰화기에 대해 별도로 학습하겠습니다. 아래 예시는 토큰화를 간단히 설명한 것입니다:

title:"데이터 검색 원리";

// 토큰화 후
데이터
검색
원리
데이터 검색
검색 원리
2. 역색인 생성 과정

간단한 예를 통해 역색인의 생성 과정을 설명해 보겠습니다. 현재 2개의 데이터가 있다고 가정합니다:

message:올해 통급인상 진짐 6666배가 될 것 같다;
message:사장님이 말씀하셨다, 올해 통급인상 없을 것 같다;
  1. 정방향 인덱스는 각 Document에 고유 번호를 부여하여 식별자로 사용합니다.
문서 ID 내용
1 올해 통급인상 진짐 6666배가 될 것 같다
2 사장님이 말씀하셨다, 올해 통급인상 없을 것 같다
  1. 역색인을 생성하려면 먼저 필드 내용을 토큰화합니다. 예를 들어, 두 Document에는 6통급인상급인상사장과 같은 키워드가 포함됩니다. 그런 다음 키워드를 인덱스로 사용하고 해당 문서 ID를 연결하여 역색인을 구성할 수 있습니다. 역색인이 있으면 다양한 검색 요구사항을 빠르고 유연하게 구현할 수 있습니다. 전체 검색 과정에서 어떠한 텍스트의 모호한 매칭도 수행할 필요가 없습니다.
6 1
통급인상 1,2
급인상 1,2
사장 2
  1. 예를 들어 "급인상 사장 말씀"을 조회하려면, 역색인을 통해 먼저 문서 ID 1, 2를 찾고, "사장"을 통해 문서 ID 2를 찾은 다음, 교집합을 취해 ID가 2인 문서를 얻습니다.

  2. 역색인을 사용할 때, 토큰화된 단어Term Dictionary라는 개념을 사용하여 저장됩니다. 하나의 토큰은 Term이며, 파일에서는 .tim 접미사를 가진 문서에 저장됩니다. 문서 ID는 Postings List 컬렉션에 저장되며, 파일에서는 .doc 접미사를 가진 문서에 저장됩니다.

  3. 이 시점에서 우리는 이렇게 저장하면 문서와 토큰의 관계가 1:N이라는 점을 고려해야 합니다. 즉, 하나의 문서는 여러 토큰에 해당할 수 있습니다. 예를 들어, 1000개의 문서는 2000개 이상의 토큰에 해당할 수 있으며, 이는 문서 크기와 토큰화 정밀도에 따라 달라집니다. 대량의 토큰을 검색할 때 CPU는 이러한 Term을 디스크에서 메모리로 로드합니다. 디스크는 한 번에 최대 4MB의 데이터를 로드할 수 있으므로 여러 번에 걸쳐 분단위로 로드됩니다. 이때 단 2개의 단어만 조회하려도 모든 Term을 메모리로 로드해야 할까요? 이는 매우 비효율적입니다.

  4. 사실 엘라스틱서치는 위 문제를 해결하고 Term 조회 효율을 높이기 위해 Term Dictionary 위에 추가로 인덱스 전략을 추상화합니다. Term 인덱스 파일을 저장하며, 파일에서는 .tip 접미사를 가진 문서에 저장됩니다. 조회 시에는 인덱스를 통해 Term 단어를 찾고 메모리로 로드한 다음, 문서 ID를 찾아 최종적으로 문서를 찾을 때까지 진행합니다.

4. 집계 시나리오

먼저 집계가 무엇인지 알아야 합니다. Google에 따르면 집계는 정보 과학에서 관련 데이터를 콘텐츠 선택, 분석, 분류하고, 최종적으로 사람들이 원하는 결과를 분석하는 것을 말합니다. 간단히 말해 통계 작업을 수행하는 것입니다.

사실 엘라스틱서치는 통계의 효율성과 성능을 높이기 위해 데이터 통계 저장 방면에 몇 가지 설계 전략을 적용했습니다. 관계형 데이터베이스에서 데이터는 단위로 저장되지만, 엘라스틱서치는 단위로 저장됩니다. 열 단위 저장은 집계 작업에 유리하며, 이를 doc_values라고 부릅니다.

doc_values 필드 파일은 실제 파일에서 .fnm 접미사로 저장되며, doc_values 값 파일은 .tmd 접미사로 저장됩니다.

태그: 엘라스틱서치 전문 검색 엔진 분산 시스템 역색인 데이터 분석

6월 2일 17:42에 게시됨