모니터링 기초 — 지표는 어디에 있고, 무엇을 알람으로 걸 것인가
Kafka: The Definitive Guide (O'Reilly, 2017, 1st Edition) — Neha Narkhede, Gwen Shapira, Todd Palino Chapter 10: Monitoring Kafka — Metric Basics (Where Are the Metrics? / Internal or External Measurements / Application Health Checks / Metric Coverage) (pp.211-213)
Kafka는 지표가 너무 많아서 무엇을 봐야 할지가 오히려 문제가 된다. 이 모듈은 Kafka 지표가 노출되는 통로인 JMX, 애플리케이션이 스스로 만드는 내부 지표와 바깥에서 측정하는 외부 지표의 역할 차이, 프로세스 자체의 생사를 확인하는 헬스체크, 그리고 알람을 적게 유지해야 하는 이유(alert fatigue)를 다룬다. 이후 모듈에서 다룰 개별 지표들이 왜 '반드시 봐야 할 것'으로 선정되었는지의 근거가 된다.
지표는 어디에 있는가 — JMX
Kafka가 노출하는 모든 지표는 JMX(Java Management Extensions) 인터페이스로 접근할 수 있다. 외부 모니터링 시스템에서 이를 쓰는 가장 쉬운 방법은 모니터링 시스템이 제공하는 수집 에이전트를 Kafka 프로세스에 붙이는 것이다.
방식은 크게 두 가지다. 하나는 시스템에서 별도 프로세스로 돌면서 JMX 인터페이스에 접속하는 것으로, Nagios XI의 check_jmx 플러그인이나 jmxtrans가 여기에 해당한다. 다른 하나는 Kafka 프로세스 안에서 직접 돌면서 지표를 HTTP로 노출해 주는 JMX 에이전트를 쓰는 것으로, Jolokia나 MX4J가 여기에 해당한다.
모니터링 에이전트를 직접 구축·운영해 본 경험이 조직에 없다면, 에이전트·수집·저장·그래프·알람을 묶어 제공하는 모니터링 서비스(monitoring as a service)를 쓰는 것도 현실적인 선택지다.
브로커에 JMX로 직접 붙는 시스템을 설정할 때 필요한 JMX 포트는 브로커가 자기 정보에 함께 기록해 둔다. ZooKeeper의 /brokers/ids/<ID> znode에 JSON 형식으로 브로커 정보가 들어 있고, 여기에 hostname과 jmx_port 키가 포함되어 있다.
핵심 포인트
- Kafka의 모든 지표는 JMX로 노출된다
- 수집 방식은 외부 프로세스형(check_jmx, jmxtrans)과 인프로세스 에이전트형(Jolokia, MX4J) 두 가지
- 브로커의 JMX 포트는 ZooKeeper /brokers/ids/<ID> znode의 jmx_port 키에서 확인할 수 있다
내부 측정 대 외부 측정
JMX 같은 인터페이스로 제공되는 지표는 내부(internal) 지표다. 모니터링 대상 애플리케이션 자신이 만들어 내보내는 값이라는 뜻이다. 요청의 각 단계별 소요 시간처럼 애플리케이션만이 알 수 있는 수준의 상세 정보는 내부 지표가 최선이다.
반면 요청 전체 소요 시간이나 특정 요청 타입의 가용성처럼 바깥에서 측정할 수 있는 지표도 있다. 이 경우 Kafka 클라이언트나 제3의 애플리케이션이 서버(우리 경우에는 브로커)를 대신 측정해 주는 셈이다. 흔히 가용성(브로커에 접속이 되는가)이나 지연(요청이 얼마나 걸리는가) 같은 값이며, 애플리케이션 바깥에서 본 관점이라 오히려 더 유익한 경우가 많다.
책이 드는 비유는 웹사이트 헬스 모니터링이다. 웹 서버는 정상 동작 중이고 자기가 보고하는 지표도 전부 정상이다. 그런데 웹 서버와 외부 사용자 사이의 네트워크에 문제가 생겨 아무도 사이트에 접속할 수 없다. 내부 지표만 보면 이 상황을 절대 알 수 없고, 네트워크 바깥에서 도는 외부 모니터링만이 이를 감지해 알려 줄 수 있다.
핵심 포인트
- 내부 지표는 애플리케이션 자신이 만드는 값 — 단계별 상세 정보에 강하다
- 외부 지표는 바깥에서 본 가용성과 지연 — 내부 지표가 정상이어도 사용자가 못 쓰는 상황을 잡아낸다
- 둘은 대체 관계가 아니라 보완 관계다
애플리케이션 헬스체크
지표를 어떤 방식으로 수집하든, 애플리케이션 프로세스 자체의 전반적인 건강 상태를 확인하는 단순한 헬스체크를 별도로 갖춰야 한다. 방법은 두 가지다.
첫째, 브로커가 살아 있는지 죽었는지를 보고해 주는 외부 프로세스를 두는 것(헬스체크)이다. 브로커의 경우 클라이언트가 접속하는 그 외부 포트에 접속해 응답하는지 확인하는 것만으로 충분하다.
둘째, Kafka 브로커가 지표를 보고하지 않는다는 사실 자체에 알람을 거는 것(stale metrics)이다. 이 방식도 동작은 하지만, 브로커가 죽은 것인지 모니터링 시스템이 죽은 것인지 구분하기 어렵다는 약점이 있다.
클라이언트 애플리케이션의 헬스체크는 더 복잡할 수 있다. 프로세스가 떠 있는지만 보는 단순한 확인부터, 애플리케이션이 스스로 건강 상태를 판정하는 내부 메서드를 노출하는 방식까지 폭이 넓다.
핵심 포인트
- 브로커 헬스체크는 클라이언트가 쓰는 외부 포트에 접속해 응답을 보는 것으로 충분하다
- 지표 미보고(stale metrics)에 알람을 거는 방식은 브로커 장애와 모니터링 시스템 장애를 구분하기 어렵다
지표 커버리지와 알람 피로
Kafka가 노출하는 측정값의 개수를 생각하면, 무엇을 볼지 고르는 일이 특히 중요하다. 그 값들로 알람을 정의할 때는 더욱 그렇다. 알람이 너무 많이 울려 문제의 심각도를 판단하기 어려워지는 '알람 피로(alert fatigue)'에 빠지기 쉽고, 모든 지표에 대해 적절한 임계값을 정하고 최신 상태로 유지하는 일도 어렵다. 알람이 과도하거나 자주 틀리면, 우리는 알람이 애플리케이션 상태를 제대로 설명한다고 믿지 않게 된다.
따라서 높은 수준의 커버리지를 가진 알람 몇 개를 두는 편이 유리하다. 큰 문제가 있다는 사실만 알려 주는 알람 하나를 두고, 정확한 원인은 추가 데이터를 모아 판별하는 방식이다.
책의 비유는 자동차의 체크 엔진 등이다. 에어 필터, 오일, 배기 등 개별 문제를 알리는 표시등이 100개 있으면 오히려 혼란스럽다. 대신 표시등 하나가 문제가 있다는 것을 알려 주고, 정확히 무엇이 문제인지는 별도로 상세 정보를 찾아보는 경로가 있으면 된다. 다음 모듈에서 볼 under-replicated partitions 지표가 바로 이 체크 엔진 등 역할을 하는 대표적인 지표다.
핵심 포인트
- 알람이 많을수록 신뢰가 떨어진다 — alert fatigue
- 커버리지가 넓은 소수의 알람 + 상세 진단을 위한 추가 지표 조합이 실전적이다
- 체크 엔진 등 비유: 문제 발생을 알리는 지표 하나, 원인 규명은 별도 경로
이 모듈과 연관된 문항 2개가 문제 은행에 있습니다.
이 내용으로 문제 풀어보기