사용한 기술: spring batch, transactional, aws sns
특정 조건의 컨텐츠 메타 데이터를 수정하고, 수정한 컨텐츠들에 대해 이벤트를 발행하는 배치를 만들었다.
스텝은 두 개다.
1. 수정할 컨텐츠 메타 데이터를 외부로부터 가져오는 스텝
2. 컨텐츠를 수정하고, 이벤트를 발행하는 스텝
컨테이너 클래스를 만들어서, 컨테이너 안에 Map 필드를 두었다.
외부 데이터를 Map에 저장했다.
두 번째 스텝은 reader, processor, writer로 구성했다.
reader:
특정 조건에 맞는 컨텐츠를 가져온다.
컨텐츠 db를 조회한다.
기존에 있는 인덱스를 활용할 수 있도록 조건을 만들었다.
processor:
디비 쿼리보다 세분화된 조건으로 필터링한다.
writer:
컨텐츠를 수정하고, 이벤트를 보낸다.
컨텐츠 수정을 모두 커밋한 뒤 이벤트를 보내야 하는 요구사항이 있었다.
배치를 작성하다보니 쉽지 않았다.
writer에 있는 코드는 모두 스텝에서 설정된 하나의 트랜잭션으로 관리했다.
그래서 이벤트 보내는 코드가 writer 안에 있는 이상, 커밋하기 이전에 이벤트가 발송됐다.
따라서 코드를 수정했다.
1. 우선 스텝에 설정한 트랜잭션 매니저를 제거했다. 그리고 컨텐츠 내용을 수정하는 코드는 따로 클래스를 만들어서 옮긴 후, @Transactional 어노테이션을 위에 붙였다. 새로 만든 수정 메서드가 시작할 때 새로운 트랜잭션이 만들어지고, 끝날 때 커밋되는 것을 의도했다.
2. 추가로 새로 생성한 메서드에 조회하는 로직을 추가했다. 메서드에서 수정하는 로직만 있는 경우, 변경 감지 커밋이 동작하지 않았다.
위와 같이 수정한 후, db에 커밋된 후에 이벤트가 발송되는 것을 확인했다.
운영과 비슷한 데이터 환경에서 배치 시간이 얼만큼 걸릴지 측정하고 싶었다.
베타 환경, 로컬 환경 두 곳 중 어디에서 테스트할지 고민했다.
결국 로컬 환경에서 테스트했다.
local에서 이벤트 보내는 기능을 재현하기 위해, local에서 aws 인증 키를 구성하여 aws sns에 직접 발송하도록 했다.
localstack sns로 보낼 수 있었지만, 보다 정확한 시간을 알기 위해 aws sns에 직접 연결했다.
약 11만 개의 데이터에 대해 배치 소요시간은 약 한 시간 반 정도 걸렸다.