ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Elasticsearch ILM 탐색기
    Elasticsearch 2024. 6. 29. 17:01

    그동안 자사 서비스의 최신/과거 데이터 관리를 크론탭을 활용하여 자바 프로세스를 통해 관리를 했다면

    이번엔 Elasticsearch의 기능 중 하나인 ILM을 통해 자체적으로 자동화를 할 수 있는지 알아보겠습니다..!

     

    ILM을 통해 관리한다는 것은,,! 자동으로 Phase를 옮긴다는 것과 같은 말이라고 생각합니다.

    하지만 애석하게도 서비스의 노드마다 elasticsearch.yml 설정인 node.roles를 상세하게 설정해놓지 않았습니다.(master냐? data냐?) node.attr.tier을 통해 구분할 뿐 node의 역할을 명시해 놓지 않았습니다.

    대신. yml 파일에 node.attr을 통해 설정하므로써 노드에 속성을 부여해주며 구분을 지었습니다. 

    (Node attribute에 대해 공식문서 링크해드리려 했는데 없습니다,, ㅎ ㅠㅠ 찾으면 알려주세요)

     

    즉 ! "node.attr으로 구분한 클러스터에 ILM 적용하기"가 이 글의 주제가 되겠습니다. 


    목표
    1. ILM을 활용하여 daily(hot) -> montly(warm)으로 phases 이동
    2. 과거 데이터는 삭제하지 않음
    3. warm phase로 이동시 primary shard 수 감소 -> 과거 데이터 수정을 위해 삭제하지 않음

     

    환경설정

    - 서버 : 3대

    - 데이터 노드에 적용되어 있는 설정 - elasticsearch.yml 

        node.roles : [data] 
        node.attr.tier : <hot, warm, …>

        node.attr.partition : <number>

    Kibana - 페이즈 변경 속도 확인 및 변경 
    GET /_cluster/settings
    PUT /_cluster/settings

     ** 페이즈 변경 및 인덱스 refresh의 간격이 좁을수록 cpu 부하 **


    1. ILM 작성

    PUT _ilm/policy/test_policy
    {
      "policy": {
        "phases": {
          "hot": {   # ---------- 1
            "min_age": "0d", # ----- 1-1
            "actions": {
              "set_priority": { # ---- 1-2
                "priority": 100
              },
              "rollover": { # ------ 1-3
                "max_age": "30d",
                "max_docs": 1000,
                "max_size": "5gb"
              }
            }
          },
          "warm": { # ----------- 2
            "min_age": "0d",
            "actions": {
              "set_priority": { # ------- 2-1
                "priority": 50
              },
              "allocate": { # ------ 2-2
                "require": {
                  "tier" : "warm"
                }
              }, 
              "shrink": {
                "number_of_shards": 1
              },
              "forcemerge": {
                "max_num_segments": 1
              }
            }
          }
        }
      }
    }

    1. "hot" phase

    1-1 : min_age를 0으로 설정함으로써 대기시간 없이 바로바로 hot phase로 유입된다.

    1-2 : set_priority를 설정함으로써 phase의 우선순위를 정해준다.

    1-3 : rollover 설정 > 아래의 조건 중 하나라도 만족 시 새로운 인덱스로 rollover

     

    2. "warm" phase

    2-1 : 1-2와 같음

    2-2 : allocate 설정( 접근 위치를 설정할 수 있음) -> replica shard는 1개로 설정하고, "require" 설정을 통해 사용자가 지정한 노드에 접근

     

    kibana를 통해 접근된 노드를 확인


    2. Index_template 작성 및 ILM 적용

    PUT _index_template/<Index Template 이름>
    {
      "index_patterns": ["hit-test-*"],
      "template": {
        "settings": {
          "number_of_replicas": 1,
          "number_of_shards": 3,
          "index.lifecycle.name" :<ILM_POLICY_이름>,
          "index.lifecycle.rollover_alias" : <rollover_별칭>
        }
      }
    }
    •  "index.lifecycle.name" : <앞서 만들었던 ILM Policy>
    • "index.lifecycle.rollover_alias" : <별칭 설정>

    3. Rollover 별칭을 사용하여 초기 인덱스에 적용

    PUT hit-test-1
    {
      "aliases": {
        <rollover_별칭>: {
          "is_write_index": true
        }
      }

     


    TEST

     

    - "max_docs"의 한계인 10개 이상 doc 넣어보기

    put <rollover_alias>/_doc/15
    {
      "test" : "hi"
    }
    • 초기 인덱스인 "hit-test-1"이 "warm" phase로 넘어가는 것 확인
    • 변경이 안된다면? -> 페이즈 변경 속도 확인 / refresh_interval 확인

    - 강제 rollover을 시켜주어 phase 넘어가는 것 확인

    • PUT /rollover_alias/_rollover 를 날리면 강제 rollover 가능
    • Rollover 조건을 강제로 변환
    POST ilm_test/_rollover
    {
      "conditions": {
        "max_docs": 1
    } }
    POST ilm_test/_rollover
    {
      "conditions": {
        "max_age": "1s"
    } }

    * 오류 시 "is_write_index" : true 설정과 "indices.lifecycle.poll_interval" 설정 확인

     


    결과

     

    1. ILM을 활용하여 daily(Hot) -> montly(Warm)으로 phase 이동 Rollover

    ※ 
    ILM은 기본적으로 인덱스 생성 시간과 min_age 설정 기준으로 동작하기 때문에 날짜가 변경되어도 Rollover되지 않을 수 있음
    -> 현재 날짜에 맞추어 다루려면 Logstash와 연동 모색
    관련 링크 : 
    https://discuss.elastic.co/t/index-not-rollover-when-the-date- changes/272385

     

    2. warm phase로 이동 시 primary shard 수 축소 (삭제는 하지 않음)

    ※ 
    warm phase에서 shrink를 통해 Primary shard 수를 축소 가능하나 ILM에서의 Warm phase는 더 이상 update가 필요하지 않은 데이터이다.
    > primary shard 를 줄인다면 update가 불가하다. 이를 가능하게 하려면 수동으로 처리가 필요하다
    (ex - reindex, ...)

     

    3. Phase 변경 중 유입된 데이터는 어떻게 관리되는지? 

    ※ Phase 변경 속도를 늦추어 Test
    변경 되기 전 인덱스로 데이터가 유입 (조건에 맞지 않는 인덱스가 발생)
    > ex) max_docs는 10까지가 한계임에도 조건 개수를 초과하는 인덱스가 발생한다.

     

    4. 인덱스 이름 제한

    인덱스 이름은 ^.*-\d+$ 패턴에 일치해야 한다. (ex ilm-test-000001)

    https://www.elastic.co/guide/en/elasticsearch/reference/7.16/indices-rollover- index.html#_using_date_math_with_the_rollover_api


    결론

     

    ILM을 통해 이루고자 하는 목표인 자동 인덱스 관리를 하려면 부가적이 프로세스가 필요하다고 생각합니다.

    • Date 관리 (29,39,31) -> alias : 최대 index 수명 단위가 day이며 month 단위 부터는 없다.
    • 조건 초과 index 관리 -> 강제 rollover 프로세스 개발 (인덱스를 검사하는 최소 interval 단위 1초)

    대체 가능 프로세스 고안

    ※ 글쓴이의 개인적인 생각이므로 완벽하지 않습니다 ※

     

    JAVA + ILM 혼용

    • ILM : 29일, 30일, 31일에 맞춘 ILM 정책 - alias로 구분하기 때문에 정책이 다르지 않다면 한개도 가능
    • _index_template : 1~12월의 template 총 12개 → index_pattern = [service_main_2024<01~12>-*<day>]
    • 해당 월에 맞추어 ILM 적용 → Rollover_alias는 12개 (alias 하나에 인덱스 하나만 적용 가능)

    순서 

    1. Logstash
      1. Date에 맞추어 Elasticsearch로 데이터 전달
    2. Elasticsearch(_index_template)
      1. day
        1. crontab을 활용하여 강제 rollover
        2. 생성 예시 → service_main_202401-<000001, ... ~>
      2. month
        1. logstash 활용하여 date에 맞게 인덱스명 변경
    3. Java Process
      1. 년도가 바뀔때마다 template 변경 필요

    기대효과 

    • 월별 인덱스 검색을 위한 alias 설정 안해도 된다. → rollover_alias 명으로 검색 가능
    • logstash 활용으로 Date 관리
    • ILM 장점 활용 가능 (후처리 process 등)

    필요사항

    • template 수정 필요 → 매년 만들어주어야 함
    • 인덱스 rollover 조건이 하루가 지나기 전 rollover이 되지 않도록 충분해야 한다.
      • 후처리 목표 (shard, index location) 위주 조건
    • Logstash에서 ILM에 강제 Rollover을 걸 수 있는지 봐야한다.
    • 기존 서비스가 활용하는 인덱스 명을 ILM 규칙에 맞게 변경

     

Designed by Tistory.