elasticsearch routing 사용하기
데이터베이스/Elasticsearch

elasticsearch routing 사용하기

반응형

[기본구조]

elasticserch에서 데이터는 index에 저장되고 index는 shard로 구성되어 있다. 기본적으로 데이터가 shard에 들어가는 기준은 document에 _id를 기준으로 들어가게 된다. 그렇기 때문에 index에 데이터를 조회할 때 어떤 샤드에 값이 저장되어 있는지 알수 없기 때문에 모든 shard에 값을 질의하고 그 값을 조합해서 값을 내려준다.

 

한번 일반적인 index를 만들고 조회해보자. 아래처럼 Index를 생성하고 "name"에 wedul을 넣고 조회해보겠다.

PUT localhost:19200/before-route
{
  "settings": {
    "number_of_shards": 4,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "name": { "type": "text" }
    }
  }
}

그럼 아래에 보는것처럼 4개의 shard 모두 조회에 사용된 것을 확인할 수 있다.

 

 

[routing]

그럼 routing을 추가해서 값을 조회해보자. 우선 routing을 index에 무조건 넣어서 데이터를 indexing하도록 만들어보자. 기존 before-route index를 놔두고 새로운 after-route index를 생성해보자.  mappings에 _routing필드를 추가하고 required 속성을 true로 지정하면 무조건 indexing할때 routing 정보가 있어야 라우팅 된다.

PUT localhost:19200/after-route
{
    "settings": {
        "number_of_shards": 4,
        "number_of_replicas": 0
    },
    "mappings": {
        "_routing": {
            "required": true
        },
        "properties": {
            "name": {
                "type": "text"
            }
        }
    }
}

이를 강제해서 무조건 필요한 데이터 조회 시 특정한 샤드를 조회할 수 있도록 해야한다. 물론 아무때나 routing field를 추가할 수 있는건 아니다. 전체 문서 기준으로 조회가 매번 필요하고 별도 샤드를 나눌 기준이 없는경우에는 routing을 기준으로 삼을만한게 없다. 이럴때는 routing을 넣을 때 신중하게 기준을 삼는게 좋고 그게 어렵다면 routing filed를 사용하지 않는것도 방법이다. routing field에 적합한 예로는 특정 가게에 있는 상품들을 조회한다고 가정하였을 때, 단순 쿼리로 shopNo를 필터한다면 모든 샤드를 다조회해야하고 그 양이 일반적인 커머스라면 수억건이 될거라서 부담을 많이 줄 수 있기에 가게번호 기준으로 routing을 해놓으면 특정 샤드만 조회하기에 이점을 가져갈 수 있다.

 

단 주의해야할 점이 routing은 특정 shard를 매칭하기 위함이기에 shopNo에 대한 필터 쿼리는 유지해야한다. routing에 가게번호를 넣어서 조회한다고해서 해당가게 데이터만 나오는게 아니다. 단순히 routing은 shard에 대한 routing이기에 해당 shard에 있는 다른 데이터들도 함께 조회되기 때문에 filter 쿼리를 빼먹으면 안된다.

 

그럼 값을 넣어보자. 

routing을 사용해서 값을 넣을 때는 request param으로 routing 필드를 넣어줘야한다. 그럼 이렇게 들어간 데이터의 routing 필드 데이터를 _search api로 확인해보면 아까 넣은값이 들어있는걸 확인할 수 있다.

_search 조회 시 _routing field값 보임

단, _routing field를 강제한 상황에서 doc을 조회할 시 기존처럼 id로 조회할 때 무조건 routing을 함께 적어야한다. 그렇지 않으면 routing_missing_exception이 발생한다.

_routing정보를 빼고 조회한경우

GET localhost:19200/after-route/_doc/1?routing=1000

이렇게 routing을 넣어줘야 값이 제대로 나온다.

그럼 다음으로 실제로 routing을 넣어서 조회하면 하나의 shard에서만 조회가 발생하는지 확인해보면 아래 같은 쿼리에서 routing만 붙여서 조회해도 shard가 1개에서 조회가 이뤄진거를 확인할 수 있다.

 

이처럼 routing을 사용하면 성능상 이점을 가져올 수 있고 리소스 사용량도 확 줄일 수 있다. 하지만 잘못된 routing을 넣으면 값이 없기 때문에 내가 넣은 데이터의 routing정보를 잘 확인하고 조회에 사용해야 서비스 버그를 예방할 수 있다. 실제 60000 routing field에 저장된 값을 1로 임의로 바꿔서 조회하면 아래처럼 값이 나오지 않는걸 알 수 있다.

 

추가적으로 routing을 사용했다고 해서 전체 document를 대상으로 조회가 되지 않는건 아니다. 만약 routing을 제외하고 전체 document를 대상으로 조회하고 싶은경우에는 _search api에서 routing parameter만 빼고 조회하면 된다. (단, 위에서 봤듯이 특정 document에 경우에는 조회하고자 할경우에 무조건 routing정보를 기입해줘야한다.)

 

반응형