Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] 낙관락 vs 비관락 성능 비교 #192

Closed
lokigem opened this issue Aug 31, 2024 · 0 comments
Closed

[REFACTOR] 낙관락 vs 비관락 성능 비교 #192

lokigem opened this issue Aug 31, 2024 · 0 comments
Assignees
Labels
⚡️ Perf 성능 개선 🔨 Refactor 코드 리팩토링

Comments

@lokigem
Copy link
Collaborator

lokigem commented Aug 31, 2024

Goal

Retryable의 Retry 시간을 Random하게 지정했을 때 성능 비교

Overview

Test Case 1

export let options = {
  stages: [
    { duration: "2m", target: 10 }, // 2분 동안 10명의 사용자가 증가
    { duration: "2m", target: 20 }, // 2분 동안 20명으로 유지
    { duration: "2m", target: 20 },
    { duration: "2m", target: 0 },
  ],
};
  • 비관락

TPS : 10
실패율 : 0%
평균응답속도 : 224ms

비관락테스트-v1

  • 낙관락

TPS : 7
실패율 : 27.81%
평균응답속도 : 189.36ms

낙관락테스트-v1

낙관락이 더 빠른 것처럼 보이지만 실패율이 27%라서 낙관락을 적용한 API가 안정적이라고 할 수 없음
따라서 지금 테스트 조건으로는 한 번에 몰리는 트래픽이 있기 때문에 낙관락이 비관락보다 우세하다고 할 수 없음

Test Case 2

동시접속자수가 3명 정도 있는 서비스라고 가정하고 Request 요청이 Random한 시간에 일어난다고 가정

  • Stage 설정
export let options = {
  // iterations: 25,
  stages: [
    { duration: "10s", target: 1 },
    { duration: "10s", target: 2 },
    { duration: "30s", target: 3 },
    { duration: "10s", target: 2 },
    { duration: "10s", target: 1 },
  ],
};
  • 요청 타이밍 설정
  const randomSleepMs = Math.random() * 10000; // 0ms ~ 10000ms
  sleep(randomSleepMs / 1000);  // 초 단위로 변환하여 sleep 호출

  const res = http.post(apiUrl, payload, params);
  check(res, {
    "is status 200": (r) => r.status === 200,
  });
  • 낙관적 락 테스트 1

실패율 : 4.76%
평균응답속도 : 203.54ms

image
  • 낙관적 락 테스트 2

실패율 : 05
평균응답속도 : 229.62ms

어쨋든 요청이 성공하긴 해야한다는 조건이 있어서 Retry 횟수를 50까지 늘려줬다.

image
  • 비관적 락

실패율 : 0%
평균응답속도 : 331ms

image

결론

Retryable을 랜덤으로 주고 실상황에서 Race Condition 문제가 발생할 확률을 고려했을 때, 낙관적 락 전략을 사용하기로 했다.

Retryable을 Random으로 줘야 하는 이유

이전에 테스트를 진행했을 때, 비관적락이 어떠한 경우에서도 낙관적 락보다 빨랐다. 지금 생각해보면 충돌이 단 한 번이라도 일어나면 비관적락보다 느려질 수 밖에 없어지는 구조였던 것 같다. 최근에 TheWing님을 만나서 이 현상에 대해서 조언을 들었는데, 비관락을 사용할 때 재시도 간격을 동일하게 준게 아니냐는 얘기를 들어서 재시도 간격에 따른 성능을 비교해보고자 한다.

  • Retryable을 재시도 시간을 랜덤하게 주지 않았을 때
image
  • Retryable을 재시도 시간을 랜덤하게 줬을 때

실패율이 무려 8배 가까이 줄어든 것을 알 수 있다.

image
@lokigem lokigem added the 🔨 Refactor 코드 리팩토링 label Aug 31, 2024
@lokigem lokigem self-assigned this Aug 31, 2024
@rookedsysc rookedsysc pinned this issue Oct 13, 2024
@rookedsysc rookedsysc added the ⚡️ Perf 성능 개선 label Oct 13, 2024
@rookedsysc rookedsysc unpinned this issue Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚡️ Perf 성능 개선 🔨 Refactor 코드 리팩토링
Projects
None yet
Development

No branches or pull requests

2 participants