Loki — 로그를 색인하지 않는 로그 저장소 · 질의가 얼마를 읽는가 · 이론
줄 필터는 읽는 양을 줄이지 않는다
한 줄 요약
Loki 질의의 값은 읽은 바이트로 매겨진다. 그리고 읽는 양을 줄이는 것은 스트림 선택자와 시간 구간 둘뿐이다 — 줄 필터와 파서는 이미 읽은 줄을 거를 뿐이다.
왜 이게 필요했나
새벽에 결제 오류를 조사하던 사람이 Grafana 에서 {cluster="prod"} |= "payment" |= "timeout" 을 하루 구간으로 던졌다. 질의는 4분을 돌다 시간 초과로 끊겼다. 옆 사람이 {cluster="prod", app="pay"} 로 바꾸고 구간을 30분으로 좁히자 2초 만에 답이 나왔다. 두 질의의 결과는 같았다.
차이는 읽은 양이다. 첫 질의는 그 클러스터의 모든 스트림을 하루치 읽고 나서 걸렀고, 두 번째는 한 스트림을 30분치만 읽었다. 줄 필터 두 개는 읽는 양을 한 바이트도 줄이지 않았다.
어떻게 동작하나
Loki 는 본문을 색인하지 않는다. 색인에 있는 것은 라벨 조합(스트림)과 그 스트림의 청크가 어느 시간대에 있는가 뿐이다. 그래서 질의가 실행되는 순서는 늘 같다.
1. 선택자가 색인을 보고 어떤 스트림의 어떤 청크를 열지 고른다.
2. 시간 구간이 그 청크 중 겹치는 것만 남긴다.
3. 남은 청크를 전부 읽어 줄 필터와 파서와 라벨 필터를 차례로 적용한다.
1번과 2번만 읽는 양을 정한다. 3번은 이미 읽은 것을 버리는 일이다. 그래서 응답에 실려 오는 통계에서 totalLinesProcessed 와 totalBytesProcessed 는 선택자와 구간에만 반응하고, totalPostFilterLines 와 반환된 줄 수만 필터에 반응한다. 이 두 쌍을 나눠 읽는 것이 Loki 질의를 튜닝하는 방법의 전부에 가깝다.
그렇다고 줄 필터가 쓸모없는 것은 아니다. 줄 필터는 파서보다 훨씬 싸다. 파서는 줄마다 구문을 해석해 라벨을 만들어야 하고, 라벨 필터는 그 라벨을 비교한다. 그래서 파서를 붙일 때는 앞에 줄 필터를 두어 파서가 볼 줄 수를 줄이는 것이 여전히 이익이다 — 다만 그 이익은 읽는 바이트가 아니라 CPU 에서 난다. 두 가지를 섞어 말하면 "줄 필터를 앞에 뒀는데 왜 안 빨라지지" 에서 막힌다.
limit 은 믿을 만한 비용 손잡이가 아니다. 단순한 로그 질의에서는 Loki 가 필요한 만큼 모은 뒤 일찍 멈출 수 있어 읽는 양이 줄기도 한다. 다만 얼마나 줄지는 질의가 몇 조각으로 쪼개져 병렬로 도는지에 달려 있어서, 같은 질의를 같은 구간에 두 번 던져도 읽은 줄 수가 다르게 나온다(이 실습 환경에서 실제로 그랬다). 그래서 "limit 을 줄여 비용을 아끼자" 는 계획은 세울 수 없고, 지표 질의에는 limit 이 아예 적용되지 않는다.
라벨 설계가 결국 질의 성능이 되는 이유가 여기 있다. app 라벨이 없으면 애초에 좁힐 방법이 없고, 반대로 user_id 같은 것을 라벨로 넣으면 스트림이 폭발해 색인 조회 자체가 비싸진다. 좁힐 수 있을 만큼만 라벨로, 나머지는 본문으로 — 이 균형이 Loki 운영의 중심이다.
현장에서 만나는 모습
비용 사고는 대개 대시보드에서 난다. 사람이 손으로 던지는 질의는 하루 몇 번이지만, 대시보드 패널은 30초마다 자동으로 돈다. 선택자가 헐거운 패널 하나가 한 달이면 수십 테라바이트를 읽는다. 그래서 대시보드를 만들 때는 패널마다 통계를 한 번씩 찍어 보고, 읽는 양이 큰 패널은 선택자를 좁히거나 기본 구간을 줄여 둔다.
또 하나. 사람들은 조사할 때 구간을 넓게 잡는 버릇이 있다. "언제인지 모르니 일단 하루" 다. 그런데 사고 시각은 대개 지표나 경보로 이미 알고 있다. 먼저 지표에서 시각을 못박고 로그는 그 앞뒤 15분만 보는 순서로 바꾸면, 같은 조사가 열 배 빨라진다.
다음 실습에서 할 것
네 스트림 2400줄을 파드의 Loki 에 넣고, 드물게 섞여 있는 표시 한 줄을 찾는 질의를 네 가지 방법으로 던져 본다. 매번 응답의 stats.summary 를 읽어 읽은 줄 수와 바이트를 기록하고, 선택자를 좁혔을 때와 구간을 좁혔을 때만 그 숫자가 줄어드는 것을 표로 만든 뒤, 마지막에는 정해진 예산 안에서 같은 답을 내는 질의를 직접 써서 제출한다.