LabHub
배우기 러닝패스 코스

Grafana — ダッシュボードは問いだ

このダッシュボードは1分に何回投げているのか

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

대시보드 하나의 질의 횟수·계열 수·점 개수를 실제로 재어 값을 매기고, 예산을 파일과 검사기로 적은 뒤 그 예산 안에 드는 판을 만들어 제출합니다.

왜 중요한가

대시보드는 공짜로 보인다. 패널을 하나 더 붙이는 일은 클릭 세 번이고 비용은 다른 팀의 Prometheus 에서 발생하기 때문이다. 그래서 대시보드는 언제나 무거워지는 쪽으로만 자란다. 값을 매기는 셈법 자체는 어렵지 않다 — 패널마다 붙은 쿼리를 더하고, 목록을 서버에 물어보는 변수를 더하면 한 번 열 때의 질의 수이고, 여기에 자동 새로고침 주기를 곱하면 분당 질의 수다. 쿼리 열 개에 10초 새로고침이면 1분에 예순 번, 하루에 팔만 번이고, 그 화면을 아무도 보지 않는 밤에도 똑같이 날아간다. 이 숫자를 한 번 세어 본 팀과 세어 보지 않은 팀은 대시보드를 대하는 태도가 달라진다.

단계

  1. lab-start-grafana 로 Grafana 를 띄우고, /opt/lab/gfd/gfd-perf/heavy.json고치지 말고 그대로 Grafana 에 올리세요(uid 는 파일에 적힌 gfd-perf, 패널 8개). curl/api/dashboards/db 에 POST 하면 됩니다. 이 대시보드는 이 실습이 끝날 때까지 원본으로 그대로 남겨 둡니다 — 줄인 판은 마지막 단계에서 다른 uid 로 따로 저장합니다.
  2. Grafana 에 올라간 대시보드를 내려받아 세세요. /root/gfd-perf/02-count.txtpanels= targets= var_queries= open= 네 줄을 적습니다. panels 는 행(row)을 뺀 패널 수, targets 는 모든 패널의 쿼리 수, var_queriestemplating.listtypequery 인 변수의 수, opentargetsvar_queries 를 더한 값 — 대시보드를 한 번 열 때의 질의 수입니다.
  3. 패널마다 붙은 쿼리를 실제로 던져 돌아오는 계열 수를 재세요. 지나간 시각을 하나 골라(지금보다 5분 이상 앞, 6시간 이내) 모든 쿼리를 그 시각의 순간값으로 던집니다. /root/gfd-perf/03-series.txtat= total= top_id= top_series= 네 줄을 적습니다 — at 은 고른 시각의 epoch 초, total 은 대시보드의 모든 쿼리가 돌려주는 계열 수의 합, top_id 는 계열을 가장 많이 돌려주는 패널의 id, top_series 는 그 패널의 계열 수입니다. 가장 무거운 패널의 그래프에 선이 몇 개 그려질지 생각해 보세요.
  4. 지나간 구간을 하나 골라(2시간 이상, 끝은 지금보다 앞) 3번 패널의 p95 쿼리를 같은 구간에 step 만 바꿔 두 번 던지세요 — 한 번은 step=15, 한 번은 step=300. /root/gfd-perf/04-points.txtstart= end= points_fine= points_coarse= 네 줄을 적습니다. points_fine 은 step 15 일 때, points_coarse 는 step 300 일 때 계열 하나에 돌아온 점 개수입니다.
  5. 대시보드 JSON 의 자동 새로고침 주기를 읽어 /root/gfd-perf/05-rate.txtrefresh= refresh_sec= targets= per_min= 네 줄을 적으세요. refresh 는 JSON 에 적힌 문자열 그대로, refresh_sec 는 그것을 초로 환산한 정수, targets 는 2단계에서 센 쿼리 수, per_mintargets 곱하기 60 / refresh_sec 입니다. 이 실습의 셈법에서는 자동 새로고침이 패널 쿼리만 다시 던지고 변수 질의는 다시 던지지 않는 것으로 봅니다.
  6. 3번 패널의 p95 쿼리는 버킷 계열 마흔여덟 개를 읽어 매번 분위수를 계산합니다. /etc/prometheus/rules/gfd-perf.yml 에 그룹 이름 gfd-perf, interval 15초, 레코딩 룰 하나를 두세요 — recordhandler:http_request_duration_seconds:p95, expr 은 3번 패널의 p95 쿼리 그대로입니다. promtool check rules /etc/prometheus/rules/gfd-perf.yml 로 확인한 뒤 curl -X POST http://127.0.0.1:9090/-/reload 로 반영하고, 20초 이상 기다렸다가 promq 'handler:http_request_duration_seconds:p95' 가 값을 돌려주는지 확인하고 다음 단계로 넘어가세요.
  7. /root/gfd-perf/budget.txt 에 예산을 다섯 줄로 적으세요 — max_panels=6 max_targets=6 max_var_queries=0 min_refresh_sec=60 max_queries_per_min=6. 그리고 /root/gfd-perf/budget.py 를 만드세요. 예산 파일 경로와 대시보드 JSON 경로를 인자로 받아 위반을 한 줄에 하나씩(B1~B5 로 시작) 출력하고, 위반이 하나라도 있으면 종료 코드 1 로 끝나야 합니다. B1 패널 수 초과 · B2 쿼리 수 초과 · B3 변수 질의 수 초과 · B4 새로고침이 켜져 있는데 주기가 너무 짧음 · B5 분당 질의 수 초과. 원본 /opt/lab/gfd/gfd-perf/heavy.json 에 돌려 다섯 위반이 모두 잡히는지 확인하세요.
  8. 원본 gfd-perf 는 그대로 두고, 예산 안에 드는 새 대시보드를 uid gfd-perf-slim 으로 저장하세요. 줄이는 방법은 자유지만 다음 셋은 반드시 들어가야 합니다 — 아무 패널도 쓰지 않는 변수 질의를 없앨 것, 자동 새로고침 주기를 60초 이상으로 바꿀 것, 그리고 p95 패널의 쿼리를 6단계에서 만든 handler:http_request_duration_seconds:p95 로 바꿀 것. 저장한 뒤 그 대시보드를 그대로 내려받아 /root/gfd-perf/fixed.json 에 저장하고(.dashboard 본문만), 7단계의 검사기를 돌려 위반 0 · 종료 코드 0 인 것을 확인하세요. 그리고 /root/gfd-perf/08-review.mdB1= 부터 B5= 까지 다섯 줄로 각 항목을 어떻게 예산 안에 넣었는지 각 30자 이상 적으세요.

참고

값을 매길 대시보드를 올린다

lab-start-grafana 로 Grafana 를 띄우고, /opt/lab/gfd/gfd-perf/heavy.json고치지 말고 그대로 Grafana 에 올리세요(uid 는 파일에 적힌 gfd-perf, 패널 8개). curl/api/dashboards/db 에 POST 하면 됩니다. 이 대시보드는 이 실습이 끝날 때까지 원본으로 그대로 남겨 둡니다 — 줄인 판은 마지막 단계에서 다른 uid 로 따로 저장합니다.

저장 API 는 대시보드 본문을 dashboard 키 안에 담고 overwrite 를 함께 보냅니다. 파일에서 그 모양을 만드는 데는 jq -n --slurpfile 이 편합니다. Grafana 가 뜨는 데 몇십 초 걸리니 /api/health 가 답하는지 먼저 보세요.

한 번 여는 데 질의가 몇 번 날아가는가

Grafana 에 올라간 대시보드를 내려받아 세세요. /root/gfd-perf/02-count.txtpanels= targets= var_queries= open= 네 줄을 적습니다. panels 는 행(row)을 뺀 패널 수, targets 는 모든 패널의 쿼리 수, var_queriestemplating.listtypequery 인 변수의 수, opentargetsvar_queries 를 더한 값 — 대시보드를 한 번 열 때의 질의 수입니다.

행 안에 접혀 있는 패널도 패널입니다. jq 로 펴려면 .panels[] | (., (.panels[]?)) 뒤에 typerow 인 것을 걸러 내면 됩니다. 쿼리는 패널마다 targets 배열에 들어 있고 패널 하나에 둘 이상일 수 있습니다. 변수는 목록을 서버에 물어보는 것만 셉니다 — 손으로 적어 둔 상수 목록은 질의를 만들지 않습니다.

어느 패널이 가장 무거운가

패널마다 붙은 쿼리를 실제로 던져 돌아오는 계열 수를 재세요. 지나간 시각을 하나 골라(지금보다 5분 이상 앞, 6시간 이내) 모든 쿼리를 그 시각의 순간값으로 던집니다. /root/gfd-perf/03-series.txtat= total= top_id= top_series= 네 줄을 적습니다 — at 은 고른 시각의 epoch 초, total 은 대시보드의 모든 쿼리가 돌려주는 계열 수의 합, top_id 는 계열을 가장 많이 돌려주는 패널의 id, top_series 는 그 패널의 계열 수입니다. 가장 무거운 패널의 그래프에 선이 몇 개 그려질지 생각해 보세요.

계열 수는 /api/v1/query 응답의 data.result 길이입니다. 시각을 못박으려면 time= 을 함께 보내세요 — 그래야 나중에 다시 세어도 같은 답이 나옵니다. 쿼리를 대시보드 JSON 에서 뽑아 반복문으로 돌리면 손으로 옮겨 적지 않아도 됩니다. 패널 하나에 쿼리가 둘이면 그 둘을 더한 것이 그 패널의 계열 수입니다.

해상도를 바꾸면 돌아오는 점이 몇 배가 되나

지나간 구간을 하나 골라(2시간 이상, 끝은 지금보다 앞) 3번 패널의 p95 쿼리를 같은 구간에 step 만 바꿔 두 번 던지세요 — 한 번은 step=15, 한 번은 step=300. /root/gfd-perf/04-points.txtstart= end= points_fine= points_coarse= 네 줄을 적습니다. points_fine 은 step 15 일 때, points_coarse 는 step 300 일 때 계열 하나에 돌아온 점 개수입니다.

구간 질의는 /api/v1/query_range 이고 start·end·step 을 함께 보냅니다. 돌아온 JSON 의 data.result[0].values 길이가 계열 하나의 점 개수입니다. 두 숫자의 비를 내 보면 해상도가 비용에 그대로 곱해진다는 것이 보입니다. 구간을 지나간 절대 시각으로 못박아야 나중에 다시 재도 같은 값이 나옵니다.

자동 새로고침을 곱해 분당 질의 수를 낸다

대시보드 JSON 의 자동 새로고침 주기를 읽어 /root/gfd-perf/05-rate.txtrefresh= refresh_sec= targets= per_min= 네 줄을 적으세요. refresh 는 JSON 에 적힌 문자열 그대로, refresh_sec 는 그것을 초로 환산한 정수, targets 는 2단계에서 센 쿼리 수, per_mintargets 곱하기 60 / refresh_sec 입니다. 이 실습의 셈법에서는 자동 새로고침이 패널 쿼리만 다시 던지고 변수 질의는 다시 던지지 않는 것으로 봅니다.

자동 새로고침 주기는 대시보드 JSON 의 맨 위 refresh 열쇠에 10s·1m 같은 문자열로 들어 있습니다. 끝 글자가 단위이고 앞이 숫자입니다. 이 숫자가 왜 중요한지 감이 안 오면 24를 곱해 하루치를 내 보세요 — 아무도 보지 않는 밤에도 같은 수가 날아갑니다.

무거운 계산을 레코딩 룰로 옮긴다

3번 패널의 p95 쿼리는 버킷 계열 마흔여덟 개를 읽어 매번 분위수를 계산합니다. /etc/prometheus/rules/gfd-perf.yml 에 그룹 이름 gfd-perf, interval 15초, 레코딩 룰 하나를 두세요 — recordhandler:http_request_duration_seconds:p95, expr 은 3번 패널의 p95 쿼리 그대로입니다. promtool check rules /etc/prometheus/rules/gfd-perf.yml 로 확인한 뒤 curl -X POST http://127.0.0.1:9090/-/reload 로 반영하고, 20초 이상 기다렸다가 promq 'handler:http_request_duration_seconds:p95' 가 값을 돌려주는지 확인하고 다음 단계로 넘어가세요.

레코딩 룰의 이름은 관례가 정해져 있습니다 — 수준:지표:연산 꼴로 콜론 두 개를 씁니다. 그룹의 interval 이 계산 주기이고, 반영 직후에는 아직 한 번도 계산하지 않았으므로 그 주기가 한 번 지나야 값이 생깁니다. curl -s http://127.0.0.1:9090/api/v1/rules | jq 로 룰이 실렸는지 볼 수 있습니다.

예산을 적고 그 예산을 검사하는 도구를 만든다

/root/gfd-perf/budget.txt 에 예산을 다섯 줄로 적으세요 — max_panels=6 max_targets=6 max_var_queries=0 min_refresh_sec=60 max_queries_per_min=6. 그리고 /root/gfd-perf/budget.py 를 만드세요. 예산 파일 경로와 대시보드 JSON 경로를 인자로 받아 위반을 한 줄에 하나씩(B1~B5 로 시작) 출력하고, 위반이 하나라도 있으면 종료 코드 1 로 끝나야 합니다. B1 패널 수 초과 · B2 쿼리 수 초과 · B3 변수 질의 수 초과 · B4 새로고침이 켜져 있는데 주기가 너무 짧음 · B5 분당 질의 수 초과. 원본 /opt/lab/gfd/gfd-perf/heavy.json 에 돌려 다섯 위반이 모두 잡히는지 확인하세요.

예산을 글로 적어 두면 아무도 안 지킵니다. 돌아가는 코드로 적으세요. 행(row) 안에 접힌 패널도 패널이라는 점, 파일이 {"dashboard": ...} 로 감싸여 있을 수도 있다는 점을 잊지 마세요. refresh 가 없거나 꺼져 있으면 자동 새로고침이 없는 것이라 B4 와 B5 는 걸리지 않아야 합니다.

예산 안으로 줄여 새 판으로 제출한다

원본 gfd-perf 는 그대로 두고, 예산 안에 드는 새 대시보드를 uid gfd-perf-slim 으로 저장하세요. 줄이는 방법은 자유지만 다음 셋은 반드시 들어가야 합니다 — 아무 패널도 쓰지 않는 변수 질의를 없앨 것, 자동 새로고침 주기를 60초 이상으로 바꿀 것, 그리고 p95 패널의 쿼리를 6단계에서 만든 handler:http_request_duration_seconds:p95 로 바꿀 것. 저장한 뒤 그 대시보드를 그대로 내려받아 /root/gfd-perf/fixed.json 에 저장하고(.dashboard 본문만), 7단계의 검사기를 돌려 위반 0 · 종료 코드 0 인 것을 확인하세요. 그리고 /root/gfd-perf/08-review.mdB1= 부터 B5= 까지 다섯 줄로 각 항목을 어떻게 예산 안에 넣었는지 각 30자 이상 적으세요.

새 uid 로 저장할 때는 본문에서 id 를 빼야 합니다 — 남겨 두면 Grafana 가 그 id 의 기존 대시보드를 바꿔 버립니다. 쿼리 수를 줄이는 방법은 패널을 지우는 것만이 아닙니다. 두 쿼리를 하나의 식으로 합칠 수 있는 패널이 있는지 보세요 — 건수 둘을 따로 받아 눈으로 나누는 패널이 그렇습니다. 계열을 마흔여덟 개 돌려주는 패널은 그 화면에서 읽어 낼 것이 없는지 먼저 물어보세요.