Elasticsearch auto rollover 적용

brody·2021년 2월 22일
0

elasticsearch에서 자동으로 index를 rollover하는 방식에 대해 알아보자.

주의할점은, rollover는 alias기준으로 수행되는것이지, index기준으로 수행되는것이 아니다.

index는 rollover시마다 이름이 바뀌기 때문에, rollover시에도 항상 유지할 alias에 대해 rollover rule을 규정하는것이다.

rolling policy 만들기

kibana의 > Stack Management > Index Management에서 policy를 생성한다.

아래와같이 이름은 rolling, 1GB / 2개문서 / 1days 로 생성했을시, 3개 중 하나라도 먼저 도달하는 것이 있으면 index가 rolling된다.

(키바나 ui가 없으면 아래 api를 날려도 됨)

PUT _ilm/policy/rolling
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_age": "1d",
            "max_primary_shard_size": "1gb",
            "max_docs": 2
          },
          "set_priority": {
            "priority": 100
          }
        },
        "min_age": "0ms"
      }
    }
  }
}

index template생성

아래와같이 template을 설정하였다.

PUT _template/rolling
{
  "order": 1,
  "version": 1,
  "index_patterns": [
    "rolling*"
  ],
  "settings": {
    "index": {
      "lifecycle": {
        "name": "rolling",
        "rollover_alias": "rolling-write-index"
      },
      "number_of_shards" : "1",
      "number_of_replicas" : "0"
    }
  }
}

rolling이라는 이름으로 시작하는 모든 index에, rolling 라이프사이클을 적용하였고,

rollover대상의 alias는 rolling-write-index라는 alias이다.

index와 alias 생성

PUT rolling-test-000001
{
  "aliases": {
    "rolling-write-index": { "is_write_index": true } 
  }
}

alias를 처음에는 template에 넣어뒀다가, 아래와같은 error와 함께 rolling이 제대로 안되서 index시점에 따로 alias를 생성해주었다.

        "type" : "illegal_argument_exception",
        "reason" : "Rollover alias [rolling-write-index] can point to multiple indices, found duplicated alias [[rolling-write-index]] in index template [rolling]",

마지막에 더 얘기하겠지만 alias는 template에 넣어서는 안되고 따로 지정해야한다.
template에 넣었을시에는 "is_write_index": true 가 먹지 않는다.

해당 index에 3개의 doc을 생성함

POST rolling-write-index/_doc
{"id":1}
POST rolling-write-index/_doc
{"id":2}
POST rolling-write-index/_doc
{"id":3}

ilm상태 확인

GET rolling-write-index/_ilm/explain
{
  "indices" : {
    "rolling-test-000001" : {
      "index" : "rolling-test-000001",
      "managed" : true,
      "policy" : "rolloing",
      "lifecycle_date_millis" : 1613977180668,
      "age" : "16.72s",
      "phase" : "hot",
      "phase_time_millis" : 1613977180704,
      "action" : "unfollow",
      "action_time_millis" : 1613977180755,
      "step" : "wait-for-follow-shard-tasks",
      "step_time_millis" : 1613977180766,
      "phase_execution" : {
        "policy" : "rolloing",
        "phase_definition" : {
          "min_age" : "0ms",
          "actions" : {
            "rollover" : {
              "max_size" : "1gb",
              "max_age" : "1d",
              "max_docs" : 2
            },
            "set_priority" : {
              "priority" : 100
            }
          }
        },
        "version" : 1,
        "modified_date_in_millis" : 1613976026352
      }
    }
  }
}

당장 수행되지않고 status가 "wait-for-follow-shard-tasks" 이다. ( status가 "check-rollover-ready"의 경우 아직 rollover 기준에 도달하지 못했다는 것이다.)

아래와 같이, 기본 ILM poll 주기가 10분이라고한다.

By default the poll interval for ILM is 10 minutes, if you want to test your policy (with a 1 minute rollover), you can lower that by changing the dynamic indices.lifecycle.poll_interval setting.

아래처럼 10초로 바꿀수있다.

PUT /_cluster/settings
{
  "transient" : {
    "indices.lifecycle.poll_interval" : "10s"
  }
}

10분후 확인해보면 000002로 rolling되었음을 확인할수있다.

GET rolling-write-index/_ilm/explain
{
  "indices" : {
    "rolling-test-000002" : {
      "index" : "rolling-test-000002",
      "managed" : true,
      "policy" : "rolloing",
      "lifecycle_date_millis" : 1613983439108,
      "age" : "1.75m",
      "phase" : "hot",
      "phase_time_millis" : 1613983439190,
      "action" : "unfollow",
      "action_time_millis" : 1613983439236,
      "step" : "wait-for-follow-shard-tasks",
      "step_time_millis" : 1613983439265,
      "phase_execution" : {
        "policy" : "rolloing",
        "phase_definition" : {
          "min_age" : "0ms",
          "actions" : {
            "rollover" : {
              "max_size" : "1gb",
              "max_age" : "1d",
              "max_docs" : 2
            },
            "set_priority" : {
              "priority" : 100
            }
          }
        },
        "version" : 1,
        "modified_date_in_millis" : 1613976026352
      }
    }
  }
}

index가 rolling, 굴러가는 모양이다.

롤링하는 순간
rolling-test-000001

"rolling-write-index": {
      "is_write_index": false
    }

가 되고

rolling-test-000002

"rolling-write-index": {
      "is_write_index": true
    }

가 된다.

즉 rolling-write-index로 검색하면 두 index모두에서 검색가능하지만, indexing하면 000002에만 인덱싱된다. 000001 인덱스의 크기는 더이상 늘지 않는 것이다.

주의할점은, template에 rollover대상인 alias를 넣어선 안된다는 것.

처음에는 template에 index생성시 alias를 생성하도록 아래와 같이 넣어뒀었다.

PUT _template/rolling
{
  "order": 1,
  "version": 1,
  "index_patterns": [
    "rolling*"
  ],
#  "aliases": {
#    "rolling-write-index": {
#      "is_write_index": true
#    }
#  },
  "settings": {
    "index": {
      "lifecycle": {
        "name": "rolloing",
        "rollover_alias": "rolling-write-index"
      },
      "number_of_shards" : "1",
      "number_of_replicas" : "0"
    }
  }
}

그런데, 이런 경우 rollover시 아래와 같은 에러가 나며 rolling이 제대로 수행되지 않는다.

     "step_info" : {
        "type" : "illegal_argument_exception",
        "reason" : "Rollover alias [rolling-write-index] can point to multiple indices, found duplicated alias [[rolling-write-index]] in index template [rolling]",

policy에 적용되어있는 rolling alias template에 넣지 않고 생성시 한번 따로 생성해야한다.

추가: 수동 rollover시

매핑이 계속 수정되면서 rollover로 신규 템플릿을 적용해왔다.

PUT rolling-write-index/_rollover

근데 이런 경우 실제 이미 수동 rollover된 index가 ILM에 의해서 또 rollover시도하면서 아래와 같은 error가 난다.

index [rolling-test-000002] is not the write index for alias [rolling-write-index]

index를 수동으로 rollover하는 경우 아래와같이 수동으로 complete처리를 해줘야한다.

PUT rolling-test-000002/_settings
{ index.lifecycle.indexing_complete : true }

수동 complete처리 후 해당 index에 ilm이 제대로 동작하는지 아래와같이 재시도하여 확인할수있다.

POST rolling-test-000002/_ilm/retry

정상의 경우 ack : true로 리턴된다.

profile
일하며 하는 기록

1개의 댓글

comment-user-thumbnail
2024년 1월 1일

좋은 글 감사합니다!

궁금한 점이 rolling-test-000002가 생성되는 시점은 언제일까요? 그리고 rolling-test-000002 생성할 때도 인덱스를 지정하지만 is_write_index는 일단 false가 되는 걸까요? 만약 그러면 alias로 조회하면 2개의 인덱스가 조회가 되는데 어떻게 is_write_index: true인 경우만 조회하는지도 궁금합니다

답글 달기