[Grafana Tempo] 쿼리 최적화
Tempo는 전통적인 데이터베이스들과 다르게 인덱스나 뭐 그런 개념은 없다.
그래서 쿼리 최적화에 접근하는 방식도 좀 다르다.
캐싱
Tempo는 일반적으로 메모리를 조금 넉넉하게 잡아주고, 캐시 달아주는 정도로도 충분한 사용성을 가져갈 수 있다.
https://blog.naver.com/sssang97/223772135638
이걸로도 부족하다면 세심한 옵션 선택을 시도해본다.
Query Frontend
쿼리를 받아서 실행하는 것은 Query Frontend라는 서브시스템에 의해서 이루어진다.
애초에 이건 로컬 디스크에만 저장하는게 아니라, S3 같은 외부 저장소를 기반으로도 동작할 수 있게 되어있기 때문에, 메인 시스템과 스토리지 접근이 약간 느슨하게 분리되어 있다.
그래서 Tempo에서 쿼리 최적화는 query_frontend 같은 옵션을 통해 병렬처리 같은 세부설정을 조정하는 정도로만 제어가 가능하다.
일단 query의 동작 방식을 간단히 정리해보겠다.

- Query를 날리면 일단 query frontend라는 앞단 시스템이 쿼리를 받는다. 여기서 하나의 쿼리는 batch라고도 부른다.
- query frontend는 querier라는 동시성 태스크들을 여러개 띄워서 작업을 분할한다. querier의 개수는 쿼리가 긁어와야할 데이터 크기에 비례한다.
- querier들이 각각의 스캔/필터 작업을 완료했다면, 다시 query frontend에 전달한다. frontend는 받은 데이터를 중복제거하고 잘 가공해서 client에게 잘 반환해준다.
그리고 tempo의 데이터 스캔은 기본적으로 시간 범위 내의 풀스캔이다. RDB들처럼 인덱스 잡아서 특정 값만 빠르게 골라오고 그런게 없다.
timeout 늘리기
어쩔 수 없이 엄청나게 넓은 범위의 쿼리를 날려야 한다면, 어떻게 해도 느릴 수 밖에 없다.
server:
http_server_read_timeout: 2m
http_server_write_timeout: 2m
느리더라도 동작은 하길 원한다면 타임아웃을 늘리는게 좋다.
이렇게 하면 쿼리의 최대 실행시간이 2분으로 늘어난다. 기본값은 각각 30초다.
query frontend 옵션 조정
query frontend라는 옵션 영역이 따로 있다. 대부분의 쿼리 튜닝은 여기서 이루어진다.

건드릴 수 있는 여지는 이것저것 많지만, 대표적인 것들만 몇가지 정리해본다.
concurrent_jobs은 동시에 처리할 수 있는 작업, 동시성 태스크의 개수를 설정할 수 있는 옵션이다.
query_frontend:
search:
concurrent_jobs: 2000
기본값은 1000이다.
이게 충분해야 디스크 조회 범위가 크더라도 분산처리를 통해서 빠르게 데이터를 긁어올 수 있다.
하드웨어 스펙이 충분하다면 이걸 키워보는 것도 좋다.
target_bytes_per_job라는 옵션도 건드려볼만 하다.
query_frontend:
search:
target_bytes_per_job: 100MiB
이건 query frontend가 동시성 job을 분리하는 기준이 된다. 기본값은 100MB다.
이게 100MiB인데 스캔할 데이터의 추정 크기가 500MiB라면, 5개의 태스크로 분할하는 것이다.
그래서 크기를 늘리면 작업 수가 줄어드는 대신 각각의 작업들이 처리하는 디스크 영역이 커지고, 크기를 줄이면 작업 수가 늘고 각각의 작업이 처리하는 디스크 영역이 작아진다.
이건 더 늘리거나 줄이라고 단언하기가 어려운 것 같다.
하지만 조금은 늘리는게 대체로 성능 향상에 도움이 되는 것 같더라. 200MB 정도?
querier를 늘리는 것도 방법이다. max_concurrent_queries는 동시에 처리할 수 있는 querier의 개수를 늘린다.
querier:
max_concurrent_queries: 40
기본값은 20이다.
이것도 하드웨어 스펙이 괜찮다면 올릴만하다.
참조
https://grafana.com/docs/tempo/latest/setup/size/
https://grafana.com/docs/tempo/latest/configuration/#query-frontend
https://grafana.com/docs/tempo/latest/operations/backend_search/
https://github.com/grafana/tempo/issues/2252