프로젝트를 진행하면서 CPU가 새벽에 꺼지는 문제가 발생했었다. 프로젝트 진행 중에 원인이 무엇인지 알아보기는 했지만 단지 CPU 성능이 좋지 않아 트래픽을 견뎌내지 못한 것이라고 판단했지만, 찾아보니 성능을 향상하기 위한 기능이 많아서 관련 기술 찾아본 내용을 정리했다.
찾아보니 위 기술들은 MSA 환경에서 대량 트래픽의 유량 제어를 위해 사용할 수 있는 옵션들이었다.
스케줄러 분산
분산된 환경에서 스케쥴러를 관리하는 방법이 꽤 복잡하고 어려운 것 같다.
상황
Scalling 중이고, Scheduler가있는서버인경우 Multiple Scheduler Instances가발생한다. 이때 고민할 수 있는 2가지는 다음과 같다.
Quartz와같은분산스케줄링프레임워크사용해서여러인스턴스에서의스케줄러실행조정하기
한 번에 하나의 스케쥴러 인스턴스만 실행하게 함
SchedLock으로한번에하나의스케줄러인스턴스만실행되게할수있음
SpringBoot에서 Scheduler에 Lock을 거는 방법
한 번에 하나의 스케줄러 인스턴스만 실행하게 하기
스케줄러 인스턴스 실행 시 공유 자원에 잠금을 획득해 작업을 진행한다. 락이 없는 인스턴스는 대기한다
ShedLock
예약된 작업에 대한 분산 잠금을 제공하는 Spring Boot 라이브러다.
잠금 데이터베이스 테이블과의 조합을 사용해 분산 환경에서 실행되는 애플리케이션의 여러 인스턴스에서 예약된 작업이 한 번만 실행되도록 한다.
예약된 작업 ShedLock에 등록
가용 테이블 확인 : ShedLock이 Lock DB 테이블 사용할 수 있는지 확인
Lock DB 테이블 사용할 수 없는 경우 경고 기록하고 작업 건너뜀
사용할 수 있으면 예약된 작업의 cron 표현식을 기반으로 시간 계산
잠금 획득 시도 : 시간상 실행할 수 있는 예약된 작업인 경우, 테이블에 레코드를 삽입해 예약된 작업에 대한 잠금 획득 시도
삽입 성공 : SchedLock이 잠금 획득 성공
삽입 실패 : ShedLock 잠금 획득 실패, 경고 기록하고 작업 건너뜀
작업 완료: ShedLock은 Lock DB 테이블에서 잠금 레코드 삭제하고 잠금을 해제한다
잠금이 해제되기 전에 잠금을 보유한 응용 프로그램 인스턴스가 다운되면 ShedLock은 지정한 시간 초과 기간 후에 잠금을 해재해 다른 인스턴스가 차단되지 않도록 한다.
개발을 하면서 아직 해결되지 않은 고민이 있었는데, 바로 '데이터 삭제를 어떻게 할 것인가?'였다. 개발을 공부한지 얼마 안되었을 때는 '그냥 DB에 delete 쿼리 날려서 조건에 맞는 레코드 삭제하면 되는거 아닌가?'라고 생각했었다. 하지만 팀 프로젝트를 하거나 실무를 경험했을 때 생각보다 데이터 삭제에는 여러 상황이 얽혀있기 때문에 상황에 맞추어 삭제 방식을 선택해야함을 알게 되었다. 그 중 Soft Delete와 Hard Delete에 대해 공부한 내용이다.
1. Soft Delete란?
데이터베이스에서 데이터를 삭제하지 않고, 사용자 입장에서는 데이터에 접근할 수 없게 하는 방식을 의미한다. 보통 테이블에 is_deleted컬럼을 만들어 boolean값으로 데이터를 사용여부를 결정하는 방식이다. is_delete = 0이면 조회 가능, is_deleted = 1이면 조회 불가능한 것처럼 말이다. 조건 컬럼이 들어가므로 is_deleted의 값을 체크하는 쿼리가 들어가야 한다.