Skip to main content Link Menu Expand (external link) Document Search Copy Copied

created at 2024-01-03

Table of contents

  1. 성능개선 이전에 기존 서비스의 성능측정
    1. 사용 DB Active Connection(pgAdmin)
    2. 커스텀 지표(Grafana + Prometheus + micrometer)
  2. Chatting 테이블 PK 를 String 에서 Long 타입으로 변경 후 seq 에 따라 자동으로 삽입되도록 설정
    1. Chat 의 id 타입 변경 시 성능차이가 나는 이유는 뭘까요?
      1. Long 타입 ID의 이점
      2. String 타입 ID 이점

성능개선 이전에 기존 서비스의 성능측정

10분간 POST /api-chat/chat 의 퍼포먼스를 ramp-up VUSER 300 으로 측정하였습니다. 아래의 테이블은 Thread warm up 이전과 이후 차이를 관찰합니다. 그리고 그래프는 웜업 이후의 그래프입니다.

이후 성능개선 비교는 warm-up 이후를 기준으로 비교합니다.

MetricBefore Thread Warm-upAfter Thread Warm-upChange
Total Tests-220,313-
Error Rate0.00%(0)0.00%(7)-
TPS 평균 (Average)302.62377.2424.61% 🟢
TPS p50303.50390.2528.56% 🟢
TPS p95104.83270.60157.59% 🟢
TPS p9963.1592.5846.64% 🟢
TPS p99.959.4134.05-42.71% 🔴
MTTFB 평균 (Average)594.34 ms496.27 ms-16.51% 🟢
MTTFB p50580.98 ms480.31 ms-17.35% 🟢
MTTFB p951049.11 ms882.81 ms-15.86% 🟢
MTTFB p991292.91 ms1163.81 ms-9.99% 🟢
MTTFB p99.91382.09 ms1225.86 ms-11.29% 🟢
MTTFB 차이 평균 (Average Difference)135.38 ms106.51 ms-21.33% 🟢
MTTFB 평균적인 변동률 (Average Variability)21.30%20.77%-2.49% 🟢

image

image

사용 DB Active Connection(pgAdmin)

image

커스텀 지표(Grafana + Prometheus + micrometer)

image

Chatting 테이블 PK 를 String 에서 Long 타입으로 변경 후 seq 에 따라 자동으로 삽입되도록 설정

MetricBeforeAfterChange
Total Tests220,313236,9577.54% 🟢
Error Rate0.00%(7)0.00%(0)-
TPS 평균377.24404.367.18% 🟢
TPS p50390.25420.507.76% 🟢
TPS p95270.60277.902.69% 🟢
TPS p9992.5864.34-30.53% 🔴
TPS p99.934.0543.1726.74% 🟢
MTTFB 평균496.27 ms456.42 ms-8.03% 🟢
MTTFB p50480.31 ms431.84 ms-10.07% 🟢
MTTFB p95882.81 ms799.67 ms-9.41% 🟢
MTTFB p991163.81 ms1130.67 ms-2.84% 🟢
MTTFB p99.91225.86 ms1275.62 ms4.06% 🔴
MTTFB 차이 평균106.51 ms74.02 ms-30.46% 🟢
MTTFB 평균적인 변동률20.77%15.27%-26.60% 🟢

image

image

image

대부분의 성능지표 수치가 개선되었습니다! 특히 MTTFB 평균차이가 30.5% 개선되었습니다. 원래는 변동폭이 심했지만, 좀 더 완화된 것이죠. 가장 오래걸린 시간 지표에서 ChatRepository 의 save 를 봤을 때, 수치가 많이 내려가 것이 확인되었습니다.
단순히 채팅 id 타입을 String 에서 Long 타입으로 변경하고 자동 increase 되도록 설정만 했는데 어떻게 성능이 향상된 것일까요?

Chat 의 id 타입 변경 시 성능차이가 나는 이유는 뭘까요?

Postgresql 은 기본인덱싱 전략이 B 트리로 되어있어요. 그리고 B 트리는 어떤 데이터가 삽입될 때 조건부로 리밸런싱이 일어나면서 추가적인 연산이 소모됩니다. 바로 이점에서 데이터의 PK 타입에 따른 성능차이가 발생합니다. PK 타입이 String 타입에 이 String 값이 무작위라면(저는 Hash 값) 리밸런싱이 매우 자주 일어나게되죠. 반면, PK가 Long 타입에 SERIAL 자동증가된다면 B 트리 리밸런싱이 거의 필요하지 않게됩니다. 즉, 인덱스 리밸런싱에 소모되는 추가적인 연산이 줄어들어 성능이 향상되는 것이죠!

다시 한번 정리해 보겠습니다.

Long 타입 ID의 이점

  1. 크기와 효율성: Long 타입은 64비트(8바이트)의 크기를 가지며, 이는 UUID(128비트, 16바이트)보다 작습니다. 작은 크기는 인덱스의 메모리 사용량을 줄이고, 디스크 I/O를 최소화합니다. 그러니까 “key의 크기가 작을수록 노드의 차수가 증가하고 block 단위 디스크 i/o 가 발생하는 빈도수가 낮아진다“는 것이죠.
  2. 순차적 증가: Long 타입 ID는 주로 DB 에서 시퀀스를 받아와 순차적으로 증가시킵니다. 이는 B-트리의 균형을 유지하며, 새로운 데이터가 트리의 맨 끝에 추가되므로 재조정(rebalancing)이 거의 필요하지 않습니다. 삽입 성능이 뛰어나겠죠? 만약 UUID 로 하면 진짜 여기저기 추가되기 때문에 리밸런싱이 계속해서 일어나야합니다. 쉽게 말하면 Long 은 여러 노드들의 빈 자리를 차근차근 채워나가지만 String 은 노드들의 빈자리를 무작위로 채워나가는 것이기때문에 리밸런싱 빈도수가 높습니다.
  3. 범위 검색 최적화: 숫자 기반의 ID는 범위 검색에 적합합니다. 예를 들어, 특정 ID 범위의 데이터를 효율적으로 검색할 수 있습니다. 채팅의 경우에는 아무래도 채팅id 가 그룹처럼 붙어있습니다. 즉, 어떠한 범위가 있기 때문에 Long 타입 id 가 유리합니다.

String 타입 ID 이점

String 값이 특별한 의미가 있을 때 : 예로 제품 이름, 주소, 설명 등을 색인화하고 검색할 때 String 키는 효과적입니다. 하지만 Chat id 의 경우 특별한 의미가 없기때문에 Long 타입이 더 성능면에서 이점을 가져다 줄거에요.