ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ElasticSearch Essential
    ELK/Elasticsearch 2023. 11. 23. 17:22

    ElasticSearch 소개

    - ElasticSearch란 Lucene 기반의 오픈 소스 검색엔진

        ㆍJSON 기반의 문서를 저장하고 검색할 수 있으며 분석 작업도 가능하다.

    - 준실시간 검색 시스템

        ㆍ실시간이라고 생각될 만큼 색인된 데이터가 빠르게 검색된다.

    - 고가용성을 위한 클러스터 구성

        ㆍ한 대 이상의 노드로 클러스터를 구성하여 높은 수준의 안정성을 달성하고 부하 분산이 가능하다.

    - 동적 스키마 생성

        ㆍ입력될 데이터들에 대해 미리 스키마를 정의하지 않아도 동적으로 스키마 생성이 가능하다.

    - Rest API 기반의 인터페이스

        ㆍRest API 기반의 인터페이스를 제공하여 비교적 사용을 위한 진입 장벽이 낮다.

     

    클러스터와 노드 이해하기

    - 클러스터 : 컴퓨터 클러스터는 여러 대의 컴퓨터들이 연결되어 하나의 시스템처럼 동작하는 컴퓨터들의 집합을 말한다.

    - ElasticSearch 클러스터 : 여러 대의 노드들이 각자의 역할을 바탕으로 연결되어 하나의 시스템처럼 동작하게 되어 있다.

        ㆍ어떤 노드에 어떤 요청을 해도 동일한 응답을 준다.

     

    - 클러스터의 성능이 부족하면 노드를 늘려서 대응할 수 있다.

        ㆍ하지만 노드를 늘린다고 모두 성능을 늘릴 수 있는 건 아니다.

     

    - 노드의 종류

    종류 역할
    마스터 노드 클러스터 상태 관리 및 메타데이터 관리
    데이터 노드 문서 색인 및 검색 요청 처리
    코디네이팅 노드 검색 요청 처리
    인제스트 노드 색인되는 문서의 데이터 전처리

     

    - 마스터 노드

        ㆍ마스터 노드는 마스터 노드와 마스터 후보 노드로 이루어진다.

        ㆍ마스터 노드는 지금 클러스터에서 마스터 노드의 역할을 하고 있는 노드이다.

        ㆍ마스터 후보 노드는 마스터 노드에 문제가 생겼을 때 마스터 노드가 될 수 있는 노드이다.

        ㆍ마스터 노드가 죽으면 마스터 후보 노드들 중에서 새로운 마스터가 된다.

     

    * 각각의 노드가 본연의 역할에 충실할 수 있도록 구성하는 것이 중요하다.

        ㆍ클러스터이기에 누구에 어떤 요청을 해도 괜찮지만 각자의 역할에 충실할 수 있게 하는게 더 효율적이다.

    * 예를 들어 데이터 노드에 대한 직접적인 요청을 차단하고 앞쪽에 로드밸런서를 둔다.

     

    인덱스와 샤드 이해하기

    ElasticSearch RDBMS
    index database
    mapping schema
    document row

     

    - 인덱스란? : 문서가 저장되는 논리적인 공간

        ㆍ문서를 저장하기 위해서는 반드시 인덱스가 존재해야 한다.

        ㆍ인덱스를 설계하는 것이 ElasticSearch를 사용하기 위해 고려해야 하는 첫 단계이다.

        ㆍ인덱스 설계에 따라 달라지는 문서의 구조 및 검색 쿼리 - 사용 패턴과 문서의 특성에 따라 설계 해야 한다.

    케이스 장점 단점
    하나의 인덱스를 사용할 때 관리해야 할 인덱스의 수가 적어
    관리 리소스가 적게 발생한다.
    쿼리와 문서의 구조가 복잡해 질 수 있다.
    여러개의 인덱스로 나눌 때 각각의 경우에 최적화된 쿼리와
    문서 구조를 사용할 수 있다
    관리해야 할 인덱스의 수가 많아
    관리 리소스가 발생할 수 있다.

        ㆍ하나의 인덱스로 단순하게 시작 -> 사용 패턴에 따라 인덱스를 별도로 운동

     

    - 샤드(shard)란? : 인덱스에 색인되는 문서가 저장되는 공간

        ㆍ하나의 인덱스는 반드시 하나 이상의 샤드를 가진다.

    종류 역할
    프라이머리 샤드 문서가 저장되는 원본 샤드, 색인과 검색 성능에 모두 영향을 줌
    레플리카 샤드 프라이머리 샤드의 복제 샤드, 검색 성능에 영향을 줌
    프라이머리 샤드에 문제가 생기면 레플리카 샤드가 프라이머리 샤드로 승격

     

    - 샤드 라우팅 

        ㆍRouting Rule = (문서의 ID)%(샤드의 개수)

        ㆍ샤드의 개수가 바뀐다면 문서가 저장되는 규칙이 완전히 바뀌게 된다.

        ㆍ따라서 인덱스를 생성할 때 프라이머리 샤드의 개수를 설정하는 건 매우 중요하다. - 바꿀 수 없기 때문에!

        ㆍnumber_of_shards의 기본값은 1이다.

               - 하지만 이 기본값을 그대로 사용하면 성능에 큰 영향을 미친다.

     

    - 인덱스 템플릿

    curl -X PUT _index_template/base_template
    
    {
        "index_patterns" : ["nginx-logs-*"],
        "template" : {
          "settings" : {
            "number_of_shards" : 3,
            "number_of_replicas" : 2,
          }
        }
    }

        ㆍnginx-logs-로 시작하는 모든 인덱스는 프라이머리 샤드 3개, 레플리캬 샤드 6개로 생성

     

    매핑 이해하기

    - 매핑이란? : 문서의 구조를 나타내는 정보

        ㆍElasticSearch는 스키마리스가 아니라 미리 정의하지 않아도 될 뿐이다.

    종류 정의
    동적 매핑 (Dynamic Mapping) 처음 색인되는 문서를 바탕으로 매핑 정보를 ElasticSearch가 동적으로 생성
    정적 매핑 (Static Mapping) 문서의 매핑 정보를 미리 정의

     

    - 동적 매핑 : 어떤 문서가 색인될지 스키마를 미리 정의하지 않아도 된다.

        ㆍ동적 매핑에 의해 매핑 정보가 생성된 후에는 타입이 안맞을 경우 파싱 에러가 발생한다.

    - 정적 매핑 : 어떤 문서가 색인될지 스키마를 미리 정의한다.

        ㆍ문서의 필드들이 가지는 값에 따라 타입을 지정해 줄 필요가 있을 때

        ㆍ불필요한 색인이 발생하지 않기 위해서 - ex) 문자열 필드마다 자동 생성되는 keyword 타입

     

    색인 과정 이해하기

    - 색인(indexing) 이란 : 문서를 분석하고 저장하는 과정을 색인이라고 한다.

    - 색인 과정

    1. 인덱스가 있는가?

        ㆍNo - 인덱스 생성

    2. 매핑정보가 있는가?

        ㆍNo - 매핑 정보 생성(동적매핑)

    3. 매핑 정보가 올바른가?

        ㆍNo - 에러 (색인 불가)

    4. inverted index 생성

    5. 프라이머리 샤드에 저장

    6. 레플리카 샤드에 복사

     

    - 만약 노드가 3개이고 프라이머리 샤드가 1개이면 색인이 하나의 데이터 노드에서만 일어난다.

        ㆍ데이터노드가 3대지만 색인에 있어서는 사실상 1대 있는거나 마찬가지이다.

        ㆍ클러스터로서의 이점을 전혀 살리지 못하는 상황이다.

        ㆍ그래서 적절한 수의 샤드 개수를 설정하는 것이 성능에 큰 영향을 미친다.

        ㆍ만약 프라이머리 샤드가 3개이면 3대의 데이터 노드 모두 색인에 참여한다.

        ㆍ여기서 1대의 데이터노드를 늘린다면? -> 샤드의 개수가 고르게 분배되지 않기 때문에 용량 불균형이 일어날 수 있다.

    - 적절한 샤드의 개수는?

        ㆍ처음부터 완벽한 샤드 배치 계획을 세울 순 없다.

        ㆍ성능에 문제가 있다면 샤드의 수를 늘리거나 데이터 노드를 스케일 아웃/업 하면서 최적의 수치를 찾아간다.

     

    * 색인 성능에 문제가 있다면 클러스터로서의 이점을 살리고 있는지를 먼저 살펴봐야 한다.

        ㆍ가능한 많은 노드들이 색인에 참여하고 있는지? 색인에 참여한 노드들이 CPU나 리소스들을 충분히 사용하고 있는지?

     

    검색 과정 이해하기

    - 검색과정

        ㆍ1. 검색어 분석                  ( = analyzer 적용 )

        ㆍ2. inverted index 검색   ( = 생성된 토큰을 inverted index에서 검색 )

        ㆍ3. 검색 결과 표시

    - inverted index : 문자열을 분석한 결과를 저장하고 있는 구조체

     

    - 애널라이저 (Analyzer)

        ㆍ문자열. -> character filter(특수 문자 제거)  -> tokenizer(공백을 기준으로 나눔) -> token filter(소문자로 만들거나)

            -> tokens

        ㆍ문자열을 분석해서 inverted index 구성을 위한 토큰을 만들어 내는 과정

     

    - 검색 요청은 프라이머리 샤드와 레플리카 샤드 모두가 처리할 수 있습니다.

        ㆍnumber_of_replicas를 늘려서 레플리카 샤드를 늘려준다면 검색 성능이 좋아진다.

    - 검색 성능에 문제가 있다면 클러스터로서의 이점을 살리고 있는지를 먼저 살펴봐야한다.

     

    정리

    - 애널라이저를 통해서 색인 과정에서 문자열을 분석하고 토큰들이 생성되며 이 토큰들이 inverted index를 구성한다.

    - 애널라이저를 통해 검색어로 부터 생성된 토큰들을 inverted index에서 찾는 과정을 검색이라고 한다.

    - 검색 요청은 프라이머리 샤드와 레플리카 샤드 모두에서 처리될 수 있다.

    - 색인과 검색 모두 적절한 샤드의 수가 성능을 결정하며, 적절한 샤드의 수가 클러스터로서의 이점을 활용하느냐 아니냐를 결정한다.

    -*** ElasticSearch는 클러스터로 구성되기 때문에 모든 노드가 색인과 검색을 처리할 수 있도록 구성하는 것이 가장 중요하다.

     

    text vs keyword

    text keyword
    - 둘 다 문자열을 나타내기 위한 타입이다.
    - 전문 검색 (Full-text search)을 위해 토큰 생성 - Exact Matching(정확히 일치)을 위해 토큰 생성
    i / am / a / boy i am a boy
    주소, 이름, 물품 상세정보 성별, 물품 카테고리

     

    - 그래서 keyword 타입이 색인 속도가 더 빠르다. -> text타입보다 CPU를 덜 사용하기에!

    - 문자열 필드가 동적 매핑되면 text와 keyword 타입 두 개가 모두 생성된다.

        ㆍ문자열의 특성에 따라 text와 keyword를 정적 매핑해주면 성능에 도움이 된다.

     

    정리

    - text와 keyword 타입 모두 문자열을 처리하기 위한 타입이다.

    - 문자열을 동적 매핑하면 text와 keyword 타입이 모두 생성된다.

    - keyword가 text 타입보다 색인이 더 빠르다.

    - 굳이 토크나이징이 필요하지 않은 필드의 경우 keyword로 정적 매핑 설정해 놓으면 색인 성능에 도움이 된다.

     


    ElasticSearch 모니터링

    cat API

    - Compact and Aligned Text (CAT) APIs의 약자이며 클러스터의 정보를 사람이 읽기 편한 형태로 출력하기 위한 용도로 만들어진 API

    - UI 기반의 모니터링 시스템이 원인 파악에 더 편하지만 cat API는 상황을 빠르게 판단하는데 도움이 된다.

     

    cat health

    - ElasticSearch 클러스터의 전반적인 상태를 확인할 수 있다.

    curl -X GET /_cat/health?v
    상태 의미
    green - 프라이머리 샤드, 레플리카 샤드 모두 정상적으로 각 노드에 배치되어 동작하고 있는 상태
    yellow - 프라이머리 샤드는 정상적으로 동작하지만 일부 레플리카 샤드가 정상적으로 배치되지 않은 상태
    - 색인 성능에는 이상 없지만 검색 성능에는 영향을 줄 있다.
    red - 일부 프라이머리 샤드와 레플리카 샤드가 정상적으로 배치되지 않은 상태
    - 색인 성능, 검색 성능에 모두 영향을 주며 문서 유실이 발생할 수 있다.

     

    cat nodes

    - 노드들의 전반적인 상태를 확인할 수 있다.

    curl -X GET /_cat/nodes?v

        ㆍ기본적인 정보로 확인 가능한 정보는 제한적이다.

     

    curl -X GET /_cat/nodes?help
    curl -X GET /_cat/nodes?h=ip,heap.percent,disk.avail,name&v

     

    - 언제 활용하기 좋을까?

        ㆍ노드들의 디스크 사용량 확인

        ㆍ노드들이 명확한 역할을 수행하고 있는지 확인

        ㆍ어떤 노드가 마스터 노드인지 확인

        ㆍ노드들의 메모리 사용량 확인

     

    cat indices

    - 인덱스의 상태를 확인할 수 있다.

    curl -X GET /_cat/indices?v

    - cat health 에서 봤던 상태 정보를 cat indices 에서도 볼 수 있다.

        ㆍ사실 클러스터의 상태는 인덱스의 상태라고 보면 된다.

        ㆍ1개 이상의 인덱스가 yellow 상태면 클러스터도 yellow, 1개 이상의 인덱스가 red 상태면 클러스터도 red

     

    - 언제 활용하면 좋을까?

        ㆍ인덱스들의 프라이머리 샤드 개수와 레플리카 개수 확인

        ㆍ이상 상태인 인덱스 확인

     

    cat shards

    - 샤드의 상태를 확인할 수 있다.

    curl -X GET /_cat/shards?v

     

    - cat shards도 cat nodes와 마찬가지로 더 많은 정보를 볼 수 있다.

    curl -X GET /_cat/shards?h=index,shard,prirep,state,docs,unassigned.reason&v

     

    - 언제 활용하면 좋을까?

        ㆍ이상 상태인 샤드들 확인

        ㆍ샤드들의 이상 상태 원인 확인

     

    정리

    - cat API는 클러스터의 다양한 정보를 사람이 읽기 쉬운 형태로 보여주기 위한 용도의 API 입니다.

    - cat health는 클러스터의 상태에 대한 정보를 보여준다.

    - cat nodes는 클러스터 내의 노드들에 대한 상태 정보를 보여준다.

    - cat indices는 인덱스의 상태에 대한 정보를 보여준다.

    - cat shards는 인덱스의 샤드들에 대한 상태 정보를 보여준다.

     

    주요 모니터링 지표 살펴보기

    - 모니터링의 기본 : 이상 징후를 감지하고 필요한 정보를 바탕으로 전파하는 것!

    시스템 종류 추천하는 모니터링 도구
    Elastic Cloud
    Self-Hosted ElasticSearch
    Kibana의 Stack Monitoring
    AWS OpenSearch Service AWS CloudWatch

     

    - 지표들은 크게 임계치를 걸어서 알람을 받아야하는 지표와 문제 원인을 찾아내기 위해 분석용도로 사용하는 지표로 나뉜다.

     

    주요 모니터링 지표 11가지

    - 알람을 위한 지표

    이름 의미 임계치 설정
    CPU Usage 노드가 CPU를 얼마나 많이 사용하고 있는가
    (얼마나 요청이 들어오고 있는가?)
    50% 이상
    Disk Usage 노드가 얼마나 많은 문서를 저장하고 있는가 70% 이상
    Load 노드가 얼마나 많은 CPU와 디스크 연산을 처리하고 있는가
    (노드가 처리하고 있는 프로세스 갯수)
    CPU 개수에 따라 상이
    (ex. CPU 개수가 2라면 2이상)
    JVM Heap 노드의 JVM이 얼마나 많은 메모리를 사용하는가
    (GC의 역할을 제대로 해주고 있는가)
    85% 이상
    Threads 처리량을 넘어서는 색인/검색 요청이 있는가 Rejected Threads가 1 이상

     

    - 문제원인을 위한 지표

    이름 의미
    Memory Usage 노드에 설치되어 있는 물리적 메모리의 사용량, JVM Heap과 다르다
    ( JVM Heap을 어느정도까지 늘릴 수 있는가 )
    Disk I/O 노드에서 발생하는 디스크 연산의 지연 시간 (작업 시간)
    GC Rate 노드에서 발생하는 GC의 발생 주기
    GC Duration 노드에서 발생하는 GC의 소요 시간
    Latency 노드에서 색인 및 검색에 소요되는 시간
    Rate 노드에서 색인 및 검색 요청이 인입되는 양

     

    정리

    - 모니터링 시스템 구축도 중요하지만 수집하는 지표들의 의미를 알고 중점적으로 봐야할 지표들을 이해하는 것도 중요하다.

    - CPU Usage, Load, JVM Heap, Threads 지표 등은 임계치를 지정해 놓고 임계치 이상의 값이 발생하면 알람을 받도록 하는 것이 좋다.


    ElasticSearch 트러블 슈팅

    트러블 슈팅의 기본

    - 트러블 슈팅이란? : 문제 상황을 파악하고 원인을 분석 후 해결하는 과정

     

    - 문제상황파악 - 무엇이 문제인가?

        ㆍ모니터링 알람 확인 -> 클러스터 상태 확인 -> 노드에서의 에러 로그 확인 -> 클라이언트에서의 에러 로그 확인

    - 원인분석 - 왜 문제가 발생했는가?

        ㆍ주요 지표 살펴보기 -> 에러 로그 분석

    - 문제해결 - 어떻게 해결할 수 있는가?

        ㆍ원인 분석을 통해 확인한 원인을 제거하는 과정을 진행한다.

     

     

    트러블 슈팅 사례 #1

    - 문제 상황 : 클러스터의 상태가 Green이 아니다.

        ㆍYellow 혹은 Red 상태에 따른 영향도를 정확하게 파악하는 것이 먼저이다!

    - 원인 분석 : 인덱스들 중 누가 Yellow 혹은 Red 인가를 먼저 파악

        ㆍYellow 혹은 Red 인 인덱스들 중 어떤 샤드들에 문제가 생겼는지를 파악한다.

    - 문제 해결

     

    * 클러스터의 상태가 Yellow 혹은 Red이지만 경우에 따라서는 장애 상황이 아닐 수 있기 때문에 정확한 파악이 중요하다.

     

    트러블 슈팅 사례 #2

    - 문제 상황 : 클러스터에 갑자기 문서가 색인 되지 않는다. 클라이언트에서 403 Forbidden Error 발생

    - 원인 분석 : 노드의 디스크 사용량이 100%가 되면 노드의 운영 체제도 정상적으로 동작하지 않기 때문에

                        ElasticSearch에는 디스크 사용량이 일정 수준 이상 되면 더이상 색인하지 않도록하는 보호 장치가 있다.

    이름 의미
    cluster.routing.allocation.disk.threshold_enabled 보호장치를 사용할 것인지 아닌지를 설정한다.
    cluster.routing.allocation.disk.watermark.low 기본값은 85%이고, 이 값보다 높아지면 더이상 샤드를 배치하지 않습니다.
    cluster.routing.allocation.disk.watermark.high 기본값은 90%이고, 이 값보다 높아지면 샤드들을 다른 데이터 노드로 옮기기 시작한다.
    cluster.routing.allocation.disk.watermark.flood_stage 기본값은 95%이고, 이 값보다 높아지면 더이상 색인을 하지 않는다.
    검색만 가능하다!

     

    - 문제 해결 : 데이터노드를 증설하거나 불필요한 인덱스를 삭제해서 디스크 공간을 확보한다.

        ㆍ디스크 공간 확보 후 Read-Only 상태의 인덱스들을 명시적으로 풀어줘야 한다.

    curl -X PUT /*/settings
    {
        "index.blocks.read_only_allow_delete": null
    }

     

    트러블 슈팅 사례 #3

    - 문제 상황 : 간헐적으로 색인 과정에서 일부 문서가 누락된다. 노드에서 간헐적으로 Rejected 에러가 발생한다.

    - 원인 분석 : ElasticSearch 에는 새인/검색 요청을 처리하는 스레드가 존재한다.

                        그리고 스레드가 모두 요청을 처리하고 있을 때를 대비해서 큐도 존재한다.

        ㆍ하지만 모든 큐가 꽉 차 있다면? -> Rejected Error

    - 문제 해결 : 데이터 노드 증설 / 큐 증설

        ㆍ큐 증설은 제한적인 상황에서 효과를 발휘할 수 있다. -> 평상 시 처리량은 충분하지만 간헐적으로 많은 양의 요청이 인입되는 경우

    thread_pool.bulk.queue_size: 1000

     

    정리

    - ElasticSearch 에는 색인/검색 요청을 처리하기 위한 스레드가 존재하고 각 스레드 별로 큐가 존재한다.

    - 큐가 가득 찰 정도로 많은 양의 요청이 인입되면 Rejected 에러가 발생한다.

    - Rejected 스레드가 발생하고 있는지를 모니터링해서 감지할 수 있다.

    - 클러스터의 처리량이 부족한 것이 근본 원인이기 때문에 데이터 노드 증설이 가장 좋은 방법이지만 간헐적으로 많은 양의 요청이 인입되는 경우라면 큐 증설을 통해서도 대응할 수 있다.

     

    트러블 슈팅 사례 #4

    - 문제 상황 : 샤드 배치가 되지 않는다.

    - 원인 분석 : 노드들이 가지고 있을 수 있는 전체 샤드의 개수에는 제한이 존재한다.

                        그리고 이 제한을 넘어가면 더 이상 샤드가 생성되지 않고 인덱스 생성도 불가능해진다.

    cluster.max_shards_per_node (Defaults: 1000)

     

    - 문제 해결 : 데이터 노드 증설 / 인덱스 설정 변경 / cluster.max_shards_per_node 변경

        ㆍcluster.max_shards_per_node 변경은 노드들에 너무 많은 샤드가 배치됨으로서 발생할 수 있는 사이드 이펙트 때문에 권고 X

     

    트러블 슈팅 사례 #5

    - 문제 상황 : CMS GC 환경에서 너무 잦은 Old GC가 발생한다.

    - 원인 분석 : 불필요하게 많은 객체들이 Old 메모리 영역으로 이동하기 때문에 잦은 Old GC가 발생

    - 문제 해결 : Survivor 영역을 늘려준다.

        ㆍNewRatio와 SurvivorRatio 튜닝

     

    정리

    - CMS GC를 사용할 경우 Old GC에 의해 성능에 영향을 받을 수 있다.

    - Survivor 영역이 작아서 Eden 영역의 객체들이 이동하지 못하고 Old 영역으로 바로 이동할 수 있고 이로 인해 불필요하게 Old 영역에 객체들이 많이 생성될 수 있다.

    - NewRatio와 SurvivorRatio 튜닝을 통해 Eden과 Survivor 영역을 늘려주고 이를 통해 문제를 해결할 수 있다.

     


    후기

    대부분은 이해가 되었지만 따로 실습을 해봐야 더 많은 것을 접할 수 있을 것같다.

    그리고 트러블 슈팅 사례#5 과 같은 경우는 이해하기 어려운 부분이었다. 좀 더 공부를 하고 다시 봐야할 듯하다.

    댓글

Designed by Tistory.