땅콩은 현재 실시간 보장 기술로 Polling을 사용하고 있는데, 아직 방에서 유저가 웹 브라우저를 종료하여 나갔을 때 유저를 Room에서 내보내는 처리가 되어있지 않은 상황이다.
또 Room이 삭제되는 방식은 Room에서 마지막 유저가 나갔을 때 Room이 함께 삭제되도록 구현해두었는데 위와 같은 웹브라우저 강제 종료 방식으로 방에서 나가게되면 Room 또한 삭제되지 않고 DB에 남아있다.
이러한 문제 해결을 위해 2시간 이상 어떠한 변화도 발생하지 않는 Room에 대해서 Expired 되었다고 판단하는 정책을 세웠고, 팀원에 의해 Expired된 Room에 대한 정보를 모두 delete하고 Room의 Vote 정보를 Total Vote 테이블로 마이그레이션하는 스케쥴러가 구현되었다.
하지만 해당 스케쥴러의 코드를 살펴보니 delete 쿼리가 4N
개 발생하는 형태로 구현되어 있었고
이는 네트워크 왕복 비용을 증가시키고, 한 번만 수행될 수 있는 파싱 및 최적화 과정을 여러번 수행시켜 CPU와 I/O에 불필요한 부하를 줄 것이라고 생각하였다.
이 문제를 해결하기 위해 delete할 데이터를 List로 모아 Batch DELETE
를 통해 한 번에 처리하여 쿼리의 발생 갯수를 4N
→ 4
로 줄여보고자 하였다.
@Transactional
public void deleteRoomBefore(LocalDateTime modifiedAt) {
roomService.findRoomsBefore(modifiedAt)
.stream()
.forEach(this::delete);
}
private void delete(Room room) {
roomBalanceVoteMigrator.migrateToTotalVote(room);
roomContentService.deleteRoomContents(room);
memberService.deleteMember(room);
roomService.delete(room);
}
Expired Room의 데이터를 Room 별로 각각 deleteAllInBatch() 수행