DB 성능 측정
on 조잘조잘
들어가기전…
안녕하세요 피카입니다.
이전의 글에서 리플리케이션과 인덱스를 적용하여 DB의 성능을 향상 시켰습니다. 이 글에서는 실제로 성능 향상을 수치로 나타내어 얼만큼의 성능이 증가했는지 알아보기 위해 작성한 글입니다.
테스트 환경
DB 구성은 3가지로 나뉘어 테스트합니다.
- 단일 DB
- 리플리케이션 적용
- 리플리케이션 + 인덱스 적용
데이터는 DB에 선호도 데이터 53만건을 넣었습니다.
테스트 도구는 k6로 이루어집니다.
테스트 시나리오는 메인페이지 조회(읽기), 선호도 수정(쓰기) 2가지 시나리오로 구성되어있습니다.
k6 결과 출력
테스트를 들어가기 전 k6로 출력되는 결과가 무엇인지 확인할 필요가 있습니다. 자세한 정보는 k6 공식문서 에서 확인할 수 있습니다.
다음은 k6의 결과를 나타내는 지표 예시입니다. 간단히 하나씩 살펴보겠습니다.
- data_received: 수신된 데이터의 양입니다.
- data_sent: 전송된 데이터의 양입니다.
- http_req_blocked: 요청을 시작하기 전에 차단된 시간(사용 가능한 TCP 연결 슬롯 대기)입니다.
- http_req_connecting: 원격 호스트에 대한 TCP 연결을 설정하는 데 소요된 시간입니다.
- http_req_duration: 요청에 대한 총 시간입니다. (즉, 초기 DNS 조회/연결 시간 없이 원격 서버가 요청을 처리하고 응답하는 데 걸린 시간)
- http_req_failed: setResponseCallback 에 따른 실패한 요청 비율입니다.
- http_req_receiving: 원격 호스트에서 응답 데이터를 수신하는 데 소요된 시간입니다.
- http_req_sending: 원격 호스트에 데이터를 보내는 데 소요된 시간입니다.
- http_req_tls_handshaking: 원격 호스트와 TLS 세션을 핸드셰이킹하는 데 소요된 시간입니다.
- http_req_waiting: 원격 호스트의 응답을 기다리는 데 소요된 시간입니다.
- http_reqs: k6이 생성된 총 HTTP 요청 수입니다.
- iteration_duration: 기본/메인 함수의 전체 반복을 완료하는 데 걸린 시간입니다.
- iterations: 테스트의 VU가 JS 스크립트를 실행한 총 횟수입니다.
- vus: 현재 활성 가상 사용자 수입니다.
- vus_max: 최대 가상 사용자 수입니다.
여러가지 많지만 저희는 성능 테스트를 하기 때문에 http_req_duration
또는 http_req_waiting
만 볼 것입니다. 이 글에서는 http_req_waiting
을 기준으로 측정하겠습니다.
단일 DB
읽기 시나리오
http_req_waiting: 17.6s
쓰기 시나리오
http_req_waiting: 356.12ms
리플리케이션 적용
읽기 시나리오
http_req_waiting: 10.08s
쓰기 시나리오
http_req_waiting: 363.88ms
인덱스 + 리플리케이션 적용
읽기 시나리오
http_req_waiting: 9.36s
쓰기 시나리오
http_req_waiting: 440.38ms
정리
리플리케이션 적용 후
읽기는 1.74배 (17.6s/10.08s), 쓰기는 0.97배(356.12ms/363.88ms)로 쓰기는 거의 변동이 없고 읽기는 매우 크게 향상된 것을 확인할 수 있습니다. 실제로 리플리케이션은 여러 대의 replica를 통해 분산시켜 읽기 성능을 향상시키는 것을 목적으로 하였으므로 소기 목적을 달성했다고 볼 수 있습니다.
인덱스 + 리플리케이션 적용 후
읽기는 1.88배(17.6s/9.36s), 쓰기는 0.8배(356.12ms/440.38ms)로 성능의 변동이 있습니다.
실제로 인덱스는 쓰기 성능을 희생시켜 읽기 능력을 향상시키기 때문에 이러한 결과가 나왔다고 볼 수 있습니다.
느낀 점
성능 개선을 했지만, 아직 데이터가 많을 경우 10초나 걸리기 때문에 성능 개선이 더 필요하다고 느껴집니다.
따라서 추후에 Optimizer 실행 계획을 분석하는 쿼리 튜닝을 적용해 볼 예정입니다.