본문 바로가기

자바 심화/TIL

동시성 제어 시점과 데이터 일관성 유지 관점

개요

MSA 예약 관리 프로젝트에서 예약 관리 서비스를 개발하게 되었다.

예약 관리 서비스는 Kafka를 사용해 비동기 처리를 하도록 할 예정이다.

서비스의 동시성 제어와 데이터 일관성을 유지하기 위한 방법에 대해 알아보고 어떤 방식을 적용할 지 고려해 볼 것이다.

 

사용 기술 및 라이브러리

  • Kafka - 이벤트 기반 비동기 처리
  • Redis - Redisson 라이브러리 사용 분산락(동시성 제어)\

 

동시성 제어 시점

  1. Kafka Consumer에서 메시지를 처리할 때 lock 적용
  2. 예약 서비스에서 예약 생성 시 lock 적용

각 방식의 차이

  1. Consumer에서 Lock 사용
    • 동작
      1. Consumer가 메시지 처리할 때 리소스에 대해 락 획득
      2. 락 획득 후 예약 생성 요청을 처리
      3. 메시지 처리 중 Consumer 또는 프로세스가 동일 리소스에 접근 못하게 제어
    • 장점
      1. 단순 동시성 제어 - 로직이 비교적 단순
      2. 초기 설계 용이 - 서비스 계층의 복잡성을 줄일 수 있음
    • 단점
      1. 확장성 - 컨슈머 인스턴스가 증가해도 성능 이점이 제한적
      2. 비효율 - 모든 메시지에 대해 락을 시도해 성능 저하
      3. 높은 대기 시간 - 메시지가 대기열에 있는 동안 처리 속도가 락 타임아웃에 의해 제한됨
  2. 예약 생성 단계에서 Lock 사용
    • 동작
      1. 예약 생성 로직 실행 시 동일 가게 ID에 대한 분산 락 획득
      2. 락 획득 상태에서 예약 생성 작업 진행
      3. 예약 생성이 완료되면 락 해제
    • 장점
      1. 세분화 된 락 적용: 특정 가게에 대해서만 동시성을 제어해 불필요한 락 사용을 방지
      2. 확장성 우수: 컨슈머 처리 속도는 락에 의존하지 않아 시스템 확장성이 더 높음
      3. 효율적인 동시성 제어: 락 충돌을 최소화 할 수 있음
    • 단점
      1. 복잡성: 서비스 계층에 락 처리 로직이 추가되 복잡해질 수 있음
      2. 잠재적 경합: 가게당 트래픽이 매우 높은 경우 락 충돌 가능성 증가

결론

  • 예약 생성 단계에서 Lock을 생성해서 동시성 제어
    • 메시지 단에서는 다른 가게에 대한 요청도 같이 들어오기 때문에 메시지에 락을 걸면 성능이 너무 떨어질 것으로 예상 됨
    • 예약 수정 시 충돌이 발생하지 않도록 서비스 단에서 락을 걸어야 될 것으로 판단

고려해야 될 점

  • 락 충돌 가능성을 어떻게 줄일 것인가
  • 예약 수정과 예약 생성이 서로 충돌될 수 있는데 이 문제를 어떤 식으로 해결하는 게 좋을까

 

데이터 수정(예약) 시 데이터 일관성 유지

  • 예약이 생성되는 시점에는 Lock을 사용하기 때문에 데이터의 일관성을 유지할 수 있음
  • 예약 수정(취소, 삭제 포함) 시 예약 생성과 데이터 충돌을 방지하고 데이터의 일관성을 유지해야 함

방법

  • 예약 별로 락을 세분화
    • 생성 시 가게 단위로 락을 적용
      • 예) reservation-lock-{storeId} key 사용
    • 수정(삭제 포함) 시에는 예약 ID 단위로 락을 적용
      • 예) reservation-lock-{reservationId} key 사용
  • 데이터 충돌 방지 설계
    • 동시성 제어 범위 최소화
      • 락 범위를 줄여 성능에 미치는 영향을 최소화
    • Optimistic Locking 사용
      • DB에서 낙관적 락을 사용해 마지막 수정 시점 기반으로 데이터 충돌 방지
        • Version 어노테이션 필드 사용
      • 데이터 수정 시, version 필드 값을 확인해서 다르면 수정 실패 처리
  • 비즈니스 로직 재검증
    • 수정 작업 중 예약이 새로 생성된 경우 재검증 로직을 추가해 일관성 유지
      • 예약이 수정 가능한 상태인지 확인.
  • 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