Q. 인상깊었던 주제는 무엇이었나요?

분산락과 캐시 전략중 어떤 주제가 더 인상깊었나요?

항해를 하기전 레디스를 사용해왔을때는 JWT 토큰정도로만 해왔습니다. Key value 기반 NoSQL 데이터베이스인 레디스가 단순히 캐싱의 역할을 하지 않고 Lock으로서의 역할을 할 수 있다는걸 이번과제를 통해 새로알게됐습니다. 또한 읽기와 쓰기에서의 캐싱전략이 여러가지가 있다는걸 처음알게됐습니다.

해당 개념을 통해 어떤 구조적/성능적 문제 해결을 가능성을 느꼈나요?

아직까지는 과제를 수행해보면서 어느점이 문제인지, 그에 대한 해결은 무엇인지에 대한 답변이 명확하지 않았습니다. 그래도 떠오르는 한가지는 캐싱쪽에서는 트랜잭션을 접근하기전에 캐시저장소(redis)에서 캐시히트가되면 빠른 응답을 해줄 수 있다는 점입니다.

Q. Race condition, Deadlock, Cache Stampede 등 방어할 포인트는 어떻게 설계하나요?

  • Race condition & Deadlock

분산락을 도입하기전에 동시에 좌석예약을 할경우에는 낙관적락을 사용하여 빠른 실패를 나타내어 해결을했습니다. 그러므로 낙관적락은 논리적락으로써 Race condition, DeadLock 문제는 자연스레 해결이 됐습니다.

포인트 충전/사용 의 경우에는 배타락을 사용하였습니다. 동시요청이 들어와도 포인트라는 공유자원에 대한 데이터의 정합성을 우선으로 하였기때문에 비관적락이자 물리적락인 x-lock을 사용했습니다. 유저포인트라는 공유자원을 동시에 요청할때 락을 획득하지 않은 다른 트랜잭션들은 읽기/쓰기 접근을 하지못하도록 막습니다.

솔직히 기존의 락으로도 Race condition이나 dead-lock을 막을 수 있다고 생각합니다.

  • Cache stampede

이에 대한 방어포인트는 데이터의 변경이 자주 일어나는지? 데이터의 변경이 드문지를 파악해야될거 같다고 생각합니다.

Q. 여러 캐싱방식과 락 구현방법중 어떤것을 왜 선택했는지 설명해주세요.

  • 분산락 구현 계획과 그이유
사용 기능사용 분산락사유TTL
좌석 임시예약심플락재시도횟수가 필요없으며, 동일한좌석에 대해 동시접근할때 1명을 제외한 나머지는 빠른실패를 비롯한 즉각적인 응답을 나타내야하기때문입니다.5분
포인트 사용 & 충전스핀락포인트(공유자원)에 대한 접근을 배타락으로 보호하여 동시요청이 오더라도 데이터정합성을 지키기위해서 동시에 충전/사용이 처리가 됩니다. 동시에 접근을 차단해주며, 다시 시도하여 순차적으로 처리하여 데이터의 정합성까지 지키기위해서 스핀락을 사용하기로 했습니다. 락을 점유할 수 있는 최대시간은 5초이며, 락 획득을 위해 다른 스레드가 기다릴 수 있는 최대시간은 5초입니다. 락을 얻기위해 다시 시도를 하기위한 시간은 100ms 로 설정했습니다.5초
  • 캐싱방식 구현 계획과 그이유
사용 기능선택전략사유TTL
콘서트목록읽기전략현재를 기준으로 예약가능한 목록리스트를 불러오기위함입니다.60분
콘서트일정 목록읽기전략현재를 기준으로 예약가능한 콘서트 일정목록을 나타내며 concertSeat, concert테이블을 조인하기때문입니다.30분
콘서트좌석목록읽기전략좌석상태(예약확정, 임시예약, 예약가능)를 확인하기 위함입니다. 상시변경가능성이 높기때문에 TTL고려가 필요5분
토큰발급쓰기전략토큰상태 상관없이 토큰의 유효시간은 5분이기때문에 토큰의 유효성을 나타내기위함입니다5분
좌석 임시예약쓰기전략좌석상태가 변경되기때문에 캐시저장소와 데이터베이스에 저장된 데이터가 일치하도록 정합성을 지켜야합니다. 예를들어 데이터의 정합성이 어긋나버리면 좌석이 이미 임시예약상태인데 클라이언트입장에서는 예약가능하다고하면 UX상에서도 불편함을 초래할 수 있기때문입니다.5분
좌석 임시예약 취소쓰기 전략임시예약의 유효시간(5분)이 지났기때문에 스케줄러에 의해 취소처리가됩니다. 취소처리된 좌석은 다시 예약가능한상태이므로, 데이터의 정합성을 위해서 캐시저장소와 데이터베이스에서도 즉시 반영을 해야합니다.5분

Q. 구현중 어려웠던 점과 고민했던 선택지는 무엇이었나요?

이번과제의 아무래도 분산락과 캐싱전략에 대한 이해. 즉 과제의 요구사항를 이해하는것이 어려웠던것같습니다. 제겐 처음인거 같았고 낯설었습니다. 익숙해지는데 시간이 많이 필요했습니다.

콘서트시나리오에서는 어느기능에서 어떤 분산락을 써야될지, 어느기능에서 캐싱이 필요한지를 파악하는 것과 각 분산락 기법과 각 캐싱전략에 대한 이해가 필요했습니다. 분산락과 캐싱과의 관계가 있는지 모르는게 투성이었습니다.

임시예약과 예약취소는 좌석의 상태를 변경이 일어나므로, write-through를 전략으로 콘서트좌석목록을 캐싱하는 방안으로 했습니다. 콘서트좌석목록은 데이터의 변경이 자주일어나서 데이터의 정합성을 지키는게 우선이라고 생각했습니다. write-through 전략의 이론처럼 캐시저장소와 데이터베이스의 동기화시켜 데이터의 정합성을 지키는 쪽으로 구현했습니다.

Q. 이번주차를 통해 얻은 인사이트는 무엇이었나요?

이번주차를 통해 얻은 인사이트와 다음에 적용할 포인트가 무엇이며, 이번학습을 통해서 성능/동시성 에 대한 어떤 관점이 생겼을까요?

제가 얻은 인사이트는

  • 첫번째로는 분산락은 트랜잭션보다 먼저 수행되어야하며, 트랜잭션이 종료후에 락을 해제하므로 트랜잭션보다 나중에 끝난다.
    • 락획득 -> 트랜잭션시작 -> 수행 -> 트랜잭션종료 -> 락해제
  • 분산락은 방어선 역할일뿐, 기존의 RDBMS의 비관적락과 논리락인 낙관적락 등의 대체제는 아니다.
  • 캐싱에는 읽기 전략만 있는게 아니라 쓰기전략도 존재하며, 쓰기전략에는

앞으로 실무프로젝트나 이후 과제에서 “이 전략을 사용해보고싶다” 포인트가 있을까요?

  • 기존의 락으로 해결하기 어렵고, 분산락만이 해결될 수 있는 상황은 어떤 상황인지에 대해 나만의 언어로 정리해보고 싶습니다.

  • 프로젝트라기보다는 이 주제에 대해서 조금더 부딪혀보고 조금이라도 더 이해해보고 싶다는 생각이 들었습니다.

  • 왜 락획득을 트랜잭션접근 이전에 해야될까? 이 순서가 지켜지지 않을때 왜 데이터의 정합성이 깨져버릴까? 에 대한 구체적인 예시를 근거로 만들어내서 나만의 언어로 정리해보고싶습니다.

  • 이번주차에 연관된 기술이론을 바탕으로 주먹구구식으로 과제에 접목해서 임해왔지만, 성능적인 측면을 개선해보는 조금 더 나아가서 생각해보고 깊게 고민해보고 싶습니다.

  • 캐싱전략들중 여러개의 전략들이 있는데 직접 구현해보고 그 차이점이 무엇인지 나만의 언어로 정리해보고싶습니다.