Skip to content
isdnetworks
Go back

실패가 쌓이는데 건마다 대응했다

수집 실패 알림이 하루에 몇 건씩 왔다. 올 때마다 그 장치에 접속해 확인하고 다시 띄웠다.

일주일쯤 그렇게 하다가 처리한 건들을 한자리에 모아 봤다.

Table of contents

Open Table of contents

건마다 보고 있었다

알림이 오면 늘 같은 순서를 밟았다.

알림 → 해당 장치 접속 → 로그 확인 → 재시작 → 정상 확인

건당 10분쯤 걸렸고 하루 서너 건이면 한 시간이다. 장치에 ssh 로 붙어 로그를 보고 다시 띄우는 것까지가 한 건이었다. 그 한 시간이 매일 사라지는데도 각각은 별개의 일로 보였다.

증상이 제각각이라 더 그랬는데 어떤 건은 통신 오류였고 어떤 건은 메모리 부족이었고 어떤 건은 그냥 멈춰 있었다.

한 건씩 보면 그 건의 장치와 그 건의 오류만 보게 된다. 다른 건과 비교할 일이 없으니 공통점이 있는지조차 물어보지 않았다.

목록으로 모으니 패턴이 보였다

일주일치 알림을 표로 만들었다.

날짜        장치   시각    증상
11-07  D012  03:14  통신 오류
11-07  D019  03:16  메모리 부족
11-08  D005  03:12  응답 없음
11-08  D012  03:15  통신 오류
11-09  D023  03:13  응답 없음
...

장치 번호는 제각각인데 시각이 전부 03:12에서 03:18 사이였다. D012D019D005 도 같은 몇 분 안에 몰려 있었다. 증상만 보고 있을 때는 안 보이던 것이 시각을 나란히 놓으니 드러났다.

새로 조사한 것이 하나도 없다는 점이 걸렸는데 이미 가지고 있던 alert_log 를 한 자리에 놓기만 했는데도 새 정보가 나왔다.

원인 — 새벽 백업의 표 잠금

그 시각에 무엇이 도는지 서버의 예약 작업을 봤다.

0 3 * * * /opt/backup/db-backup.sh

db-backup.sh 가 새벽 3시에 돌고 그동안 mysqldump 가 표를 잠근다. 장치가 자료를 보내면 저장이 실패하고 재시도를 하다가 시간이 초과된다.

여기서 장치마다 다른 증상이 나왔다. 재시도하며 쌓아 둔 자료로 메모리가 모자란 장치가 있었다. 시간 초과가 통신 오류로 보고된 장치도 있었고 응답을 기다리다 그대로 멈춘 장치도 있었다.

원인은 하나인데 증상이 셋이었던 것이다. 대상이 여럿이면 같은 원인도 각자의 사정에 따라 다른 얼굴로 나온다.

조치 — 표를 잠그지 않는 백업

백업이 표를 잠그지 않게 옵션을 붙였다.

mysqldump --single-transaction shopdb > dump.sql

--single-transaction 은 트랜잭션 안에서 일관된 시점을 읽으므로 표를 잠그지 않는다. 다만 이 옵션은 저장 엔진이 트랜잭션을 지원할 때만 뜻이 있다.

그래서 엔진을 먼저 확인했다.

SELECT table_name, engine FROM information_schema.TABLES
WHERE table_schema='shopdb' AND engine != 'InnoDB';

information_schema.TABLES 를 뒤져 보니 두 표가 다른 엔진이었다. 그 둘은 백업을 따로 돌리게 나눴다.

이렇게 고치고 나니 알림이 하루 0~1건으로 줄어서 한 시간씩 쓰던 대응이 거의 사라졌다.

검증 — 남은 알림을 대상 기준으로

남은 알림도 같은 방법으로 모아 봤다. 이번에는 시각에 규칙이 없었다.

장치   건수
D012     8
D019     6
D005     2
나머지    각 0~1

대신 특정 장치에 몰려 있었다. D012D019 를 확인해 보니 같은 현장에 있는 장치였고 그 현장의 망이 불안정했다.

시간으로 안 보이면 device_id 를 축으로 놓고 다시 센다. 같은 자료라도 어느 축으로 모으느냐에 따라 보이는 것이 달라졌다.

집계를 자동으로 만들었다

매번 손으로 표를 만드는 것이 번거로워 조회로 만들어 뒀다.

SELECT DATE(reg_date) AS d, HOUR(reg_date) AS h, COUNT(*)
FROM alert_log WHERE reg_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY d, h ORDER BY d, h;

HOUR(reg_date) 로 잘라 GROUP BY 하면 시간대별 분포가 나온다. 대상 쪽은 묶는 열만 바꾸면 된다.

SELECT device_id, COUNT(*) FROM alert_log
WHERE reg_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY device_id ORDER BY COUNT(*) DESC LIMIT 10;

device_id 로 묶고 건수 내림차순으로 열을 뽑았다. 두 조회를 주간 보고에 넣어 두니 몰리는 자리가 있으면 바로 눈에 띈다.

즉시 대응과 원인 조사를 나눴다

알림이 오면 즉시 대응은 어차피 해야 한다. 다만 그것으로 끝나지 않게 자리를 나눴다.

즉시 대응   재시작하고 서비스 복구
기록        알림 로그에 남김
주간 조사   목록을 모아 패턴을 본다

즉시 대응만 하면 영원히 그것만 하게 되고 건당 10분이 쌓여도 원인 쪽으로는 한 발짝도 안 간다.

주간 조사가 일정에 들어 있어야 목록을 볼 시간이 생기는데 이번 일도 일주일치를 모아 본 것이 전부였다.

정리


Share this post on:

Previous Post
스택이 다섯 번 바뀐 해
Next Post
과제가 끝날 때 남기는 것