전글과 전전글을 보고 오시면, 이해하기 더 수월합니다.
갑자기 슬랙 알림이 미친듯이 오더니, 서버 메모리는 터져서 다운 직전이고
내 API 요청의 응답시간은 10초를 넘어간다고 생각해보자.
그리고 모든 사람이 담당자인 나를 찾는다.
당신은 무슨일 부터 시작할 것인가?
답을 상상하며, 아래 케이스를 같이 보자.
현재 상황은 트래픽이 갑자기 솟구치는 상황입니다.
(엄청나게 많은 유저가 한번에 콘서트 좌석 예약을 시도하는 상황)
비관락은 전글에서 보았듯이, 성능이 뚜렷하게 낮으므로, 낙관락과 분산락을 중점적으로 비교해보겠습니다.
한참 성능 테스트를 하며 결과를 받을 때 한계에 도달했습니다.
바로 어디서 병목이 일어나는지 확인이 불가능했기 때문입니다.
API의 요청 응답 시간만 주구장창 확인하며 실험을 계속 진행하기보다 실제로 각 요청에 얼마나 많은 시간이 소모되는지 확인하고자 하여, APM을 설정했습니다.
세가지 APM이 후보였습니다.
결론적으로는 OpenTelemetry + jaeger 조합을 사용했습니다.
opentelemetry-spring-boot-starter
를 사용했습니다.
큰 설정없이 굉장히 많은 종류의 인프라를 알아서 트레이싱해주는 기능이 있습니다..만
제가 사용하고 있던 Redisson
은 없었습니다.
그래서.. 해당 라이브러리가 아닌 OpenTelementry Java Agent
와 Redisson Instrument
를 사용하면 됐지만, 시간이 너무 많이 소모되어 직접 커스텀 span
을 추가하는 방식으로 퉁쳤습니다.
LockId lockId = new LockId(type + "-" + id);
RLock rLock = redissonClient.getLock(lockId.getValue());
Span span = tracer.spanBuilder("RedissonLockManager.tryLock").startSpan();
Oracle APM과 PinPoint를 제외한 이유
처음엔 Oracle APM을 선택했습니다.
이유는 OCI 기반으로 실행하고 있었기에 현재 인프라와 잘 어울린다고 생각했기 때문입니다.추가적으로 공식 문서만 봐도 짧은 시간안에 APM을 설정하고 값을 확인할 수 있었습니다.
그러나..
무료 버전(Always Free) 임에도 하루에 약 만원 정도가 지불되는 상황에 현실적으로 이용하기 어려웠습니다.
APM 리소스를 생성/삭제하는데에도 큰 시간이 들었고,
다시 생성한 APM 리소스 기반으로 Agent도 재설치 해야했습니다.그래서 모든 Oracle APM 설정을 걷어내고, OpenTelementry 기반으로 바꿨습니다.
이외에 PinPoint는 분명 설정해볼만 했지만, 시간관계상 샘플만 구동해보고 포기했습니다.
먼저 jaeger UI에서 가장 긴 Duration을 갖는 요청의 span을 확인했습니다.
좌석 요청까지도 가지 못하고, 대기자 였는지 확인을 위한 DB 커넥션을 받다가 timeout이 났습니다.
커넥션 풀도 이미 DB에서 미리 설정해놓은 200개를 다 가져가버린 상황이었습니다.
이렇다면, 사실상 분산락/낙관락 비교를 하기 어렵기에 TPS를 낮춰 실험을 해보겠습니다.
9344건의 요청에서 10건정도가 3초 이상의 요청 시간이 걸렸습니다.
11844건의 요청에서 7건정도가 3초 이상 요청 시간이 걸렸습니다.
알고보니, 현재 실험 제약에서 대기열에서 대기자인지 확인하기 위해 먼저 DB 커넥션을 받아오는데, 여기서부터 정확한 실험을 설계하는 것 자체가 불가능합니다.
즉, 여기서 분산락은 성능에 이점 보다는 동시성 제어에만 도움을 주고 있습니다.
대기열을 Redis로 이관하여, 결과를 확인해보겠습니다!