API/ElasticSearch

[ElasticSearch]. 다중 검색 종류 비교 : 비동기 검색(async_search) VS 멀티 서치(msearch)

Acdong 2022. 8. 23. 17:13
728x90

ElasticSearch 서비스를 개발하는 과정에 있어서

여러 개의 쿼리를 필연적으로 한번에 날려야하는 순간이 있다.

 

우리 서비스도 동시에 3개의 쿼리를 날려서 결과를 취합하는 과정이 있는데.

 

처음(비동기 프로그래밍을 모를때)에는 그냥 3개의 쿼리를 순차적으로 날려서 결과값을 받았고

이 과정에서 많은 시간적 비용이 소모되었다. 

 

이번 포스팅에서는 쿼리 여러개를 효과적으로 처리하는 방법 2가지를 소개하고 성능을 비교해보고자한다.


Async Search : 비동기 검색

비동기 검색은 엘라스틱서치 쿼리를 비동기로 처리하는 방법이다.

쿼리 3개의 요청을 동시(Concurrency)에 날리고 응답이 빠른 것 부터 받아서 처리하는 방법.

3개의 쿼리중 가장 느린 검색속도가 최종 검색속도라고 볼 수 있다.

 

from elasticsearch import AsyncElasticsearch
import time
import asyncio

es_client = AsyncElasticsearch(**ES_CLIENT)

query1 = {
    "size": 100,
    "query": {
        "match": {"items1": "삼성전자"}}
}
query2 = {
    "size": 100,
    "query": {
        "match": {"items2": "LG세탁기"}}
}
query3 = {
    "size": 100,
    "query": {
        "match": {"items3": "KT휴대폰"}}
}

async def es_search(query):
    result = await es_client.search(index="index", body=query)
    return result


async def main():

    result = await asyncio.gather(
        es_search(query1),
        es_search(query2),
        es_search(query3),
    )

    print(result)


if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(end - start)

Await 키워드를 사용해서 함수를 실행하려면 반드시 비동기로 함수로 작성된 함수여야만 한다.

그 과정에서 Elasticsearch 클라이언트가 아닌 AsyncElasticsearch 클라이언트를 사용해야만 비동기 검색을 할 수 있다.

 


msearch : 멀티 서치

멀티서치는 엘라스틱서치 서비스에 존재하는 다중 검색 기능이다.

여러개의 검색 쿼리를 묶어서 한번에(at the same time)요청하면 그 값을 리스트로 구분하여 리턴해준다.

 

from elasticsearch import Elasticsearch
import time

body = [{"index": "index"},
        {
    "size": 100,
            "query": {
                "match": {"items1": "삼성전자"}}
},
    {"index": "index"},
    {
    "size": 100,
            "query": {
                "match": {"items2": "LG세탁기"}}
},
    {"index": "index"},
    {
    "size": 100,
            "query": {
                "match": {"items3": "KT휴대폰"}}
}]

def es_msearch(body):
    result = es_client.msearch(index="index", body=body)
    print(result)


def main():
    es_msearch(body=body)


if __name__ == "__main__":
    start = time.time()
    print(main())
    end = time.time()
    print(end - start)

 


속도 비교

search size 100 1000 10000
Base search API time(s) 0.399 1.795 6.344
Async search API time(s) 0.272 0.974 4.560
Multi search API  time(s) 0.345 0.937 4.910

 

검색량이 증가할수록 방법에 따라 속도가 개선되는 것을 알 수 있었다.

Msearch 와 AsyncSearch 의 성능은 미세한 차이로 AsyncSearch 가 좋았다.

 

엘라스틱서치를 사용할때 여러개의 쿼리를 한번에 날려야할 경우가 있다면 위 자료가 도움이 되길바란다.

반응형