diff --git a/docs/04-experiment.md b/docs/04-experiment.md index 3b4ce48..874a68b 100644 --- a/docs/04-experiment.md +++ b/docs/04-experiment.md @@ -42,7 +42,7 @@ MySQL만 사용하는 초기 리다이렉트 구조에서 VU 증가에 따라 | Java | 25 | | Spring Boot | 4.1.0 | | Database | MySQL 8.4 | -| Redis | 미적용 | +| Redis | Baseline 미적용 / Experiment 적용 | | k6 | 2.1.0 | | Prometheus | 3.13.0 | | Grafana | 13.1.1 | @@ -106,9 +106,11 @@ MySQL만 사용하는 초기 리다이렉트 구조에서 VU 증가에 따라 ## 8. Warm-up -- 별도 Warm-up: 미실행 -- 측정 제외 구간: 없음 -- 보완 사항: Redis 비교 실험에서는 동일한 Warm-up 조건으로 Baseline도 다시 측정한다. +- Baseline: 별도 Warm-up 미실행 +- Redis: `setup()`에서 리다이렉트를 한 번 호출해 캐시 저장 +- 측정 제외 구간: URL 생성 요청과 캐시 Warm-up 요청 +- 실제 측정 요청: Redis Cache Hit 상태 +- 한계: Baseline과 Redis의 Warm-up 조건이 완전히 동일하지 않아 최종 비교 시 재측정이 필요하다. ## 9. Baseline 결과 @@ -136,12 +138,14 @@ MySQL만 사용하는 초기 리다이렉트 구조에서 VU 증가에 따라 ## 10. 개선 내용 -리다이렉트 조회에 Redis Cache Aside 전략을 적용할 예정이다. +리다이렉트 조회에 Redis Cache Aside 전략을 적용했다. ```text Redis 조회 → Cache Hit: 원본 URL 반환 -→ Cache Miss: MySQL 조회 후 Redis 저장 +→ Cache Miss: MySQL 조회 +→ Redis 저장 +→ 원본 URL 반환 ``` 기대 효과: @@ -153,30 +157,38 @@ Redis 조회 ## 11. 개선 후 결과 +### Redis Redirect + +| VU | 실행 시간 | 요청 수 | RPS | 평균 | p95 | p99 | 최대 | 실패율 | +|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| 20 | 1분 | 789,780 | 13,155.12 | 1.39ms | 2.81ms | 5.67ms | 198.76ms | 0.00% | +| 50 | 1분 | 975,688 | 16,238.53 | 2.90ms | 6.10ms | 11.20ms | 192.33ms | 0.00% | +| 100 | 1분 | 1,043,207 | 17,371.33 | 5.49ms | 11.93ms | 21.52ms | 154.10ms | 0.00% | + +### Baseline 비교 + | VU | 지표 | Baseline | Redis 적용 | 변화 | |---:|---|---:|---:|---:| -| 20 | RPS | 7,950.61 | 미측정 | 미측정 | -| 20 | p95 | 4.35ms | 미측정 | 미측정 | -| 20 | p99 | 6.28ms | 미측정 | 미측정 | -| 50 | RPS | 7,379.92 | 미측정 | 미측정 | -| 50 | p95 | 16.17ms | 미측정 | 미측정 | -| 50 | p99 | 27.73ms | 미측정 | 미측정 | -| 100 | RPS | 8,531.95 | 미측정 | 미측정 | -| 100 | p95 | 32.96ms | 미측정 | 미측정 | -| 100 | p99 | 49.88ms | 미측정 | 미측정 | +| 20 | RPS | 7,950.61 | 13,155.12 | 65.46% 증가 | +| 20 | p95 | 4.35ms | 2.81ms | 35.40% 감소 | +| 20 | p99 | 6.28ms | 5.67ms | 9.71% 감소 | +| 50 | RPS | 7,379.92 | 16,238.53 | 120.04% 증가 | +| 50 | p95 | 16.17ms | 6.10ms | 62.28% 감소 | +| 50 | p99 | 27.73ms | 11.20ms | 59.61% 감소 | +| 100 | RPS | 8,531.95 | 17,371.33 | 103.60% 증가 | +| 100 | p95 | 32.96ms | 11.93ms | 63.80% 감소 | +| 100 | p99 | 49.88ms | 21.52ms | 56.86% 감소 | ## 12. 결과 분석 -현재 Baseline에서는 VU 증가에 따라 응답 지연이 커지는 현상을 확인했다. +Redis 적용 후 모든 VU 구간에서 실패율 0%와 Check 성공률 100%를 유지했다. + +20 VU에서는 RPS가 약 65% 증가했고 p95는 약 35% 감소했다. 50 VU와 100 VU에서는 RPS가 두 배 이상으로 증가했으며 p95와 p99도 약 56~64% 감소했다. -Redis 적용 후 다음 내용을 비교한다. +따라서 반복 조회가 많은 환경에서는 Redis Cache Hit를 통해 MySQL 조회를 생략하는 방식이 처리량과 응답 지연 개선에 효과적이었다. -- p95와 p99가 감소했는가? -- RPS가 증가했는가? -- MySQL 조회량이 감소했는가? -- HikariCP 사용량이 감소했는가? -- Redis가 새로운 병목으로 나타나는가? +다만 이번 테스트는 고정 VU 방식이므로 응답이 빨라지면 같은 시간 동안 더 많은 요청을 보내게 된다. 또한 CPU, HikariCP, MySQL 조회량을 기록하지 않았으므로 DB 부하가 실제로 얼마나 감소했는지는 추가 측정이 필요하다. ## 13. Platform Thread와 Virtual Thread 비교 @@ -218,8 +230,8 @@ VIRTUAL_THREADS_ENABLED=true ## 15. 후속 실험 -- [ ] Redis Cache Aside 적용 -- [ ] 동일한 조건으로 Redis 적용 전후 비교 +- [x] Redis Cache Aside 적용 +- [x] 동일한 조건으로 Redis 적용 전후 비교 - [ ] Prometheus와 Grafana 서버 지표 기록 - [ ] 조건별 3회 측정 후 중앙값 비교 - [ ] Platform Thread와 Virtual Thread 비교 diff --git a/k6/redis-redirect.js b/k6/redis-redirect.js new file mode 100644 index 0000000..4f94f3b --- /dev/null +++ b/k6/redis-redirect.js @@ -0,0 +1,99 @@ +import http from 'k6/http'; +import { check } from 'k6'; + +const BASE_URL = __ENV.BASE_URL || 'http://app:8080'; + +export const options = { + vus: Number(__ENV.VUS || 20), + duration: __ENV.DURATION || '1m', + maxRedirects: 0, + + summaryTrendStats: [ + 'avg', + 'min', + 'med', + 'p(90)', + 'p(95)', + 'p(99)', + 'max', + ], + + thresholds: { + checks: ['rate>0.99'], + http_req_failed: ['rate<0.01'], + 'http_req_duration{endpoint:redirect}': ['p(95)<500'] + } +}; + +export function setup() { + const response = http.post( + `${BASE_URL}/api/v1/data/shorten`, + JSON.stringify({ + longUrl: 'https://www.google.com', + }), + { + headers: { + 'Content-Type': 'application/json', + }, + tags: { + endpoint: 'setup', + } + } + ); + + const success = check(response, { + '단축 URL 생성 상태는 201이다': (res) => res.status === 201, + 'shortCode가 반환된다': (res) => { + const body = res.json(); + return body.shortCode !== undefined && body.shortCode !== null; + } + }); + + if (!success) { + throw new Error( + `단축 URL 생성 실패: status=${response.status}, body=${response.body}` + ); + } + + const shortCode = response.json().shortCode; + + const warmUpResponse = http.get( + `${BASE_URL}/api/v1/${shortCode}`, + { + redirects: 0, + tags: { + endpoint: 'warm-up' + } + } + ) + + if (warmUpResponse.status !== 302) { + throw new Error( + `캐시 Warm-up 실패: status=${warmUpResponse.status}` + ); + } + + return { + shortCode + }; +} + +export default function (data) { + const response = http.get( + `${BASE_URL}/api/v1/${data.shortCode}`, + { + redirects: 0, + tags: { + endpoint: 'redirect', + } + } + ); + + check(response, { + '리다이렉트 상태는 302이다': (res) => res.status === 302, + 'Location 헤더가 존재한다': (res) => + res.headers.Location !== undefined, + '원본 URL이 올바르다': (res) => + res.headers.Location === 'https://www.google.com' + }); +} \ No newline at end of file diff --git a/results/redis/100vu-1m.txt b/results/redis/100vu-1m.txt new file mode 100644 index 0000000..38b331f --- /dev/null +++ b/results/redis/100vu-1m.txt @@ -0,0 +1,246 @@ + + /\ Grafana /‾‾/ + /\ / \ |\ __ / / + / \/ \ | |/ / / ‾‾\ + / \ | ( | (‾) | + / __________ \ |_|\_\ \_____/ + + + execution: local + script: /scripts/redis-redirect.js + output: - + + scenarios: (100.00%) 1 scenario, 100 max VUs, 1m30s max duration (incl. graceful stop): + * default: 100 looping VUs for 1m0s (gracefulStop: 30s) + + +running (0m01.0s), 100/100 VUs, 12202 complete and 0 interrupted iterations +default [ 2% ] 100 VUs 0m00.9s/1m0s + +running (0m02.0s), 100/100 VUs, 26837 complete and 0 interrupted iterations +default [ 3% ] 100 VUs 0m01.9s/1m0s + +running (0m03.0s), 100/100 VUs, 43783 complete and 0 interrupted iterations +default [ 5% ] 100 VUs 0m02.9s/1m0s + +running (0m04.0s), 100/100 VUs, 58187 complete and 0 interrupted iterations +default [ 7% ] 100 VUs 0m03.9s/1m0s + +running (0m05.0s), 100/100 VUs, 75024 complete and 0 interrupted iterations +default [ 8% ] 100 VUs 0m04.9s/1m0s + +running (0m06.0s), 100/100 VUs, 91586 complete and 0 interrupted iterations +default [ 10% ] 100 VUs 0m05.9s/1m0s + +running (0m07.0s), 100/100 VUs, 108031 complete and 0 interrupted iterations +default [ 12% ] 100 VUs 0m06.9s/1m0s + +running (0m08.0s), 100/100 VUs, 124980 complete and 0 interrupted iterations +default [ 13% ] 100 VUs 0m07.9s/1m0s + +running (0m09.0s), 100/100 VUs, 141740 complete and 0 interrupted iterations +default [ 15% ] 100 VUs 0m08.9s/1m0s + +running (0m10.0s), 100/100 VUs, 159138 complete and 0 interrupted iterations +default [ 17% ] 100 VUs 0m09.9s/1m0s + +running (0m11.0s), 100/100 VUs, 176353 complete and 0 interrupted iterations +default [ 18% ] 100 VUs 0m10.9s/1m0s + +running (0m12.0s), 100/100 VUs, 191889 complete and 0 interrupted iterations +default [ 20% ] 100 VUs 0m11.9s/1m0s + +running (0m13.0s), 100/100 VUs, 206571 complete and 0 interrupted iterations +default [ 22% ] 100 VUs 0m12.9s/1m0s + +running (0m14.0s), 100/100 VUs, 221627 complete and 0 interrupted iterations +default [ 23% ] 100 VUs 0m13.9s/1m0s + +running (0m15.0s), 100/100 VUs, 238709 complete and 0 interrupted iterations +default [ 25% ] 100 VUs 0m14.9s/1m0s + +running (0m16.0s), 100/100 VUs, 256341 complete and 0 interrupted iterations +default [ 27% ] 100 VUs 0m15.9s/1m0s + +running (0m17.0s), 100/100 VUs, 273668 complete and 0 interrupted iterations +default [ 28% ] 100 VUs 0m16.9s/1m0s + +running (0m18.0s), 100/100 VUs, 291574 complete and 0 interrupted iterations +default [ 30% ] 100 VUs 0m17.9s/1m0s + +running (0m19.0s), 100/100 VUs, 309652 complete and 0 interrupted iterations +default [ 32% ] 100 VUs 0m18.9s/1m0s + +running (0m20.0s), 100/100 VUs, 326923 complete and 0 interrupted iterations +default [ 33% ] 100 VUs 0m19.9s/1m0s + +running (0m21.0s), 100/100 VUs, 345052 complete and 0 interrupted iterations +default [ 35% ] 100 VUs 0m20.9s/1m0s + +running (0m22.0s), 100/100 VUs, 361077 complete and 0 interrupted iterations +default [ 37% ] 100 VUs 0m21.9s/1m0s + +running (0m23.0s), 100/100 VUs, 379409 complete and 0 interrupted iterations +default [ 38% ] 100 VUs 0m22.9s/1m0s + +running (0m24.0s), 100/100 VUs, 396184 complete and 0 interrupted iterations +default [ 40% ] 100 VUs 0m23.9s/1m0s + +running (0m25.0s), 100/100 VUs, 414317 complete and 0 interrupted iterations +default [ 42% ] 100 VUs 0m24.9s/1m0s + +running (0m26.0s), 100/100 VUs, 432517 complete and 0 interrupted iterations +default [ 43% ] 100 VUs 0m25.9s/1m0s + +running (0m27.0s), 100/100 VUs, 449992 complete and 0 interrupted iterations +default [ 45% ] 100 VUs 0m26.9s/1m0s + +running (0m28.0s), 100/100 VUs, 468289 complete and 0 interrupted iterations +default [ 47% ] 100 VUs 0m27.9s/1m0s + +running (0m29.0s), 100/100 VUs, 486616 complete and 0 interrupted iterations +default [ 48% ] 100 VUs 0m28.9s/1m0s + +running (0m30.0s), 100/100 VUs, 504202 complete and 0 interrupted iterations +default [ 50% ] 100 VUs 0m29.9s/1m0s + +running (0m31.0s), 100/100 VUs, 521785 complete and 0 interrupted iterations +default [ 52% ] 100 VUs 0m30.9s/1m0s + +running (0m32.0s), 100/100 VUs, 538723 complete and 0 interrupted iterations +default [ 53% ] 100 VUs 0m31.9s/1m0s + +running (0m33.0s), 100/100 VUs, 557363 complete and 0 interrupted iterations +default [ 55% ] 100 VUs 0m32.9s/1m0s + +running (0m34.0s), 100/100 VUs, 573853 complete and 0 interrupted iterations +default [ 57% ] 100 VUs 0m33.9s/1m0s + +running (0m35.0s), 100/100 VUs, 593040 complete and 0 interrupted iterations +default [ 58% ] 100 VUs 0m34.9s/1m0s + +running (0m36.0s), 100/100 VUs, 612195 complete and 0 interrupted iterations +default [ 60% ] 100 VUs 0m35.9s/1m0s + +running (0m37.0s), 100/100 VUs, 629231 complete and 0 interrupted iterations +default [ 62% ] 100 VUs 0m36.9s/1m0s + +running (0m38.0s), 100/100 VUs, 646993 complete and 0 interrupted iterations +default [ 63% ] 100 VUs 0m37.9s/1m0s + +running (0m39.0s), 100/100 VUs, 665602 complete and 0 interrupted iterations +default [ 65% ] 100 VUs 0m38.9s/1m0s + +running (0m40.0s), 100/100 VUs, 682838 complete and 0 interrupted iterations +default [ 67% ] 100 VUs 0m39.9s/1m0s + +running (0m41.0s), 100/100 VUs, 701380 complete and 0 interrupted iterations +default [ 68% ] 100 VUs 0m40.9s/1m0s + +running (0m42.0s), 100/100 VUs, 718803 complete and 0 interrupted iterations +default [ 70% ] 100 VUs 0m41.9s/1m0s + +running (0m43.0s), 100/100 VUs, 737248 complete and 0 interrupted iterations +default [ 72% ] 100 VUs 0m42.9s/1m0s + +running (0m44.0s), 100/100 VUs, 754303 complete and 0 interrupted iterations +default [ 73% ] 100 VUs 0m43.9s/1m0s + +running (0m45.0s), 100/100 VUs, 773059 complete and 0 interrupted iterations +default [ 75% ] 100 VUs 0m44.9s/1m0s + +running (0m46.0s), 100/100 VUs, 792349 complete and 0 interrupted iterations +default [ 77% ] 100 VUs 0m45.9s/1m0s + +running (0m47.0s), 100/100 VUs, 810978 complete and 0 interrupted iterations +default [ 78% ] 100 VUs 0m46.9s/1m0s + +running (0m48.0s), 100/100 VUs, 830879 complete and 0 interrupted iterations +default [ 80% ] 100 VUs 0m47.9s/1m0s + +running (0m49.0s), 100/100 VUs, 850174 complete and 0 interrupted iterations +default [ 82% ] 100 VUs 0m48.9s/1m0s + +running (0m50.0s), 100/100 VUs, 868970 complete and 0 interrupted iterations +default [ 83% ] 100 VUs 0m49.9s/1m0s + +running (0m51.0s), 100/100 VUs, 888905 complete and 0 interrupted iterations +default [ 85% ] 100 VUs 0m50.9s/1m0s + +running (0m52.0s), 100/100 VUs, 900502 complete and 0 interrupted iterations +default [ 87% ] 100 VUs 0m51.9s/1m0s + +running (0m53.0s), 100/100 VUs, 917539 complete and 0 interrupted iterations +default [ 88% ] 100 VUs 0m52.9s/1m0s + +running (0m54.0s), 100/100 VUs, 933756 complete and 0 interrupted iterations +default [ 90% ] 100 VUs 0m53.9s/1m0s + +running (0m55.0s), 100/100 VUs, 951054 complete and 0 interrupted iterations +default [ 92% ] 100 VUs 0m54.9s/1m0s + +running (0m56.0s), 100/100 VUs, 970028 complete and 0 interrupted iterations +default [ 93% ] 100 VUs 0m55.9s/1m0s + +running (0m57.0s), 100/100 VUs, 988830 complete and 0 interrupted iterations +default [ 95% ] 100 VUs 0m56.9s/1m0s + +running (0m58.0s), 100/100 VUs, 1008495 complete and 0 interrupted iterations +default [ 97% ] 100 VUs 0m57.9s/1m0s + +running (0m59.0s), 100/100 VUs, 1024610 complete and 0 interrupted iterations +default [ 98% ] 100 VUs 0m58.9s/1m0s + +running (1m00.0s), 100/100 VUs, 1041793 complete and 0 interrupted iterations +default [ 100% ] 100 VUs 0m59.9s/1m0s + +running (1m00.1s), 000/100 VUs, 1043207 complete and 0 interrupted iterations +default ✓ [ 100% ] 100 VUs 1m0s + + + █ THRESHOLDS + + checks + ✓ 'rate>0.99' rate=100.00% + + http_req_duration{endpoint:redirect} + ✓ 'p(95)<500' p(95)=11.93ms + + http_req_failed + ✓ 'rate<0.01' rate=0.00% + + + █ TOTAL RESULTS + + checks_total.......: 3129623 52114.037306/s + checks_succeeded...: 100.00% 3129623 out of 3129623 + checks_failed......: 0.00% 0 out of 3129623 + + ✓ 단축 URL 생성 상태는 201이다 + ✓ shortCode가 반환된다 + ✓ 리다이렉트 상태는 302이다 + ✓ Location 헤더가 존재한다 + ✓ 원본 URL이 올바르다 + + HTTP + http_req_duration..............: avg=5.49ms min=277.45µs med=4.6ms p(90)=8.95ms p(95)=11.93ms p(99)=21.52ms max=154.1ms + { endpoint:redirect }........: avg=5.49ms min=277.45µs med=4.6ms p(90)=8.95ms p(95)=11.93ms p(99)=21.52ms max=154.1ms + { expected_response:true }...: avg=5.49ms min=277.45µs med=4.6ms p(90)=8.95ms p(95)=11.93ms p(99)=21.52ms max=154.1ms + http_req_failed................: 0.00% 0 out of 1043209 + http_reqs......................: 1043209 17371.367971/s + + EXECUTION + iteration_duration.............: avg=5.72ms min=340.95µs med=4.77ms p(90)=9.41ms p(95)=12.56ms p(99)=22.27ms max=159.11ms + iterations.....................: 1043207 17371.334668/s + vus............................: 100 min=100 max=100 + vus_max........................: 100 min=100 max=100 + + NETWORK + data_received..................: 112 MB 1.9 MB/s + data_sent......................: 75 MB 1.3 MB/s + + + + +running (1m00.1s), 000/100 VUs, 1043207 complete and 0 interrupted iterations +default ✓ [ 100% ] 100 VUs 1m0s diff --git a/results/redis/20vu-1m.txt b/results/redis/20vu-1m.txt new file mode 100644 index 0000000..c2fb33c --- /dev/null +++ b/results/redis/20vu-1m.txt @@ -0,0 +1,243 @@ + + /\ Grafana /‾‾/ + /\ / \ |\ __ / / + / \/ \ | |/ / / ‾‾\ + / \ | ( | (‾) | + / __________ \ |_|\_\ \_____/ + + + execution: local + script: /scripts/redis-redirect.js + output: - + + scenarios: (100.00%) 1 scenario, 20 max VUs, 1m30s max duration (incl. graceful stop): + * default: 20 looping VUs for 1m0s (gracefulStop: 30s) + + +running (0m01.0s), 20/20 VUs, 4242 complete and 0 interrupted iterations +default [ 2% ] 20 VUs 0m01.0s/1m0s + +running (0m02.0s), 20/20 VUs, 7532 complete and 0 interrupted iterations +default [ 3% ] 20 VUs 0m02.0s/1m0s + +running (0m03.0s), 20/20 VUs, 13224 complete and 0 interrupted iterations +default [ 5% ] 20 VUs 0m03.0s/1m0s + +running (0m04.0s), 20/20 VUs, 23818 complete and 0 interrupted iterations +default [ 7% ] 20 VUs 0m04.0s/1m0s + +running (0m05.0s), 20/20 VUs, 35411 complete and 0 interrupted iterations +default [ 8% ] 20 VUs 0m05.0s/1m0s + +running (0m06.0s), 20/20 VUs, 44550 complete and 0 interrupted iterations +default [ 10% ] 20 VUs 0m06.0s/1m0s + +running (0m07.0s), 20/20 VUs, 52219 complete and 0 interrupted iterations +default [ 12% ] 20 VUs 0m07.0s/1m0s + +running (0m08.0s), 20/20 VUs, 60557 complete and 0 interrupted iterations +default [ 13% ] 20 VUs 0m08.0s/1m0s + +running (0m09.0s), 20/20 VUs, 72216 complete and 0 interrupted iterations +default [ 15% ] 20 VUs 0m09.0s/1m0s + +running (0m10.0s), 20/20 VUs, 83502 complete and 0 interrupted iterations +default [ 17% ] 20 VUs 0m10.0s/1m0s + +running (0m11.0s), 20/20 VUs, 96711 complete and 0 interrupted iterations +default [ 18% ] 20 VUs 0m11.0s/1m0s + +running (0m12.0s), 20/20 VUs, 108542 complete and 0 interrupted iterations +default [ 20% ] 20 VUs 0m12.0s/1m0s + +running (0m13.0s), 20/20 VUs, 122662 complete and 0 interrupted iterations +default [ 22% ] 20 VUs 0m13.0s/1m0s + +running (0m14.0s), 20/20 VUs, 136574 complete and 0 interrupted iterations +default [ 23% ] 20 VUs 0m14.0s/1m0s + +running (0m15.0s), 20/20 VUs, 147736 complete and 0 interrupted iterations +default [ 25% ] 20 VUs 0m15.0s/1m0s + +running (0m16.0s), 20/20 VUs, 162270 complete and 0 interrupted iterations +default [ 27% ] 20 VUs 0m16.0s/1m0s + +running (0m17.0s), 20/20 VUs, 175932 complete and 0 interrupted iterations +default [ 28% ] 20 VUs 0m17.0s/1m0s + +running (0m18.0s), 20/20 VUs, 190595 complete and 0 interrupted iterations +default [ 30% ] 20 VUs 0m18.0s/1m0s + +running (0m19.0s), 20/20 VUs, 204322 complete and 0 interrupted iterations +default [ 32% ] 20 VUs 0m19.0s/1m0s + +running (0m20.0s), 20/20 VUs, 217733 complete and 0 interrupted iterations +default [ 33% ] 20 VUs 0m20.0s/1m0s + +running (0m21.0s), 20/20 VUs, 230114 complete and 0 interrupted iterations +default [ 35% ] 20 VUs 0m21.0s/1m0s + +running (0m22.0s), 20/20 VUs, 243164 complete and 0 interrupted iterations +default [ 37% ] 20 VUs 0m22.0s/1m0s + +running (0m23.0s), 20/20 VUs, 256720 complete and 0 interrupted iterations +default [ 38% ] 20 VUs 0m23.0s/1m0s + +running (0m24.0s), 20/20 VUs, 271874 complete and 0 interrupted iterations +default [ 40% ] 20 VUs 0m24.0s/1m0s + +running (0m25.0s), 20/20 VUs, 286327 complete and 0 interrupted iterations +default [ 42% ] 20 VUs 0m25.0s/1m0s + +running (0m26.0s), 20/20 VUs, 300626 complete and 0 interrupted iterations +default [ 43% ] 20 VUs 0m26.0s/1m0s + +running (0m27.0s), 20/20 VUs, 315189 complete and 0 interrupted iterations +default [ 45% ] 20 VUs 0m27.0s/1m0s + +running (0m28.0s), 20/20 VUs, 330051 complete and 0 interrupted iterations +default [ 47% ] 20 VUs 0m28.0s/1m0s + +running (0m29.0s), 20/20 VUs, 343083 complete and 0 interrupted iterations +default [ 48% ] 20 VUs 0m29.0s/1m0s + +running (0m30.0s), 20/20 VUs, 357414 complete and 0 interrupted iterations +default [ 50% ] 20 VUs 0m30.0s/1m0s + +running (0m31.0s), 20/20 VUs, 370948 complete and 0 interrupted iterations +default [ 52% ] 20 VUs 0m31.0s/1m0s + +running (0m32.0s), 20/20 VUs, 383553 complete and 0 interrupted iterations +default [ 53% ] 20 VUs 0m32.0s/1m0s + +running (0m33.0s), 20/20 VUs, 399112 complete and 0 interrupted iterations +default [ 55% ] 20 VUs 0m33.0s/1m0s + +running (0m34.0s), 20/20 VUs, 414151 complete and 0 interrupted iterations +default [ 57% ] 20 VUs 0m34.0s/1m0s + +running (0m35.0s), 20/20 VUs, 428642 complete and 0 interrupted iterations +default [ 58% ] 20 VUs 0m35.0s/1m0s + +running (0m36.0s), 20/20 VUs, 443959 complete and 0 interrupted iterations +default [ 60% ] 20 VUs 0m36.0s/1m0s + +running (0m37.0s), 20/20 VUs, 458980 complete and 0 interrupted iterations +default [ 62% ] 20 VUs 0m37.0s/1m0s + +running (0m38.0s), 20/20 VUs, 473789 complete and 0 interrupted iterations +default [ 63% ] 20 VUs 0m38.0s/1m0s + +running (0m39.0s), 20/20 VUs, 485998 complete and 0 interrupted iterations +default [ 65% ] 20 VUs 0m39.0s/1m0s + +running (0m40.0s), 20/20 VUs, 500760 complete and 0 interrupted iterations +default [ 67% ] 20 VUs 0m40.0s/1m0s + +running (0m41.0s), 20/20 VUs, 513707 complete and 0 interrupted iterations +default [ 68% ] 20 VUs 0m41.0s/1m0s + +running (0m42.0s), 20/20 VUs, 525895 complete and 0 interrupted iterations +default [ 70% ] 20 VUs 0m42.0s/1m0s + +running (0m43.0s), 20/20 VUs, 541164 complete and 0 interrupted iterations +default [ 72% ] 20 VUs 0m43.0s/1m0s + +running (0m44.0s), 20/20 VUs, 556677 complete and 0 interrupted iterations +default [ 73% ] 20 VUs 0m44.0s/1m0s + +running (0m45.0s), 20/20 VUs, 571645 complete and 0 interrupted iterations +default [ 75% ] 20 VUs 0m45.0s/1m0s + +running (0m46.0s), 20/20 VUs, 587549 complete and 0 interrupted iterations +default [ 77% ] 20 VUs 0m46.0s/1m0s + +running (0m47.0s), 20/20 VUs, 600718 complete and 0 interrupted iterations +default [ 78% ] 20 VUs 0m47.0s/1m0s + +running (0m48.0s), 20/20 VUs, 616367 complete and 0 interrupted iterations +default [ 80% ] 20 VUs 0m48.0s/1m0s + +running (0m49.0s), 20/20 VUs, 630209 complete and 0 interrupted iterations +default [ 82% ] 20 VUs 0m49.0s/1m0s + +running (0m50.0s), 20/20 VUs, 645200 complete and 0 interrupted iterations +default [ 83% ] 20 VUs 0m50.0s/1m0s + +running (0m51.0s), 20/20 VUs, 657730 complete and 0 interrupted iterations +default [ 85% ] 20 VUs 0m51.0s/1m0s + +running (0m52.0s), 20/20 VUs, 671270 complete and 0 interrupted iterations +default [ 87% ] 20 VUs 0m52.0s/1m0s + +running (0m53.0s), 20/20 VUs, 685814 complete and 0 interrupted iterations +default [ 88% ] 20 VUs 0m53.0s/1m0s + +running (0m54.0s), 20/20 VUs, 700824 complete and 0 interrupted iterations +default [ 90% ] 20 VUs 0m54.0s/1m0s + +running (0m55.0s), 20/20 VUs, 713952 complete and 0 interrupted iterations +default [ 92% ] 20 VUs 0m55.0s/1m0s + +running (0m56.0s), 20/20 VUs, 729661 complete and 0 interrupted iterations +default [ 93% ] 20 VUs 0m56.0s/1m0s + +running (0m57.0s), 20/20 VUs, 744966 complete and 0 interrupted iterations +default [ 95% ] 20 VUs 0m57.0s/1m0s + +running (0m58.0s), 20/20 VUs, 760604 complete and 0 interrupted iterations +default [ 97% ] 20 VUs 0m58.0s/1m0s + +running (0m59.0s), 20/20 VUs, 774597 complete and 0 interrupted iterations +default [ 98% ] 20 VUs 0m59.0s/1m0s + +running (1m00.0s), 20/20 VUs, 789248 complete and 0 interrupted iterations +default [ 100% ] 20 VUs 1m00.0s/1m0s + + + █ THRESHOLDS + + checks + ✓ 'rate>0.99' rate=100.00% + + http_req_duration{endpoint:redirect} + ✓ 'p(95)<500' p(95)=2.81ms + + http_req_failed + ✓ 'rate<0.01' rate=0.00% + + + █ TOTAL RESULTS + + checks_total.......: 2369342 39465.389591/s + checks_succeeded...: 100.00% 2369342 out of 2369342 + checks_failed......: 0.00% 0 out of 2369342 + + ✓ 단축 URL 생성 상태는 201이다 + ✓ shortCode가 반환된다 + ✓ 리다이렉트 상태는 302이다 + ✓ Location 헤더가 존재한다 + ✓ 원본 URL이 올바르다 + + HTTP + http_req_duration..............: avg=1.39ms min=22.66µs med=1.14ms p(90)=2.12ms p(95)=2.81ms p(99)=5.67ms max=198.76ms + { endpoint:redirect }........: avg=1.39ms min=22.66µs med=1.14ms p(90)=2.12ms p(95)=2.81ms p(99)=5.67ms max=198.76ms + { expected_response:true }...: avg=1.39ms min=22.66µs med=1.14ms p(90)=2.12ms p(95)=2.81ms p(99)=5.67ms max=198.76ms + http_req_failed................: 0.00% 0 out of 789782 + http_reqs......................: 789782 13155.152073/s + + EXECUTION + iteration_duration.............: avg=1.5ms min=235.37µs med=1.24ms p(90)=2.28ms p(95)=3.02ms p(99)=5.96ms max=203.16ms + iterations.....................: 789780 13155.118759/s + vus............................: 20 min=20 max=20 + vus_max........................: 20 min=20 max=20 + + NETWORK + data_received..................: 85 MB 1.4 MB/s + data_sent......................: 57 MB 947 kB/s + + + + +running (1m00.0s), 00/20 VUs, 789780 complete and 0 interrupted iterations +default ✓ [ 100% ] 20 VUs 1m0s diff --git a/results/redis/50vu-1m.txt b/results/redis/50vu-1m.txt new file mode 100644 index 0000000..998bb85 --- /dev/null +++ b/results/redis/50vu-1m.txt @@ -0,0 +1,243 @@ + + /\ Grafana /‾‾/ + /\ / \ |\ __ / / + / \/ \ | |/ / / ‾‾\ + / \ | ( | (‾) | + / __________ \ |_|\_\ \_____/ + + + execution: local + script: /scripts/redis-redirect.js + output: - + + scenarios: (100.00%) 1 scenario, 50 max VUs, 1m30s max duration (incl. graceful stop): + * default: 50 looping VUs for 1m0s (gracefulStop: 30s) + + +running (0m01.0s), 50/50 VUs, 4098 complete and 0 interrupted iterations +default [ 1% ] 50 VUs 0m00.9s/1m0s + +running (0m02.0s), 50/50 VUs, 12077 complete and 0 interrupted iterations +default [ 3% ] 50 VUs 0m01.9s/1m0s + +running (0m03.0s), 50/50 VUs, 23386 complete and 0 interrupted iterations +default [ 5% ] 50 VUs 0m02.9s/1m0s + +running (0m04.0s), 50/50 VUs, 26794 complete and 0 interrupted iterations +default [ 6% ] 50 VUs 0m03.9s/1m0s + +running (0m05.0s), 50/50 VUs, 37366 complete and 0 interrupted iterations +default [ 8% ] 50 VUs 0m04.9s/1m0s + +running (0m06.0s), 50/50 VUs, 50124 complete and 0 interrupted iterations +default [ 10% ] 50 VUs 0m05.9s/1m0s + +running (0m07.0s), 50/50 VUs, 64929 complete and 0 interrupted iterations +default [ 11% ] 50 VUs 0m06.9s/1m0s + +running (0m08.0s), 50/50 VUs, 80479 complete and 0 interrupted iterations +default [ 13% ] 50 VUs 0m07.9s/1m0s + +running (0m09.0s), 50/50 VUs, 96878 complete and 0 interrupted iterations +default [ 15% ] 50 VUs 0m08.9s/1m0s + +running (0m10.0s), 50/50 VUs, 111447 complete and 0 interrupted iterations +default [ 16% ] 50 VUs 0m09.9s/1m0s + +running (0m11.0s), 50/50 VUs, 127148 complete and 0 interrupted iterations +default [ 18% ] 50 VUs 0m10.9s/1m0s + +running (0m12.0s), 50/50 VUs, 142234 complete and 0 interrupted iterations +default [ 20% ] 50 VUs 0m11.9s/1m0s + +running (0m13.0s), 50/50 VUs, 158772 complete and 0 interrupted iterations +default [ 21% ] 50 VUs 0m12.9s/1m0s + +running (0m14.0s), 50/50 VUs, 172907 complete and 0 interrupted iterations +default [ 23% ] 50 VUs 0m13.9s/1m0s + +running (0m15.0s), 50/50 VUs, 184221 complete and 0 interrupted iterations +default [ 25% ] 50 VUs 0m14.9s/1m0s + +running (0m16.0s), 50/50 VUs, 198176 complete and 0 interrupted iterations +default [ 26% ] 50 VUs 0m15.9s/1m0s + +running (0m17.0s), 50/50 VUs, 214884 complete and 0 interrupted iterations +default [ 28% ] 50 VUs 0m16.9s/1m0s + +running (0m18.0s), 50/50 VUs, 231546 complete and 0 interrupted iterations +default [ 30% ] 50 VUs 0m17.9s/1m0s + +running (0m19.0s), 50/50 VUs, 247939 complete and 0 interrupted iterations +default [ 31% ] 50 VUs 0m18.9s/1m0s + +running (0m20.0s), 50/50 VUs, 263486 complete and 0 interrupted iterations +default [ 33% ] 50 VUs 0m19.9s/1m0s + +running (0m21.0s), 50/50 VUs, 280853 complete and 0 interrupted iterations +default [ 35% ] 50 VUs 0m20.9s/1m0s + +running (0m22.0s), 50/50 VUs, 296691 complete and 0 interrupted iterations +default [ 36% ] 50 VUs 0m21.9s/1m0s + +running (0m23.0s), 50/50 VUs, 312319 complete and 0 interrupted iterations +default [ 38% ] 50 VUs 0m22.9s/1m0s + +running (0m24.0s), 50/50 VUs, 330114 complete and 0 interrupted iterations +default [ 40% ] 50 VUs 0m23.9s/1m0s + +running (0m25.0s), 50/50 VUs, 347130 complete and 0 interrupted iterations +default [ 41% ] 50 VUs 0m24.9s/1m0s + +running (0m26.0s), 50/50 VUs, 365598 complete and 0 interrupted iterations +default [ 43% ] 50 VUs 0m25.9s/1m0s + +running (0m27.0s), 50/50 VUs, 382883 complete and 0 interrupted iterations +default [ 45% ] 50 VUs 0m26.9s/1m0s + +running (0m28.0s), 50/50 VUs, 399626 complete and 0 interrupted iterations +default [ 46% ] 50 VUs 0m27.9s/1m0s + +running (0m29.0s), 50/50 VUs, 417442 complete and 0 interrupted iterations +default [ 48% ] 50 VUs 0m28.9s/1m0s + +running (0m30.0s), 50/50 VUs, 432712 complete and 0 interrupted iterations +default [ 50% ] 50 VUs 0m29.9s/1m0s + +running (0m31.0s), 50/50 VUs, 450591 complete and 0 interrupted iterations +default [ 51% ] 50 VUs 0m30.9s/1m0s + +running (0m32.0s), 50/50 VUs, 465027 complete and 0 interrupted iterations +default [ 53% ] 50 VUs 0m31.9s/1m0s + +running (0m33.0s), 50/50 VUs, 482988 complete and 0 interrupted iterations +default [ 55% ] 50 VUs 0m32.9s/1m0s + +running (0m34.0s), 50/50 VUs, 501206 complete and 0 interrupted iterations +default [ 56% ] 50 VUs 0m33.9s/1m0s + +running (0m35.0s), 50/50 VUs, 519388 complete and 0 interrupted iterations +default [ 58% ] 50 VUs 0m34.9s/1m0s + +running (0m36.0s), 50/50 VUs, 537747 complete and 0 interrupted iterations +default [ 60% ] 50 VUs 0m35.9s/1m0s + +running (0m37.0s), 50/50 VUs, 554630 complete and 0 interrupted iterations +default [ 61% ] 50 VUs 0m36.9s/1m0s + +running (0m38.0s), 50/50 VUs, 573294 complete and 0 interrupted iterations +default [ 63% ] 50 VUs 0m37.9s/1m0s + +running (0m39.0s), 50/50 VUs, 592330 complete and 0 interrupted iterations +default [ 65% ] 50 VUs 0m38.9s/1m0s + +running (0m40.0s), 50/50 VUs, 609910 complete and 0 interrupted iterations +default [ 66% ] 50 VUs 0m39.9s/1m0s + +running (0m41.0s), 50/50 VUs, 628354 complete and 0 interrupted iterations +default [ 68% ] 50 VUs 0m40.9s/1m0s + +running (0m42.0s), 50/50 VUs, 645873 complete and 0 interrupted iterations +default [ 70% ] 50 VUs 0m41.9s/1m0s + +running (0m43.0s), 50/50 VUs, 662587 complete and 0 interrupted iterations +default [ 71% ] 50 VUs 0m42.9s/1m0s + +running (0m44.0s), 50/50 VUs, 682121 complete and 0 interrupted iterations +default [ 73% ] 50 VUs 0m43.9s/1m0s + +running (0m45.0s), 50/50 VUs, 700560 complete and 0 interrupted iterations +default [ 75% ] 50 VUs 0m44.9s/1m0s + +running (0m46.0s), 50/50 VUs, 720304 complete and 0 interrupted iterations +default [ 76% ] 50 VUs 0m45.9s/1m0s + +running (0m47.0s), 50/50 VUs, 732711 complete and 0 interrupted iterations +default [ 78% ] 50 VUs 0m46.9s/1m0s + +running (0m48.0s), 50/50 VUs, 750136 complete and 0 interrupted iterations +default [ 80% ] 50 VUs 0m47.9s/1m0s + +running (0m49.0s), 50/50 VUs, 769270 complete and 0 interrupted iterations +default [ 81% ] 50 VUs 0m48.9s/1m0s + +running (0m50.0s), 50/50 VUs, 787191 complete and 0 interrupted iterations +default [ 83% ] 50 VUs 0m49.9s/1m0s + +running (0m51.0s), 50/50 VUs, 805693 complete and 0 interrupted iterations +default [ 85% ] 50 VUs 0m50.9s/1m0s + +running (0m52.0s), 50/50 VUs, 823345 complete and 0 interrupted iterations +default [ 86% ] 50 VUs 0m51.9s/1m0s + +running (0m53.0s), 50/50 VUs, 841972 complete and 0 interrupted iterations +default [ 88% ] 50 VUs 0m52.9s/1m0s + +running (0m54.0s), 50/50 VUs, 859919 complete and 0 interrupted iterations +default [ 90% ] 50 VUs 0m53.9s/1m0s + +running (0m55.0s), 50/50 VUs, 879491 complete and 0 interrupted iterations +default [ 91% ] 50 VUs 0m54.9s/1m0s + +running (0m56.0s), 50/50 VUs, 899580 complete and 0 interrupted iterations +default [ 93% ] 50 VUs 0m55.9s/1m0s + +running (0m57.0s), 50/50 VUs, 917529 complete and 0 interrupted iterations +default [ 95% ] 50 VUs 0m56.9s/1m0s + +running (0m58.0s), 50/50 VUs, 936442 complete and 0 interrupted iterations +default [ 96% ] 50 VUs 0m57.9s/1m0s + +running (0m59.0s), 50/50 VUs, 955361 complete and 0 interrupted iterations +default [ 98% ] 50 VUs 0m58.9s/1m0s + +running (1m00.0s), 50/50 VUs, 974005 complete and 0 interrupted iterations +default [ 100% ] 50 VUs 0m59.9s/1m0s + + + █ THRESHOLDS + + checks + ✓ 'rate>0.99' rate=100.00% + + http_req_duration{endpoint:redirect} + ✓ 'p(95)<500' p(95)=6.1ms + + http_req_failed + ✓ 'rate<0.01' rate=0.00% + + + █ TOTAL RESULTS + + checks_total.......: 2927066 48715.610896/s + checks_succeeded...: 100.00% 2927066 out of 2927066 + checks_failed......: 0.00% 0 out of 2927066 + + ✓ 단축 URL 생성 상태는 201이다 + ✓ shortCode가 반환된다 + ✓ 리다이렉트 상태는 302이다 + ✓ Location 헤더가 존재한다 + ✓ 원본 URL이 올바르다 + + HTTP + http_req_duration..............: avg=2.9ms min=234.54µs med=2.38ms p(90)=4.62ms p(95)=6.1ms p(99)=11.2ms max=192.33ms + { endpoint:redirect }........: avg=2.9ms min=234.54µs med=2.38ms p(90)=4.62ms p(95)=6.1ms p(99)=11.2ms max=192.33ms + { expected_response:true }...: avg=2.9ms min=234.54µs med=2.38ms p(90)=4.62ms p(95)=6.1ms p(99)=11.2ms max=192.33ms + http_req_failed................: 0.00% 0 out of 975690 + http_reqs......................: 975690 16238.559156/s + + EXECUTION + iteration_duration.............: avg=3.05ms min=300.54µs med=2.5ms p(90)=4.89ms p(95)=6.51ms p(99)=11.83ms max=193.24ms + iterations.....................: 975688 16238.52587/s + vus............................: 50 min=50 max=50 + vus_max........................: 50 min=50 max=50 + + NETWORK + data_received..................: 105 MB 1.7 MB/s + data_sent......................: 70 MB 1.2 MB/s + + + + +running (1m00.1s), 00/50 VUs, 975688 complete and 0 interrupted iterations +default ✓ [ 100% ] 50 VUs 1m0s