아빠는 개발자

[es] Warm up global ordinals 본문

Elastic/elasticsearch

[es] Warm up global ordinals

father6019 2023. 9. 23. 13:18
728x90
반응형

전역 서수는 집계 성능을 최적화하는 데 사용되는 데이터 구조입니다. 이는 느리게 계산되어 필드 데이터 캐시의 일부로 JVM 힙에 저장됩니다. 버킷팅 집계에 많이 사용되는 필드의 경우 요청을 수신하기 전에 Elasticsearch에 전역 서수를 구성하고 캐시하도록 지시할 수 있습니다. 힙 사용량이 증가하고 새로 고침 시간이 더 오래 걸릴 수 있으므로 이 작업은 신중하게 수행해야 합니다. 이 옵션은 Eager 전역 서수 매핑 매개변수를 설정하여 기존 매핑에서 동적으로 업데이트될 수 있습니다.

 

맵핑 옵션 

PUT index
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "keyword",
        "eager_global_ordinals": true
      }
    }
  }
}

테스트 해보자

데이터셋의 구조는 아래와 같다. 

다른 정보에 비해 비교적 카디널리티가 낮은 국가코드로 보이는 3번째 항목만 색인 할 예정

 

더보기

전체 코드

# -*- coding: utf-8 -*-
import time

import matplotlib.pyplot as plt
from elasticsearch import Elasticsearch
import numpy as np


##### SEARCHING #####

def run_query_loop():
    time_a = []
    time_b = []

    for i in range(SIZE):
        time_a.append(query_a())
        time_b.append(query_b())

    print("AGGS 평균 : " + str(round(np.mean(time_a), 2)))
    print("AGGS ORDINALS 평균 : " + str(round(np.mean(time_b), 2)))

    t = range(0, SIZE)
    plt.rcParams['font.family'] = 'AppleGothic'

    fig, ax = plt.subplots()
    ax.set_title('AGGS vs AGGS ORDINALS')
    line1, = ax.plot(t, time_a, lw=2, label='AGGS')
    line2, = ax.plot(t, time_b, lw=2, label='AGGS ORDINALS')
    leg = ax.legend(fancybox=True, shadow=True)

    ax.set_ylabel('score')
    ax.set_xlabel('top' + str(SIZE))

    lines = [line1, line2]
    lined = {}
    for legline, origline in zip(leg.get_lines(), lines):
        legline.set_picker(True)  # Enable picking on the legend line.
        lined[legline] = origline

    def on_pick(event):
        legline = event.artist
        origline = lined[legline]
        visible = not origline.get_visible()
        origline.set_visible(visible)
        legline.set_alpha(1.0 if visible else 0.2)
        fig.canvas.draw()

    fig.canvas.mpl_connect('pick_event', on_pick)
    plt.show()


def query_a():
    with open(AGGS_A) as index_file:
        script_query = index_file.read().strip()
    search_start = time.time()
    client.search(
        index=INDEX_NAME_A,
        body=script_query
    )

    search_time = time.time() - search_start
    return search_time * 1000


def query_b():
    with open(AGGS_B) as index_file:
        script_query = index_file.read().strip()
    search_start = time.time()
    client.search(
        index=INDEX_NAME_A,
        body=script_query
    )

    search_time = time.time() - search_start
    return search_time * 1000


##### MAIN SCRIPT #####

if __name__ == '__main__':
    INDEX_NAME_A = "aggs-ordinals-index"
    AGGS_A = "./query/aggs_query.json"
    AGGS_B = "./query/aggs_ordinals_query.json"
    SIZE = 50
    client = Elasticsearch(http_auth=('elastic', 'dlengus'))
    run_query_loop()
    print("Done.")

실행해보니 문제가 많다 우선 타임스템프 파이프 라인 부터  처리해보잣

 

 

 

타임스템프 파이프라인 생성 

PUT /_ingest/pipeline/timestamp
{
  "description": "Creates a timestamp when a document is initially indexed",
  "processors": [
    {
      "set": {
        "field": "_source.timestamp",
        "value": "{{_ingest.timestamp}}"
      }
    }
  ]
}

다시 실행하니 잘 되네 

음.. 데이터가 몇건이였더라..

800만건이였나. 일단 색인될때까지 대기

 

가만보면 인덱스 2개를 만들지 않고 필드 2개로 옵션만 다르게 처리할껄 그랬나보다

변경 - 인덱스 하나에서 두가지 타입의 필드로 색인 후  aggs 해볼 예정 

 

AGGS 쿼리

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "COUNTRY": {
      "terms": {
        "field": "country_code"
      }
    }
  }
}

AGGS ORDINALS 쿼리

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "COUNTRY_ORDINALS": {
      "terms": {
        "field": "country_code_ordinals"
      }
    }
  }
}

50회 실행

AGGS 평균 : 106.34
AGGS ORDINALS 평균 : 106.09
AGGS 평균 : 106.27
AGGS ORDINALS 평균 : 106.91
AGGS 평균 : 106.38
AGGS ORDINALS 평균 : 106.27



size 0 으로 실행하며 캐싱이 된다고 하니  0으로 실행

AGGS 평균 : 3.3
AGGS ORDINALS 평균 : 3.21
AGGS 평균 : 3.09
AGGS ORDINALS 평균 : 2.94
AGGS 평균 : 3.02
AGGS ORDINALS 평균 : 2.94

확실히 캐싱 빨이 있다. 

근데 AGGS 랑 AGGS ORDINALS 가 다른 필드를 집계한건데 캐싱이 같이 먹히는 것 같은데 .. 

 

AGGS 평균 : 3.42
AGGS ORDINALS 평균 : 3.32
AGGS 평균 : 3.46
AGGS ORDINALS 평균 : 3.31
AGGS 평균 : 3.33
AGGS ORDINALS 평균 : 3.22

AGGS 이름을 키로 케싱이 되는것을 확인 

 

이 옵션은.. 

"eager_global_ordinals": true

뭐지..

728x90
반응형