사용한 기술: spring batch, rds(mysql)
특정 범위의 사용자 대상으로 알림톡을 보내는 일을 했다.
두 가지 알림톡 기능을 만들었다.
첫째, 서비스를 가장 처음으로 시작하는 사용자에게 알림톡을 만드는 기능이다.
둘째, 특정 서비스를 시작하는 사용자에게 알림톡을 만드는 기능이다.
배치를 사용해서 알림톡을 만들었다.
배치는 다음과 같이 동작한다.
1. 1차으로 당일 서비스를 시작하는 사용자들을 추린다.
2. (최초 서비스 시작인 경우) 사용자들이 정말로 최초 서비스 시작일인지 검사한다.
3. 2에서 추린 사용자들 대상으로 전화번호가 무엇인지 타팀 API로 조회한다.
4. 2에서 추린 사용자들에게 알림톡으로 보낸다.
1이 하나의 스텝이고, (2,3,4)가 하나의 스텝이어서 총 2개의 스텝이 있다.
당일 서비스를 시작하는 사용자를 추리고, 사용자들이 정말로 최초 서비스 시작일인지 검사하려면 쿼리 메서드를 새로 만들어야 했다.
쿼리를 만들고, 운영에서 몇 초가 나오는지 검사했다.
쿼리를 운영에서 실행해 보니 13초로 매우 길게 나왔다.
운영 배치에서 쓸 수 없을 정도의 쿼리라서, 최적화 작업이 필요했다.
인덱스를 추가하기로 결정했다.
인덱스를 추가함에 따라 다른 쿼리들이 영향받는지를 알기 위해, 운영 API/배치에서 쓰는 모든 쿼리들의 실행계획을 검사해야 했다.
시간이 오래 걸리는 작업이었다.
모든 쿼리를 검사하고, 기존 쿼리에 영향을 주지 않고 새로운 쿼리에만 영향을 준다는 것을 확인했다.
인덱스를 추가하기로 최종 결정하려는 순간, 결정을 번복했다. 그 이유는 다음과 같다.
이전에 새로운 쿼리를 운영에서 테스트했을 때 13초가 걸렸다.
그래서 인덱스를 만들기로 결정했다.
당시 새로운 쿼리를 운영에서 테스트했을 때, 파라미터를 테스트 파라미터로 주었다. LIMIT을 1로 했다.
운영 배치에서는 LIMIT 500으로 실행하도록 코드를 만들었다.
LIMIT 500으로 한 실행 계획과, LIMIT 1로 실행한 실행 계획이 달랐다.
실제 운영 파라미터인 LIMIT 500으로 실행한 결과, 쿼리 시간이 0.2초 정도로 매우 빠르게 나왔다.
실제 배치는 운영 파라미터 기준으로 동작하고, 운영 파라미터 기준으로 새로운 쿼리 시간은 매우 빨라서, 인덱스를 추가하지 않아도 문제 없다.
인덱스를 추가하지 않기로 결정했다.
배포했다.
스케줄한 아침에 알림톡이 정상적으로 발송되는 것을 확인했다.
쿼리 메서드를 추가하는 과정을 미리 기억한다.
(1) 쿼리 메서드를 추가한다
(2) 쿼리를 운영에서 직접 실행해본다
(3) 쿼리 실행 시간을 측정한다
(4) 쿼리가 느리다면 인덱스 추가를 고려한다
(5) (인덱스를 추가한다면) 기존 쿼리들 실행 계획에 문제 없는지 전수 검사한다.
쿼리 메서드를 테스트할 때, 운영 파라미터 기준으로 테스트한다.
베타 테스트는 빠를수록 좋다.
베타 테스트 때 실제 요구사항이 이해한 버전과 다름을 파악했다.