개요
MSA 예약 관리 프로젝트에서 예약 관리 서비스를 개발하게 되었다.
예약 관리 서비스는 Kafka를 사용해 비동기 처리를 하도록 할 예정이다.
서비스의 동시성 제어와 데이터 일관성을 유지하기 위한 방법에 대해 알아보고 어떤 방식을 적용할 지 고려해 볼 것이다.
사용 기술 및 라이브러리
- Kafka - 이벤트 기반 비동기 처리
- Redis - Redisson 라이브러리 사용 분산락(동시성 제어)\
동시성 제어 시점
- Kafka Consumer에서 메시지를 처리할 때 lock 적용
- 예약 서비스에서 예약 생성 시 lock 적용
각 방식의 차이
- Consumer에서 Lock 사용
- 동작
- Consumer가 메시지 처리할 때 리소스에 대해 락 획득
- 락 획득 후 예약 생성 요청을 처리
- 메시지 처리 중 Consumer 또는 프로세스가 동일 리소스에 접근 못하게 제어
- 장점
- 단순 동시성 제어 - 로직이 비교적 단순
- 초기 설계 용이 - 서비스 계층의 복잡성을 줄일 수 있음
- 단점
- 확장성 - 컨슈머 인스턴스가 증가해도 성능 이점이 제한적
- 비효율 - 모든 메시지에 대해 락을 시도해 성능 저하
- 높은 대기 시간 - 메시지가 대기열에 있는 동안 처리 속도가 락 타임아웃에 의해 제한됨
- 동작
- 예약 생성 단계에서 Lock 사용
- 동작
- 예약 생성 로직 실행 시 동일 가게 ID에 대한 분산 락 획득
- 락 획득 상태에서 예약 생성 작업 진행
- 예약 생성이 완료되면 락 해제
- 장점
- 세분화 된 락 적용: 특정 가게에 대해서만 동시성을 제어해 불필요한 락 사용을 방지
- 확장성 우수: 컨슈머 처리 속도는 락에 의존하지 않아 시스템 확장성이 더 높음
- 효율적인 동시성 제어: 락 충돌을 최소화 할 수 있음
- 단점
- 복잡성: 서비스 계층에 락 처리 로직이 추가되 복잡해질 수 있음
- 잠재적 경합: 가게당 트래픽이 매우 높은 경우 락 충돌 가능성 증가
- 동작
결론
- 예약 생성 단계에서 Lock을 생성해서 동시성 제어
- 메시지 단에서는 다른 가게에 대한 요청도 같이 들어오기 때문에 메시지에 락을 걸면 성능이 너무 떨어질 것으로 예상 됨
- 예약 수정 시 충돌이 발생하지 않도록 서비스 단에서 락을 걸어야 될 것으로 판단
고려해야 될 점
- 락 충돌 가능성을 어떻게 줄일 것인가
- 예약 수정과 예약 생성이 서로 충돌될 수 있는데 이 문제를 어떤 식으로 해결하는 게 좋을까
데이터 수정(예약) 시 데이터 일관성 유지
- 예약이 생성되는 시점에는 Lock을 사용하기 때문에 데이터의 일관성을 유지할 수 있음
- 예약 수정(취소, 삭제 포함) 시 예약 생성과 데이터 충돌을 방지하고 데이터의 일관성을 유지해야 함
방법
- 예약 별로 락을 세분화
- 생성 시 가게 단위로 락을 적용
- 예) reservation-lock-{storeId} key 사용
- 수정(삭제 포함) 시에는 예약 ID 단위로 락을 적용
- 예) reservation-lock-{reservationId} key 사용
- 생성 시 가게 단위로 락을 적용
- 데이터 충돌 방지 설계
- 동시성 제어 범위 최소화
- 락 범위를 줄여 성능에 미치는 영향을 최소화
- Optimistic Locking 사용
- DB에서 낙관적 락을 사용해 마지막 수정 시점 기반으로 데이터 충돌 방지
- Version 어노테이션 필드 사용
- 데이터 수정 시, version 필드 값을 확인해서 다르면 수정 실패 처리
- DB에서 낙관적 락을 사용해 마지막 수정 시점 기반으로 데이터 충돌 방지
- 동시성 제어 범위 최소화
- 비즈니스 로직 재검증
- 수정 작업 중 예약이 새로 생성된 경우 재검증 로직을 추가해 일관성 유지
- 예약이 수정 가능한 상태인지 확인.
- 수정 작업 중 예약이 새로 생성된 경우 재검증 로직을 추가해 일관성 유지
- API 동작 분리
- 예약 생성 및 예약 수정 API 명확히 분리
- 고려해야 될 잠재적 문제
- 락 경합: 락을 너무 오래 점유하지 않도록 로직 최적화 및 TTL 조정
- 비효율적 락 사용: 락이 많은 곳에 사용되면 성능에 부정적 영향이 있음
결론
- 데이터 생성 - StoreId 기반 락 적용
- 데이터 수정(삭제 포함) - ReservationId 기반 락 적용
- DB 단에서 버전 어노테이션을 사용해 수정 시 일관성 보장
정리
- MSA 프로젝트와 Kafka 이벤트 기반의 비동기 처리를 위해 고려해야 될 사항이 상당히 많고 복잡하다는 것을 깨달았다.
- 동시성 제어와 데이터 일관성 유지를 위해 상당히 많은 점을 고려하고 코드를 구현할 필요성을 느꼈다.
'자바 심화 > TIL' 카테고리의 다른 글
Kafka - 비동기 처리 (1) | 2024.12.31 |
---|---|
Redis - Redisson (2) | 2024.12.27 |
DB Lock (1) | 2024.12.26 |
장애 대응 (1) | 2024.12.24 |
시큐어 코딩(Secure Coding) (0) | 2024.12.23 |