안녕하세요. 우아한형제들에서 DBA로 근무하고 있는 이재웅입니다.
오늘은 누구나 알고 있는 알람에 관해 이야기를 하려고 합니다.
인프라나 데이터베이스를 운영하게 되면 수많은 알람을 만나게 됩니다.
우아한형제들의 데이터베이스 또한 많은 알람이 설정되어 있습니다.
사실 알람이란건 핸드폰 알람처럼 간단하고 생활에 밀접한 도구이지만 이걸 더 잘 쓰기 위해선 좀 더 알아볼 필요가 있습니다.

현재 우아한형제들의 데이터베이스에는

운영 환경 기준으로만 약 3000개의 알람이 설정되어 있습니다.
RDS 인스턴스 하나 당 보통 16개 정도의 알람이 설정되어 있습니다.
CPU 사용량, 메모리 잔여량, DB 커넥션, 각종 Latency 등의 메트릭에 알람 설정을 합니다.
각각의 경고, 심각에 대한 임계치도 설정되어 있고 메트릭에 따라 알람 주기도 살짝 다릅니다.

이 글을 보시는 분들은 서비스 규모에 따라 이 3000개가 많게 느껴질 수도 있고 적다고 보실 수도 있습니다.
그럼 이 3000개는 어떻게 유지보수를 할까요?
당연히 어느 정도 자동화는 되어있습니다. 그리고 당연히 관리가 안되는 부분도 있습니다.
DBA가 새로운 RDS 인스턴스를 생성할 때 일련의 배치를 통해 알람을 생성합니다.
이렇게 일괄적으로 생성하다 보니 서비스 별로 알람 임계치를 일일히 맞추기 어렵습니다.
단순히 인스턴스 타입 클래스에 맞게 계산해서 생성하는 정도입니다.
클라우드 환경이다보니 인스턴스가 삭제되거나 변경되는 경우가 많은데
이런 이벤트에 따라 알람 관리가 적절히 이루어지지 않고 있습니다.

일반적으로 알람이 많으면 알람이 발생하는 비율이 높을 것이고
그래서 스트레스를 많이 받을 걸로 생각하실텐데 반은 맞고 반은 틀립니다.
알람이 밤낮 안가리고 올 수도 있는데 밤에 잠을 편하게 잘 수 있을까?
알람에 대한 긍정적인 면도 있고 부정적인 면이 있는건 사실입니다.
만약 해안가에 살고 있는데 태풍이나 해일 경보가 없다면 잠을 편하게 잘 수 있을까요?

알람의 사전적 의미는 ‘불안, 공포, 경보, 경보기, 불안하게 만들다, 경보장치를 달다’ 등 입니다.

핸드폰 알람을 생각해보세요. 우리가 핸드폰 알람을 설정하는 목적이 뭘까요?
잠에서 깨어나기 위한 알람, 약속시간에 늦지 않기 위한 알람, 라면 익히는 시간을 위한 알람 등
어떤 일을 하기 위한 타이밍을 알고 싶어서 설정합니다.
이렇게만 생각하면 알람이란건 우리의 생활을 편하게 하기 위한 좋은 도구인데 실제로는 부정적인 이미지도 있습니다.
수업시간을 알리는 종, 단 잠을 깨우는 모닝콜, 주말 나들이의 장애 알람 등
위에 나열된 것만 해도 이 알람들을 반기는 분들은 많이 없겠죠.
알람은 왜 부정적인 이미지를 갖게 됐는가?
앞에서 ‘알람은 어떤 일을 하기 위한 타이밍이다’ 라고 했는데 앞에 전제가 하나 필요합니다.
‘지금 하고 있는 일을 중단하고’
물론 단순히 새로운 일을 하기 보단 시간 인지를 위해서 알람을 걸기도 합니다.
그럼에도 알람 때문에 진행 중인 일에 흐름이 끊길 순 있습니다.
위에 전제처럼 중단점을 설정하면 온전히 앞에 일에 몰두할 수 있습니다.
이건 알람의 좋은 점이지요.
그럼에도 불구하고 부정적인 이미지는 하고 있던 일이 중단됨에 따라 그 시간의 무한한 가치와 고유성이 깨졌기 때문이 아닐까요?
오늘의 점심과 내일의 점심이 다르고, 오늘의 단 꿈을 내일 다시 꿀 수 없고,
가족과의 나들이를 내년에 또 간다 한 들 같지 않을 것입니다.

신생아의 경우 유일한 의사표현 방식은 울음입니다.

언어를 모르고 손발이 자유롭지 않기 때문에 의사소통이랄게 없습니다.
그나마 다행인건 태생적으로 생존에 대한 알람이 걸려있어요.

  • 배고플 때
  • 졸릴 때
  • output

주로 이렇게 3가지입니다.

따라서 알람이 울리면(아기가 울면)

  • 배고플 때 => 입 주변을 두드려 배고픈지 확인
  • 졸릴 때 => 재웁니다.
  • output => 기저기를 확인

각각의 상황에 대한 대응 방법이 정해져 있습니다.

아쉬운건 알람이 울음 하나 밖에 없어요. 따라서 초반엔 아기가 울면 3가지 대응 방법을 모두 시도합니다.
불편해 보이지만 케이스가 3개라 할만 합니다.
익숙지해지면 아기 울음도 상황에 따라 다르다는 것도 알게 됩니다.
그럼 아기보는건 크게 어렵지 않네요 라고 할 수 있지만 문제는 이렇게 3가지 다 정상인 상황인데 계속 알람이 울리면 난감합니다.
애가 우는데 왜 우는지 모르겠어. 문제가 있는거 같은데 어떤 문제인지 모르겠어 가 됩니다.
아기는 점점 커 나가면서 하고 싶은 것이 많아지고 변화도 생깁니다.
유치가 나면서 이앓이에 울기도 하고
누워만 있으니 답답해서 울기도 하고
좀 크면 output에도 전혀 울지 않기도 합니다.
따라서 알람에 대한 대응은 지속적으로 변화해야 되며 관심이 필요합니다.
아기의 알람의 목적은 아기의 상태를 안정적으로 유지하고 건강을 지키기 위함입니다.
만약 아기가 위의 3가지 증상이 있어도 울지 않는다면 어떻게 될까요?
배고파도 가만히 있고 output에도 울지 않는다면?
부모는 주기적으로 계속 배고픈지 분유를 먹여보고, 기저귀를 확인해볼 수 밖에 없습니다.
그렇지 않다면 아기는 영양이 부족할 수도 있고 건강에 문제가 생길겁니다.

데이터베이스의 알람도 다르지 않습니다.

데이터베이스가 안정적으로 동작할 수 있도록 유지하는게 목적입니다.
데이터베이스에 알람이 발생하면 아래와 같은 프로세스로 대응합니다.

  • CPU, Latency 등 부하 => 메트릭 확인 -> 서비스가 가능한 상태인지 확인 -> 슬로쿼리, DDL 등 원인 파악 -> 스케일 아웃 또는 튜닝
  • Failover 등 인스턴스 이상 => 서비스가 가능한 상태인지 확인 -> 에러, 이벤트 로그 확인 -> 주요 메트릭 확인 ->  장비 업체 확인

서비스를 안정적으로 운영하는데 이러한 인프라 알람만 필요할까요?
서비스 장애를 데이터베이스 같은 인프라에서 먼저 아는 경우가 있고
고객센터 또는 외부에서 서비스 장애에 대한 소식을 받고 인프라를 확인하는 경우도 있습니다.
문제가 있는데 우리가 알람을 받지 않는다면 서비스가 정상인지 주기적으로 확인하는 방법 밖에 없고
이러한 방식은 큰 장애가 나기 전엔 알기 쉽지 않습니다.
안정적인 서비스를 위한 알람은 논리적(서비스 관점)인 알람과 물리적(인프라 관점) 알람이 모두 필요합니다.

우아한형제들 데이터베이스 알람 시스템 우아한형제들 데이터베이스 알람 시스템


알람은 단순히 문제의 인식을 떠나 생활의 편리함도 목적입니다.
아기가 몇시간 동안 울지 않고 잘 지낸다면 지금 모든 상황이 만족스러운 겁니다.
알람이 설정되어 있는데 밤새 울리지 않았다면 그건 밤새 데이터베이스가 안정적이었다는 증거입니다.
그럼에도 데이터베이스에 문제가 있었다면 누락된 메트릭이 있는지 알람 임계치가 적절히 설정 되어 있는지 찾아봐야 됩니다.
알람은 이처럼 신뢰의 수단이 될 수도 있습니다.

그럼에도 불구하고 알람에 대한 부정적인 이미지가 있다면 알람이 정확한가를 따져봐야 됩니다.
아침 8시에 일어나야 되는데 알람을 잘못 설정하여 7시에 알람이 울렸다면 1시간이나 더 잘 수 있는데 아침 컨디션을 망칠 수 있죠.
반대로 9시에 알람을 설정해서 지각을 했다면?
흔하게 양치기 소년의 거짓말이 있습니다.
잘못된 알람이 계속되면 알람을 믿지 않아 정말 중요한 알람이 왔을때 무시하게 되는거죠.
저희도 알람이 아주 정교하진 않습니다.
문제가 있는데도 알람을 전혀 받지 못하는 경우도 있고 낮은 임계치가 설정되어 너무 자주 오는 경우도 있습니다.
그때그때 확인하면서 조정을 하곤 있지만 쉽진 않습니다.
특히 불필요한 알람을 계속 받는다면 정리도 필요합니다.
알람은 다음 할 일을 알려주는 기준점이기 때문에 알람을 받고도 아무런 액션을 할 수 없다면 사실 상 그 알람은 제거하던지 보완점을 찾아야 됩니다.
알람 시스템이 잘 구축 되어 있더라도 알람을 받고 아무런 액션을 취하지 않는다면 피로도는 쌓이고 알람 시스템에 대한 신뢰도가 떨어지게 됩니다.
무의미하게 반복되는 알람에 지쳐 알람을 꺼두기도 합니다. 이런 경우 정작 중요한 알람을 놓치는 일도 생깁니다.
알람에 대한 문제를 인지했고 해결하는 스케쥴과 작업 내용이 잡혔다면 그 스케쥴까진 알람을 빼도 됩니다.

이렇게 알람에 대한 관리도 어렵고 중요하다 보니 최근에는 기계학습을 통한 이상 탐지 알람들이 나왔습니다.

AWS 환경에서는 Anomaly detection 이라는 알람을 사용할 수 있습니다. Using CloudWatch Anomaly Detection
메트릭에 대한 범위를 정해주면 시간의 흐름에 따라 패턴을 인지하고 그 패턴의 범위를 벗어날 경우 이상 증상이라 판단하고 알람을 보내줍니다.
서비스의 트래픽이 증가하면 증가하는데로 임계치가 같이 변동하기 때문에 이상적일 수 있습니다.
다만 이러한 이상 탐지 알람들도 완벽하진 않고 오류를 내재하고 있습니다. 정상과 비정상의 사이는 비정상일까요?
아래의 그래프는 10/31 전후 일주일 간의 특정 DB 인스턴스 CPU 사용률과 Anomaly detection 밴드 지표입니다.
Anomaly detection
10/31 트래픽이 급증하였고 DB 인스턴스에도 부하가 심해 스케일아웃을 실시하였습니다.
트래픽 급증으로 인하여 CPU 사용률이 평소 패턴보다 늘었고 이를 이상 탐지하였습니다.
그러나 스케일 아웃을 실시하면서 인스턴스 당 트래픽이 줄었고 CPU 사용률은 평소대로 급하락 하였습니다.
이렇게 하락한 상태는 다른 날짜의 지표와 큰 차이가 없지만 앞서 급상승한 지표를 학습하여 밴드에 반영함으로써 Anomaly detection 밴드는 하락한 CPU 사용률을 비정상으로 판단하였습니다.
이와 같이 Anomaly detection 탐지도 오탐이 발생할 소지가 있습니다. (특정 기간을 학습에서 제외하여 모델을 조정할 순 있습니다)
어느 것이 정답이라는건 없고 여러 알람 설정들을 상황에 맞게 사용해야 됩니다.

알람은 이처럼 우리가 편하게 살기 위한 수단이지, 스트레스를 받기 위한 도구가 아닙니다.

저희는 지속적으로 알람 환경을 개선하고자 노력하고 있습니다.
알람 설정 및 임계치 조정을 자동화 하려고 개발하고 있고 새로운 알람 메트릭 및 탐지 기능을 꾸준히 테스트 하고 있습니다.
알람 자체가 문제의 해결책이 아닙니다. 알람을 통해 증상을 확인했으면 그에 대한 대응을 해야 알람의 목적이 이루어집니다.
알람은 서비스의 신뢰와 안정을 위해 또 인프라 담당자들의 편의를 위한 중요한 도구입니다.