NLP Blog

6. 분산 시스템 모니터링

|

6. 분산 시스템 모니터링

정의

  • 모니터링 : 쿼리의 수와 종류, 에러의 수와 종류, 처리 시간 및 서버의 활동 시간 등 시스템에 대한 정량적 실시간 데이터를 모으로 처리하고 집계해서 보여주는 것
  • 화이트박스 모니터링 : 로그나 JVM의 프로파일링 인터페이스 같은 인터페이스의 혹은 내부의 통계 지표를 제공하는 HTTP 핸들러등을 이용해서 얻은 시스템의 내부 지표들을 토대로 하는 모니터링
  • 블랙박스 모니터링 : 사용자가 보게 되는 확인 가능한 동작들을 외부에서 테스트하는 과정
  • 대시보드 : 서비스의 핵심 지표에 대한 요약된 뷰를 보여주는 애플리케이션, 가장 중요한 지표들을 사용자에게 보여주도록 만들어져 있음
  • 알림 : 사람이 읽을 수 있도록 작성된 통지. 메일, 티켓 등으로 보내짐
  • 근본 원인 : 소프트웨어 시스템의 결함이나 사람의 실수는 일단 고쳐지면 그 일이 다시는 발생하지 않을 것이라는 확신을 심어줌, 근본 원인은 해결되어야 함
  • 노드와 머신 : 물리적인 서버, 가상 머신 혹은 컨테이너에서 동작하는 커널의 단일 인스턴스
    • 서로 관련된 서비스 : 캐시 서버와 웹 서버
    • 서로 관련이 없지만 하드웨어만 공유하는 서비스 : 코드 저장소와 퍼펫이나 셰프 같은 설정 시스템의 마스터 노드
  • 푸시 : 서비스가 실행하는 소프트웨어나 관련된 설정에 대한 모든 변경사항

왜 모니터링해야 하는가?

장기적인 트렌드 분석

시간순 혹은 실험 그룹에 대한 비교

  • Acme Budkey of Byte 2.72와 Ajax DB 3.14 중 어느 것이 쿼리를 더 빨리 실행하는가? 노드를 추가했을 때 memcache의 hit rate는 얼마나 좋아지는가? 지난 주 대비 사이트가 느려졌는가?

알림

  • 문제가 생겨서 누군가 당장 수정해야 하거나 혹은 곧 문제가 생길 가능성이 있어서 누군가가 살펴봐야 하는 경우 통지를 보내야 함

대시보드

  • 개발 대시보드는 서비스에 대한 기본적인 궁금증을 해소해주며 보통 어떤 형태의 네가지 golden signal을 포함하고 있음

임시적인 회고 분석의 수행


  • 사람을 호출하는 것은 직원들의 시간을 고려하면 매우 비용이 많이 드는 일
  • 호출이 너무 빈번하면 직원들은 그냥 추측으로 넘어가거나 심한 경우 호출을 무시하게 됨
  • 효과적인 알림 시스템은 정확한 신호와 낮은 오보 비율을 갖춰야 함

모니터링에 대한 적절한 기대치 설정하기

  • 구글에서는 임계값을 학습하고 자동으로 인과관계를 찾아내는 마법같은 시스템은 선호하지 않음
  • 용량 산정이나 트래픽 예측 등에 모니터링 데이터를 활용하면 취약성 때문에 발생하는 복잡성을 완화하는 데도 도움이 됨

증상과 원인

  • 모니터링 시스템은 어떤 장애가 왜 발생했는지에 대한 질문에 답을 제시할 수 있어야 함
  • “무엇”과 “왜” 는 최대 비율의 정상적 알림과 최소 비율의 오보를 목적으로 하는 모니터링 시스템을 작성할 때 고려해야 하는 가장 중요한 간극 중 하나다.

블랙박스와 화이트 박스

  • 중요도가 낮은 서비스들에 대해서는 화이트박스 모니터링
  • 중요한 서비스들에 대해서 는 블랙박스 모니터링
  • 블랙박스 모니터링은 서버 상에 나타나는 증상을 기본으로 하며 현재 문제가 발생하는 상황을 모니터링하는 것. 즉, ‘시스템이 지금 현재 올바로 동작하지 않고 있는’ 상황을 알기 위한 것
  • 화이트박스 모니터링은 로그나 HTTP endpoin와 같은 시스템의 내부 동작들을 규범에 따라 살펴보는 기법들을 토대로 함
  • 다중계층 시스템에서는 하나 사람에게서 발생한 증상이 다른 누군가에게 장애의 원인이 되기도 함
    • 화이트박스 모니터링을 통해 어떤 정보를 얻느냐에 따라 증상에 초점을 맞출 수도 있고 원인에 초점을 맞출 수도 있음
  • 원격으로 디버깅을 수행할 때는 화이트박스 모니터링이 필수적

네 가지 결정적인 지표

  • 네 가지 결정적인 지표 : 지연응답(latency), 트래픽, 에러, 서비스 포화 상태(saturation)

지연응답

  • 요청이 서비스에 의해 처리되기까지의 시간을 말함
  • 이때 성공적인 요청의 응답 시간과 실패한 요청의 응답 시간이 중요함
    • HTTP 500 응답의 경우 실패했지만 빠르게 응답됨, 이는 통계에 나쁜 영향을 미침

트래픽

  • 시스템에 얼마나 많은 요청이 들어오는지를 측정
  • 웹 서비스의 경우는 주로 초당 HTTP 요청의 개수로 측정하며, 요청의 성질로 나누어 분류할 수도 있음
  • 오디오 스트리밍 시스템은 네트워크 입출력이나 동시 접속 세션 수 등을 측정하는 것이 알맞음
  • 키-밸류 저장소 시스템이라면 트랜잭션의 개수나 초당 조회 수 등으로 측정

에러

  • 실패한 요청의 비율
  • 이 때 명시적인 실패 (ex. HTTP 500)과 묵시적인 실패(ex. HTTP 200 성공 응답이지만 잘못된 컨텐츠가 제공된 경우), 혹은 정책과 관련된 실패 (ex. 모든 응답을 1초 내에 제공하기로 했다면 1초 이상 소요된 응답은 에러다) 등을 모두 고려해야 함
  • 사실 프로토콜의 응답 코드는 모든 종류의 실패를 표현하기에는 충분하지 않으므로 내부적인 프로토콜의 사용을 고려해야함. 이런 상황들을 모니터링하는 것은 엄청나게 어려움

서비스 포화 상태

  • 서비스가 얼마나 ‘포화’ 상태로 동작하는지를 의미함. 시스템의 일부를 측정하며 가장 병목이 발생하는 리소스를 집중해서 측정해야 한다
  • 많은 시스템들이 100% 사용량에 도달하기 전에 체감 성능의 하락이 발생하므로 기본적으로 목표 사용량을 설정해야 함
  • 복합 시스템의 경우, 시스템의 포화 상태는 높은 수준(abstract)의 부하 측정을 통해 보완할 수 있음
  • 시스템의 포화상태는 ‘데이터베이스 서버의 사용 가능한 디스크 공간이 4시간 안에 바닥날 것’과 같은 긴급한 상황을 미리 예측하는 것과 관련이 깊다.

마지막(tail) 요청(혹은 실행과 성능)에 대한 고려

  • 모니터링 시스템을 처음부터 개발하게 된다면, 가능한 한 평범한 수준의 성능을 토대로 시스템을 디자인하려 할 것이다.
  • 하지만 이는 위험함
    • CPU와 데이터베이스는 균형있게 활용되지 못하는 경우가 많음
    • 지연응답도 마찬가지, 초당 1000개의 요청에 대한 평균 지연응답이 100ms인 웹서비스의 경우 요청 중 1% 정도는 5초 정도 지연될 수 있음
  • 전체 요청에 대한 평균 응답 시간이 느려지는 것과 마지막 요청 (tail of requests)이 아주 느려지는 것을 구분하는 간단한 방법은 실제 지연응답이 아니라 전체 요청의 수와 전체 지연응답을 수집하는 것 (분포도 확인)

적당한 측정 방법 선택하기

  • 시스템의 지표들은 각기 다른 수준으로 세분화하여 측정되어야 함
    • CPU 부하를 1분 단위로 관찰한다고 해서 CPU 사용률이 갑자기 치솟아 나중에 유입된 요청들에 대한 지연응답이 발생하는 현상을 파악할 수는 없다.
    • 한편 1년에 9시간 이하의 다운타임 (99.9%의 연간 업타임)을 목표로 하는 웹 서비스에 대해 200 상태의 리턴 여부를 1분에 한두 번 이상 확인해야 한다면 너무 빈번하게 확인하는 것
    • 마찬가지로 99.9%의 가용성을 목표로 하는 서비스에 대해 하드 드라이브에 여유 공간이 있는지를 1~2분마다 한 번씩 확인하는 것 또한 무의미하다
  • CPU 부하를 초단위로 측정하면 유용한 데이터를 얻을 수도 있겠지만 비용이 너무 많이 듬
  • 만일 모니터링 시스템에 주어진 목표가 높은 수준의 분석을 위한 데이터 수집이지만 극단적으로 낮은 지연응답을 필요로 하지 않는다면, 서버에서 내부 샘플링을 수행한 후, 여러 서버에 걸쳐 데이터를 수집하고 시계열로 집계하는 외부 시스템을 구성하면 비용을 줄일 수 있음
    • 매 초마다 현재 CPU의 사용량을 기록한다
    • 5% 단위로 버킷을 구성하고 매 초당 CPU 사용량을 측정하여 적절한 버킷의 값을 증가시킨다
    • 분 단위로 이 값들을 집계한다

더욱 단순하게가 아니라 최대한 단순하게

  • 만약 아래와 같은 요구사항을 모두 고려하면 모니터링 시스템은 매우 복잡해짐
    • 모든 지표에 대해 각기 다른 지연응답 기준치 중에서 백분위수가 달라질 때마다 보내야 하는 알림
    • 발생가능한 장애 원인을 탐지하고 보여주기 위한 추가 코드
    • 이런 발생 가능한 각각의 장애 원인과 관련된 대시보드
  • 모니터링 시스템 역시 복잡도가 증가해서 장애가 쉽게 발생하거나 변경 사항을 수용하기에 너무 복잡해져서 유지보수가 어려워 짐
  • 모니터링 시스템을 디자인할 때는 최대한 간결함을 추구해야 함
    • 가장 빈번하게 발생하는 사건/사고를 탐지하기 위한 규칙은 최대한 간결하고 예측 가능하며 확실해야 함
    • 수정 빈도가 높지 않은 데이터의 수집, 집계 그리고 알림에 관련된 설정은 제거하는 것이 좋다
    • 수집은 되지만 대시보드에 노출되지도 않고 알림에 사용되지도 않는 데이터는 역시 제거하는 것이 좋다

지금까지 살펴본 원리들을 결합하기

  • 모니터링과 알림에 대한 규칙을 정의할 때 다음의 질문들을 활용하자
    • 이 규칙은 해당 규칙이 존재하지 않는다면 알아챌 수 없는 긴급하고, 대처가 가능하며 즉각적으로 사용자가 인지할 수있는 상태를 탐지 할 수 있는가?
    • 긴습하지 않은 알림이라면 무시할 수 있는 알림인가? 언제, 왜 이 알림을 무시할 수 있으며, 이런 알림을 받지 않으려면 어떻게 해야 할까?
    • 이 알림은 분명히 사용자에게 좋지 않은 영향을 미치는 상황에 대한 알림인가? 가용 트래픽이 모두 소모되었거나 테스트 배포처럼 사용자에게 부정적인 영향을 미치지 않는 경우에는 알림이 발생하지는 않았는가?
    • 이 알림에 대해 대응이 가능한가? 이 알림은 긴급한 것인가 아니면 내일 아침까지 기다려도 되는 것인가? 대응책은 안전하게 자동화가 가능한가? 알림에 대한 대응은 장기적인 수정이 될 것인가 아니면 단기적인 우회책이 될 것인가?
    • 다른 사람들이 이 이슈에 대한 호출을 받아서 적어도 하나 이상의 불필요한 호출이 발생했는가?
  • 위 질문은 아래의 기본 철학을 바탕으로 한다
    • 매번 호출기가 울릴 때마다 긴급한 상황임을 인지하고 그에 대응할 수 있어야 한다
    • 모든 호출은 대응이 가능해야 한다
    • 호출에 대한 모든 대응은 이성적이어야 한다
    • 호출은 새로운 문제나 지금까지 보지 못한 사건에 대한 것이어야 한다.

장기적 모니터링

빅테이블 SRE: 과도한 알림

  • 빅테이블의 성능을 개선하는 동안 SLO 목표치를 75% 요청 지연으로 하향 조정
  • 이메일 알림도 중단
  • 팀에 숨통이 트이면서 장기적 문제들을 해결할 시간을 갖게 됨

지메일: 사람이 예측 및 스크립팅할 수 있는 응답

  • 이해못함

한 걸음 더 나아가기

결론

  • 제대로 구성된 모니터링과 알림 파이프라인은 간결하고 명료하다.
  • 증상을 탐지하는 것에 집중하며, 문제를 디버깅하기 위한 방안을 제시함으로써 원인 분석을 통해 스스로 학습하고 성장할 수 있는 기회를 제공

Comments