배치를 두 개로 나눠 뒀던 것을 다시 하나로 합쳤다.
Table of contents
Open Table of contents
배경 — 나눈 이유를 먼저 찾았다
원래 하나였는데 나눈 것이었다.
stat_batch.php → stat_collect.php (모으기)
stat_aggregate.php (집계)
stat_collect.php 쪽이 오래 걸려서 집계가 늦어진다는 이유였다. 나눠서 따로 돌리기로 한 것이다.
기록에는 그 이유가 안 적혀 있어서 당시에 만든 사람에게 물어봤다. 이유를 모른 채 합쳤으면 같은 문제가 다시 났을 것이다. 되돌리기 전에 왜 그렇게 했는지부터 찾는 것이 첫 단계였다.
나눈 뒤에 생긴 것
나누고 나니 순서를 맞춰야 했다.
0 2 * * * stat_collect.php
0 3 * * * stat_aggregate.php
cron 시각을 벌려 놓는 것으로 순서를 맞추고 있었다. stat_collect.php 가 3시까지 안 끝나면 stat_aggregate.php 가 빈 값으로 도는데 실제로 그런 날이 있었다.
// 집계 앞에 확인을 넣었다
$cnt = $db->count("SELECT COUNT(*) FROM stat_raw WHERE stat_date = ?", $d);
if ($cnt === 0) {
error_log('모으기가 안 끝났다');
exit(1);
}
stat_raw 를 COUNT(*) 로 보는 확인이 붙고 실패하면 다시 돌리는 것도 필요했다. 실패 처리도 두 벌이 됐다.
나눈 것 때문에 생긴 일이었다. 나누는 것에는 이런 비용이 따라온다.
조건이 달라져 있었다
모으는 것이 왜 오래 걸렸는지 다시 봤다.
SELECT ... FROM orders WHERE reg_date >= ? AND reg_date < ?;
orders 의 reg_date 에 인덱스가 없었다. 그동안 인덱스를 걸어서 40분이 20초가 되어 있었다.
나눌 당시 모으기 40분, 집계 5분
지금 모으기 20초, 집계 5분
나눌 이유가 없어진 것이다.
합치면 하나가 실패할 때 둘 다 안 되는 것을 받아들여야 한다. 지금은 모으기가 실패해도 집계가 빈 값으로 돌거나 확인에 걸리는데 합치면 아예 안 돈다.
합치는 쪽이 오히려 나았다. 빈 값으로 도는 것보다 안 도는 것이 낫기 때문이다.
$db->beginTransaction();
collect($date);
aggregate($date);
$db->commit();
beginTransaction 과 commit 사이에 collect 와 aggregate 를 넣으니 중간에 실패하면 둘 다 되돌아간다.
합치는 것도 새 변경이었다
나눌 때 이유가 안 적혀 있어서 물어봐야 했다. 같은 일이 반복되지 않게 적었다.
통계 배치 통합 (2014-07)
stat_collect.php 와 stat_aggregate.php 를 stat_batch.php 로 합쳤다.
나눴던 이유
모으기가 40분 걸려서 집계가 늦어졌다. (2013-11)
합친 이유
orders.reg_date 인덱스를 건 뒤 모으기가 20초가 됐다. (2014-04)
나눠 두니 순서 확인과 실패 처리가 따로 필요했다.
합치면 한 트랜잭션으로 묶여 중간 실패 시 되돌아간다.
다시 나눌 조건
모으기가 10분을 넘으면 다시 본다.
두 파일은 지웠다. SVN 이력에는 남지만 나중에 찾기 어려워서 합친 stat_batch.php 안에 한 줄만 적었다.
/* 2013-11 ~ 2014-07 동안 stat_collect.php / stat_aggregate.php 로 나뉘어 있었다.
합친 경위는 db/notes/2014-07-stat-batch-merge.md 참고. */
어디를 보면 되는지만 적었다. 경위 전체를 코드에 적으면 읽을 때마다 걸리적거린다.
원래대로 하는 것이라고 가볍게 봤는데 실제로는 새 변경이었다. 순서 확인 코드를 지우고 cron 두 줄을 한 줄로 바꾸고 실패 알림이 두 개에서 하나가 되고 재실행 방법이 달라졌다. 전부 적어 두고 하나씩 확인했다.
정리
- 나눈 것을 합칠 때는 왜 나눴는지 먼저 찾는다. 안 적혀 있으면 물어본다
- 이유를 모르고 합치면 같은 문제가 다시 난다
- 나누면
cron시각으로 순서를 맞추게 되고 실패 처리도 두 벌이 된다 - 조건이 달라졌는지 본다. 나눌 이유가 없어졌을 수 있다
- 합치면 하나가 실패할 때 둘 다 안 된다. 그것이 나은지 따진다
- 왜 나눴고 왜 합쳤는지와 다시 나눌 조건까지 적는다
- 코드에는 어디를 보면 되는지만 적는다. 경위는 따로 둔다
- 원래대로 하는 것도 새 변경이다. 딸린 것을 목록으로 확인한다