6주차 발표 요약
- 코드 리뷰
- 코드 리뷰 -> 공동 목표 필요, 일관된 방향, 분리된 토픽으로 커밋단위로 리뷰
- countdownlatch
- 동시성 테스트툴
- 사용법(excute and finally-> countDown() 필요)
6주차 발제
- 6주차부터 대용량 트래픽부터는 커리어에 매우 도움이 많이 될것이다.
- 5주차까지는 DB락 제어-> 낙관적락과 비관적락을 사용하는가.
- 낙관적락은 충돌이 많이 발생하지않는경우, 빠른 피드백이 필요한 경우, 실패해도 되는경우
- retry 관련 로직은 application에서 비즈니스 로직에 존재
- 비관적락은 충돌이 많이 발생하는경우, 반드시 성공해야하는 경우
- DB 에서 대기 및 실행, 성능적으로는 확실히 비관적락이 빠름.
- 낙관적락은 충돌이 많이 발생하지않는경우, 빠른 피드백이 필요한 경우, 실패해도 되는경우
- 만약 DB가 여러개
이번주 목표
- DB 트랜잭션 이상의 범위, 분산 환경에서 Lock을 적용할수있는 방법 학습
(DB가 여러개라던지 MSA구조라던지) - 분산락 : DB에 의존하지않는 원자성 보장, 논리적 트랜잭션 구현
REDIS를 사용한 분산락
한번 락 획득후 실행
- try lock -> SETNX-> key값 세팅, 기존 값 존재시 false
- unlock -> DEL -> key값에 대한 값 지움
이를 활용해,
simple lock
락 획득 여부 = redis 에서 key 로 확인 if (락 획득) { try { 로직 실행 } finally { lock 제거 } } else { throw Lock 획득 실패 예외 }
재시도 횟수 = 0 while (true) { 락 획득 여부 = redis 에서 key 로 확인 // SETNX key "1" if (락 획득) { try { 로직 실행 } finally { lock 제거 } break; } else { 재시도 횟수 ++ if (재시도 횟수 == 최대 횟수) throw Lock 획득 실패 예외 시간 지연 ( 대기 ) } }1
2
3
4
5
6
- 단점: retry가 없음
- spin lock
-락 획득 여부 = redis 에서 lock 데이터 에 대한 subscribe 요청 및 획득 시 값 반환 // 특정 시간 동안 Lock 에 대해 구독 if (락 획득) { 로직 실행 } else { // 정해진 시간 내에 Lock 을 획득하지 못한 경우 throw Lock 획득 실패 예외 }1
2
3
4
5
6
- 단점: while true기때문에 불필요한 io많이생김
- pub/sub 등의 방식으로 redis를 활용
-Redis 등을 활용한 외부 Resource 를 통해 불필요한 DB Connection 까지 차단 가능하다. 하지만 관리주체가 DB + Redis 와 같이 늘어남에 따라 다양한 문제 파생으로 이어진다. 또한 Lock 의 관리주체가 다운되면 서비스 전체의 Down 으로 이어질 수 있는 문제가 있다.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- redis가 Lock 획득에 대한 대기열 제공해줌
- 레디스의 락에 대해서는 반드시 하위 양식을 따르자
- 락획득 -> 트랜잭션 시작-> 비즈니스 로직(조회 등등) -> 트랜잭션 종료 -> 락해제
## redis는 구현
- aop로 분산락을 구현해볼것이다.
- 레디스의 락에 대해서는 반드시 하위 양식을 따르자
- 락획득 -> 트랜잭션 시작-> 비즈니스 로직(조회 등등) -> 트랜잭션 종료 -> 락해제
## kafka messaging
- 메시지 큐와 같이 순서 보장이 가능한 장치를 이용해 동시성 이슈 해결가능(순서 대로 처리됨으로 경쟁하지않으니까)
- 반드시 토픽의 key가 같아야지만 동일한 patition로 들어가므로 순서보장됨
## redis에대해서 다시 생각해볼것
하지만 Redis 의 높은 원자성을 활용해 프로세스 처리단위에 대한 동일한 Lock 을
여러 인스턴스에 대해 적용할 수 있으므로 매우 효과적일 수 있고, DB 의 Conection 이나
오래 걸리는 I/O 에 대한 접근 자체를 차단할 수 있으므로 DB 에 가해지는 직접적인 부하를
원천 차단할 수 있으므로 효과적이다.
1 |
|
문제점
- 트랜잭션과 락의 순차보장이 실패해요.
- 충전과 결제가 동시에 수행 가능해요.(getLock({lock-name})) 다름
caching
적은 부하로 API 응답을 빠르게 처리하기 위해 캐싱을 사용
데이터를 임시로 복사해두는 Storage 계층
Server Caching 전략
application level
메모리 캐시- 애플리케이션의 메모리에 데이터를 저장해두고 같은 요청에 대해 데이터를 빠르게 접근해 반환함으로서 API 성능 향상 달성
caching Strategy
- 캐싱 전략이 중요함.
- expiration(사용자 입장에서는 지연발생)(TTL 세팅)
- 캐시 데이터의 유통기한을 두는 방법
- Lifetime 이 지난 캐시 데이터의 경우, 삭제시키고 새로운 데이터를 사용가능하게 함
- Eviction(정책에 따라 명시적으로 캐시지우고, 채움 -> 사용자 입장에서는 지연거의없음)
- 캐시 메모리 확보를 위해 캐시 데이터를 삭제
- 명시적으로 캐시를 삭제시키는 기능
- 특정 데이터가 Stale 해진 경우 ( 상한 경우 ) 기존 캐시를 삭제할 때도 사용
- expiration(사용자 입장에서는 지연발생)(TTL 세팅)
6주차 발제 추가정보
- 애플리케이션 메모리 캐시와 Redis 캐시, 어떤 걸 언제 선택해야 하나요?
- 강의 다시 보기
- testContainer를 통해 redis를 따로 띄워서 test진행하기
- 쿠버네틱스 docker안에서 redis캐시를 두는것을 추천함.
- aws등등을 사용하게되면 네트워크 비용이큼. 정책도 한정됨, 자유도낮음
- 외부시스템(redis) 를 적용하고 테스트를 진행할 때, 주의해야할 것들이 혹시 있을까요?
- 레디스 카프카 사용하는이유?
- Valkey 벌키도