Kudu 의 마스터와 tablet server 는 각자 내장 웹 서버로 메트릭을 낸다. 기본 포트는 마스터 8051, tablet server 8050 이다.
| 경로 | 형식 |
|---|---|
/metrics |
JSON |
/metrics_prometheus |
Prometheus 텍스트 |
Prometheus 형식 엔드포인트는 비교적 나중 버전에서 추가됐으므로, 쓰는 클러스터가 내주는지 먼저 확인한다. 없으면 JSON 을 변환하는 exporter 를 앞에 둬야 한다.
curl -s http://<TSERVER>:8050/metrics_prometheus | head
curl -s http://<TSERVER>:8050/metrics_prometheus | grep -c '^# TYPE'
메트릭 이름은 버전에 따라 다르다. 대시보드를 만들기 전에 실제 이름을 직접 뽑아 두는 편이 빠르다.
curl -s http://<TSERVER>:8050/metrics_prometheus | awk '/^# TYPE/{print $3}' | sort > /tmp/kudu_metrics.txt
scrape_configs:
- job_name: 'kudu-master'
metrics_path: /metrics_prometheus
static_configs:
- targets: ['master01:8051', 'master02:8051', 'master03:8051']
- job_name: 'kudu-tserver'
metrics_path: /metrics_prometheus
static_configs:
- targets: ['tserver01:8050', 'tserver02:8050', 'tserver03:8050']
메트릭 엔드포인트에는 인증이 없다. 사내망이라도 노출 범위를 방화벽으로 제한한다.
Grafana 패널에 임계선을 그리려면 Thresholds 를 쓴다. 메모리처럼 바이트 단위 지표는 패널의 Unit 을 bytes 계열로 바꾼 뒤 임계값을 사람이 읽는 단위로 넣는 편이 관리하기 쉽다. 단위를 바꾸지 않고 넣으려면 바이트로 환산해야 한다 — 48GiB 는 51539607552 다.
Kudu 에서 실제로 문제를 먼저 알려 주는 지표는 몇 개 되지 않는다.
| 관점 | 지표 성격 |
|---|---|
| 메모리 압박 | tablet server 의 메모리 사용량 대 --memory_limit_hard_bytes 비율 |
| RPC 적체 | 서비스 큐 길이와 큐 대기 시간, 큐 오버플로 횟수 |
| 스레드 포화 | 실행 중인 스레드 수가 풀 상한에 붙어 있는지 |
| 유지보수 지연 | 유지보수 관리자(compaction · flush)의 대기 작업 수 |
| 클러스터 형상 | 마스터가 보는 live tablet server 수 |
절대값보다 상한 대비 비율과 추세가 중요하다. 예를 들어 실행 스레드 수가 1000 이라는 사실만으로는 판단할 수 없고, 그것이 설정된 풀 상한에 붙어 있는지 그리고 같은 시각 큐 길이가 함께 올라갔는지를 봐야 한다. 스레드가 상한에 붙고 큐가 쌓이면 포화이고, 스레드는 많지만 큐가 비어 있으면 그저 동시 요청이 많은 것이다.
연결 수락 누계(rpc_connections_accepted 계열)는 부팅 이후 누적값이라 그대로 보면 의미가 없다. 증가율로 본다.
increase(<connections_accepted_metric>[5m])
값이 지속적으로 높으면 클라이언트가 연결을 재사용하지 않고 매번 새로 붙는다는 뜻이다. 단발성 Spark 잡이나 짧은 세션을 반복 생성하는 애플리케이션이 원인인 경우가 많다.
Kudu 는 "어떤 애플리케이션이 붙었는가" 를 메트릭으로 나누어 주지 않는다. 클라이언트를 구분하려면 다음을 조합한다.
Impala 쪽 총량을 먼저 파악한다. Impala 의 질의 프로필과 /queries 웹 페이지에서 Kudu 스캔·기록량을 집계할 수 있다. Kudu 전체 작업량에서 이 부분을 빼면 나머지가 Impala 외부(Spark · NiFi · 직접 클라이언트)다.
접속 주체는 tablet server 로그에서 직접 볼 수 있다. Kerberos 를 쓰면 principal 이, 쓰지 않으면 OS 사용자 이름이 남는다.
grep -o "username='[^']*'" /var/log/kudu/kudu-tserver.INFO | sort | uniq -c | sort -rn
연결 원본 IP 는 웹 UI 의 RPC 페이지에서 확인한다.
curl -s http://<TSERVER>:8050/rpcz | head -50
값을 바꾸기 전에 지금 무엇이 적용돼 있는지부터 본다. 추측하거나 문서의 기본값을 믿지 않는다. 버전마다 다르다.
kudu tserver get_flags <TSERVER>:7050
kudu master get_flags <MASTER>:7051
웹 UI 의 /varz 페이지도 같은 내용을 보여 주며, 기본값에서 바뀐 항목을 표시해 준다. 프로세스 인자로도 확인할 수 있다.
tr '\0' '\n' < /proc/$(pidof kudu-tserver)/cmdline | grep -i thread
자주 건드리게 되는 것들이다.
| 플래그 | 대상 |
|---|---|
--rpc_num_service_threads |
RPC 서비스 스레드 수 |
--rpc_service_queue_length |
RPC 서비스 큐 길이 |
--tablet_server_svc_num_threads |
tablet server 주 서비스 스레드 |
--maintenance_manager_num_threads |
flush · compaction 등 유지보수 |
--memory_limit_hard_bytes |
tablet server 메모리 상한 |
--flush_threshold_mb · --flush_threshold_secs |
MemRowSet flush 조건 |
스레드 수를 늘리는 것은 대체로 마지막 수단이다. 스레드가 모자란 것이 아니라 디스크나 메모리가 못 따라가는 경우가 많고, 그때 스레드만 늘리면 경합이 심해져 지연이 더 커진다. 큐가 넘치는지(queue_overflow 성격의 지표), 큐 대기 시간이 긴지, 디스크가 포화인지를 먼저 본 뒤에 결정한다.
--rpc_service_queue_length 를 크게 잡으면 요청이 거부되는 대신 오래 기다리게 된다. 클라이언트 타임아웃보다 오래 기다릴 큐라면 그 길이는 지연만 늘릴 뿐이다. 큐 길이와 클라이언트 타임아웃은 같이 놓고 정한다.
--flush_threshold_mb 를 크게(예: 10GB) 잡으면 쓰기 중에는 flush 가 드물어 유리하지만, 한 번의 flush 가 커져 그 순간 지연이 튀고 재시작 시 WAL 재생 시간이 길어진다. --flush_threshold_secs 와 함께 두어 시간 기준으로도 내려가게 한다.