하루 한 번 도는 cron 배치의 실행 시각을 정해야 했고 새벽 네 시로 하려고 생각하고 있었다. 그 시간이 한가할 것이라는 짐작 말고는 근거가 없었는데 실측으로 정하라는 지시를 받았다.
Table of contents
Open Table of contents
선택지 — 새벽 네 시라는 첫 안
새벽이 한가하다는 것은 사람이 안 쓰는 시간이라는 뜻이지 서버가 한가하다는 뜻이 아니었다. 사람이 안 쓰는 시간이라서 오히려 다른 작업들이 그 시간에 몰릴 수 있다.
이 구분을 하고 나니 짐작으로 고를 일이 아니라는 것이 분명해졌다. 실제로 어느 시간대에 부하가 걸리는지는 지표를 뽑아 보면 나오는 것이었다.
시간대별 부하 집계
운영 DB 에 쿼리를 날린 것이 아니라 모니터링 지표를 썼다. 평균 활성 세션을 period 3600 으로 7일치 뽑아 시각대별로 AVG() 와 MAX() 를 냈고 읽기 전용 지표라 DB 에 부담이 없었다.
결과가 이랬다.
시각 평균 최대
────────────────────
03 7.2 22.1
04 9.8 31.4
05 10.1 28.7
06 7.9 19.3
13 14.78 65.79 ← 최고
08 4.13 9.20 ← 최저
00 4.23 7.54
23 4.41 11.02
07 4.84 13.60
01 6.10 17.50
시간대마다 값이 뚜렷하게 갈렸고 밋밋한 분포가 아니었다.
통념과 반대로 나왔다
새벽 36시가 710 으로 높은 축이었고 야간에 도는 다른 cron 배치들이 그 시간에 몰려 있었다. 처음 생각했던 4시는 평균 9.8 에 최대 31.4 로 하필 그 봉우리 근처였다.
가장 높은 것은 13시의 14.78 이라 예상과 맞았지만 두 번째로 높은 곳이 새벽이라는 것은 예상 밖이었고 가장 낮은 것은 8시의 4.13 이었다. 통념으로 골랐으면 붐비는 자리에 하나를 더 얹을 뻔했다.
최저값만 보지 않는 이유
가장 낮은 시간대를 그냥 고르지는 않았는데 그 시간대의 앞뒤를 함께 봐야 했기 때문이다. 배치가 한 시간 넘게 돌면 시작 시각이 아니라 도는 구간 전체가 겹치는 자리가 된다.
AVG() 만이 아니라 MAX() 도 함께 봤는데 0시는 4.23 에 7.54 이고 23시는 4.41 에 11.02 로 AVG() 가 비슷해도 MAX() 가 갈렸다. AVG() 가 낮아도 순간적으로 튀는 시간대는 배치가 겹쳤을 때 위험한 자리였다.
컷오프 요건과 남은 후보
여기에 업무상 요건이 하나 있었는데 특정 시각까지는 결과가 나와 있어야 한다는 것이었다. 이 요건이 늦은 시간대 후보를 전부 잘라 냈다.
부하로 좁힌 후보와 요건으로 좁힌 후보를 겹쳐 보니 남는 것이 하나였다. 결정 자체보다 재현 가능한 근거가 남았다는 것이 이 작업의 소득이었다.
정리
- 배치 시각을 통념이 아니라 실측으로 정한다
- 사람이 안 쓰는 시간과 서버가 한가한 시간은 다르다
- 새벽에는 야간 배치가 몰린다
- 부하 지표
SELECT는 읽기 전용이라 부담이 없다 - 최저값만 보지 않고 그 시간대의 앞뒤를 본다
AVG()와MAX()를 함께 본다- 업무 요건이 후보를 잘라 낸다
- 결정에 재현 가능한 근거가 남는다