멀티 인스턴스 환경의 데드락 상황에서 분산락 적용기

khan·2026년 6월 2일
post-thumbnail

레디스 스트림을 도입했음에도 왜 p95가 1초이하로 내려가지 않을까?

  • 원인
    - 레디스 스트림 데드락 발생
    - PostgreSQL의 데드락 대응  : 데드락 감지한 트랜잭션 하나를 강제로 실패 (관련글 : https://velog.io/@halo_3735/데드락-victim희생-트랜잭션-선택-알고리즘
  • 원인 !image.png !image.png
    1. 멀티인스턴스구조
      1. 컨슈머 그룹에 의해서 각 인스턴스의 백엔드 서버는 별도의 이벤트를 가져감
      1. 하지만 동일한 내용의 이벤트를 가져가는 것은 컨슈머 그룹이 막을 수 없음
      1. before_update에 들어있는 유저들만 업데이트를 하는 쿼리가 가지고 있는 유저 아이디가 1,2이고
      1. 다른 쿼리가 2,1일때
      - 서로 1과 2를 가지고있는 상태에서
      - 2와 1을 락 걸려고 시도하기 때문에
      - deadlock timeout이 난 것이고
      - 이것때문에 지연 발생

      데드락 해결방법

      1. Row Lock 순서 보장

    • 근데 트랜잭션 1이 userId 1인 행 락을 계속 잡고 있으면, 다른 트랜잭션들을 기아상태가됨

      가. 최대한 빨리 행락을 잡고있는 요소를 없애기
      
      1. `카드 수 증가랑 묶여있는 알림 생성을 별도의 트랜잭션으로 분리`
          1. 하나의 트랜잭션에서 행락을 계속 잡고있기 때문에
              1. `단점`
                  1. lock wait가 발생 
                      1. 동일한 업데이트 형태의 배치 3대가 동시에 돌면 2대는 항상 기다리니까
                          1. 지연
                          2. 다른세션이 lock wait 때문에 db세션을 잡고있다
                              1. 세션 낭비
                                  1. cpu 증가
      
      나. 알림 비동기 처리
      
      1. 트랜잭션 단위로 락을 잡고있기 때문에 같은 트랜잭션에있는 알림처리를 별도의 트랜잭션으로 분리하여 의존성 낮추기
          
          !image.png
          
          - 우선순위 낮다 0.03세션 밖이 안잡아먹어서

      2. ShedLock (분산락)

    1. 하나의 인스턴스만

    2. 단점
      1. ShedLock 잡은 서버가 죽으면 락 만료 전까지 다른 서버도 실행 못 함
      1. 락 TTL 설정
      2. 쿠버네티스 환경에서는 pod로 서버 재시작

      3. 단일 컨슈머

    3. 해당 인스턴스가 죽으면 장애생김

ShedLock (분산락) 어떻게 구현할건데?

계봉 예정작

profile
과학과 컴퓨터를 좋아하는

0개의 댓글