장바구니 추가 - ekdan38/HotDealService GitHub Wiki
테스트를 위해 4만개의 장바구니 더미 데이터를 생성하였다.
개선 전 k6 테스트
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
장바구니 추가 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 19852 | 908ms | 1.28s | 109 |
VU 200 | 18729 | 1.93s | 2.59s | 102 |
VU 300 | 18679 | 2.92s | 7.56s | 101 |
테스트 결과 분석
- VU 100 -> 200 증가시, Latency(mean), Latency(P95) 모두 2배 이상 증가
- TPS는 VU 증가에 따라 감소하는 모습을 보임
성능 개선 계획
- 로직 수정 : DB 조회 횟수 개선
- DTO Projection : 필드 개수가 4개로 많지 않기 때문에 진행하지 않음
- 인덱싱 : 유저의 장바구니 상품 종류 개수 제한, 같은 종류의 상품을 이미 추가했는지 검증하는 과정에서의 조회 성능 개선을 위해 인덱싱
- 캐싱 : INSERT, UPDATE 가 무조건 발생하는 구조이기 때문에 캐싱은 진행하지 않음
로직 수정, 인덱싱 진행
기존 로직 흐름
- DB 에서 cartItem 단건 조회
- 존재한다면, quantity 증가 update
- 존재하지 않는다면, Count로 유저의 cartItem 개수 조회(장바구니는 최대 10개라는 조건 처리 위함)
- 이후, 장바구니에 INSERT 처리
기존 로직은 DB에 최소 2번 최대 3번 접근해야 하기 때문에 이를 최소로 줄이기 위해 cart_item 테이블에서 List로 유저의 모든 cartItem 을 불러오도록 수정
로직 수정
- DB에서 유저의 cartItem 목록 List 조회
- List에서 장바구니 추가 할 product가 존재하는지 필터링
- 존재한다면, quantity 증가 UPDATE
- 존재하지 않는다면, INSERT
로직 수정 후 DB 에 최소, 최대 2번 접근
로직 수정 후 k6 테스트
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
장바구니 추가 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 24352 | 739ms | 1.11s | 134 |
VU 200 | 23063 | 1.56s | 2.14s | 127 |
VU 300 | 23948 | 2.26s | 6.12s | 131 |
테스트 결과 분석
Latency
-
Latency(mean)
- VU 100: 908ms → 739ms (약 18.6% 개선)
- VU 200: 1.93s → 1.56s (약 19.1% 개선)
- VU 300: 2.92s → 2.26s (약 22.6% 개선)
Latency(mean) : 약 19 ~ 22% 개선 효과를 보임
-
Latency(P95)
- VU 100: 1.28s → 1.11s (약 13.3% 개선)
- VU 200: 2.59s → 2.14s (약 17.4% 개선)
- VU 300: 7.56s → 6.12s (약 19.1% 개선)
Latency(P95) : 약 13 ~ 19% 개선 효과를 보이지만 여전히 지연 모습을 보임
TPS
- VU 100: 109 → 134 (약 22.9% 개선)
- VU 200: 102 → 127 (약 24.5% 개선)
- VU 300: 101 → 131 (약 29.7% 개선)
TPS : 약 23 ~ 30 % 개선
DB 접근 횟수가 줄어들고, 메모리 수준에서 처리하는 로직을 통해 Latency(mean)은 최대 22%, TPS는 최대 30% 향상됨
인덱싱이 적용되어있지 않기 때문에 인덱싱을 통한 성능 향상도 진행
2.1. 실행 계획 및 쿼리 실행 소요 시간
[실행 계획]
EXPLAIN SELECT ci.cart_id,ci.product_id,ci.quantity,ci.user_id
FROM cart_item ci
WHERE ci.user_id=9836;
[소요 시간]
소요 시간 : 약 55ms
분석
- 인덱스를 타고 있지 않음 -> 인덱싱을 통해 성능 개선 가능성 존재
2.2. 인덱스 생성
cart_item 에서의 조회는 전체 필드를 조회하는 SELECT 절만 존재함, 따라서 커버링 인덱스 생성
CREATE INDEX idx_user_product_full
ON cart_item (user_id, cart_id, product_id, quantity);
Using index로 커버링 인덱스 사용중
[소요시간]
소요 시간 : 약 39ms
55ms -> 39ms로 16ms 감소
분석
- 개선 전에는 인덱스를 타지 않았음
- 커버링 인덱스 생성 후 커버링 인덱스 사용, 실행 소요 시간 39ms 감소
인덱스 적용 후 k6 테스트
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
장바구니 추가 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 32675 | 550ms | 673ms | 181 |
VU 200 | 33562 | 1.07s | 1.26s | 185 |
VU 300 | 30777 | 1.75s | 5.22s | 169 |
테스트 결과 분석
Latency
-
Latency(mean)
- VU 100: 908ms → 550ms (약 39.4% 개선)
- VU 200: 1.93s → 1.07s (약 44.6% 개선)
- VU 300: 2.92s → 1.75s (약 40.1% 개선)
Latency(mean) : 전 구간 40% 이상 개선
-
Latency(P95)
- VU 100: 1.28s → 673ms (약 47.4% 개선)
- VU 200: 2.59s → 1.26s (약 51.4% 개선)
- VU 300: 7.56s → 5.22s (약 30.9% 개선)
Latency(P95) : 약 30 ~ 51% 개선, VU 200 까지 절반 감소, VU 300은 여전히 높지만 2s 이상 단축됨
TPS
- VU 100: 109 → 181 (약 66.1% 개선)
- VU 200: 102 → 185 (약 81.4% 개선)
- VU 300: 101 → 169 (약 67.3% 개선)
TPS : 약 66 ~ 81% 개선, 최대 80% 개선 효과
커버링 인덱스를 통해 원본 row 에 접근한 필요 없기에 눈에 띄는 성능 향상을 보임
항목(각 개선 단계는 이전 단계 포함) | 로직 수정 | 인덱싱 |
---|---|---|
평균 Latency 감소율 | 약 19 ~ 22% | 약 40 ~ 44% |
TPS 증가율 | 약 23 ~ 30% | 약 66 ~ 81% |
- 로직 수정으로 DB 조회 횟수를 줄여 성능 개선 효과를 보임
- 커버링 인덱스를 통해 Latency : 최대 44%, TPS : 최대 81% 성능 개선을 보임