Spring/Redis

태태개발일지 - redis

태태코 2025. 1. 27. 19:02
반응형

인덱스 

DB글에서 많이 다룬 부분이다.

책에 책갈피를 끼고 책의 페이지를 검색하는 것과 유사하다고 보면된다.

 

 

이번 프로젝트에서 확인해야할 부분은 

기존 vs 인덱스 vs 캐시 성능의 차이를 확인하는 것이였다.

 

우선 테스트의 결과는 하단에서 다루고, index를 설정하면서 생각했던 부분을 설명하고자 한다.

 

Query

SELECT *
FROM Screenings s
INNER JOIN Movies m ON s.movie_id = m.movie_id
INNER JOIN Theaters t ON s.theater_id = t.theater_id
WHERE m.title = 'Movie Title 378'
  AND m.genre = 'ACTION'
ORDER BY m.release_date, s.screening_date;

 

쿼리요약:

    상영정보와 영화정보 극장정보를 join하여 원하는 영화에 대한 정보를 가져오는 쿼리다.

 

index:

    where 조건에만 index가 걸리는 줄 알고있었다.
  1. title과 genre의 카디널리티를 고려했다.
    title이 카디널리티가 더 높았기때문에 복합 인덱스를 (title,genre)의 순서대로 걸었다.
  2. 하지만 동적쿼리이기때문에 titile이 안들어올경우 genre만 where조건문에 들어가기 때문에
    genre도 단일 인덱스로 걸어주었다. (title의 경우 복합인덱스에 걸려있기 때문에 인덱스 효과를 볼 수 있다.)
  3. explane 을 통해 쿼리실행 계획을 봤을 때, Screenings는 아무런 index도 사용하지않고, Theaters도 마찬가지였다.
  4. 쿼리에 사용되는 모든 부분에 도움이 되는 부분에 index를 만들어주는 게 맞다고 판단하여, Join 거는 부분에 index를 걸어주었다.
  5. index를 여러개 만들어도 한 테이블에 하나만 사용하는 것을 알고, 가장 효율적인 것 하나두개만 만들어 놓는게 좋다고 판단했다.
  6. order by절에 들어가는 컬럼도 복합인덱스로 걸어주는 것이 좋다. 위에는 상영과 무비가 같이있어서 안걸었다.

효율적인 인덱스를 거는 방법에는 여러가지가 있다.

 

예를 들면 

  1. 인덱스에 있는 컬럼 where절에 사용하기
  2. like 조건앞에서 %(와일드카드) 사용하지 않기 -> 조건절 뒤에 사용하기
  3. 함수나 연산자 사용하지않기 ex)YEAR(birth_date)
  4.  or조건 사용하지 않기
  5. between, in 절 사용하기

 

여기에서는 부하테스트(k6)에 대한 정보도 들어간다.

 

테스트 결과는

 

기본 < 인덱스 < 캐시 순이였고, 

기본 과 인덱스는 큰차이를 보이지 않았지만, 캐시를 사용하고 결과를 봤을 경우 상당히 크게 차이가났다.

 

   

     checks.........................: 97.86% 2153 out of 2200
     data_received..................: 141 kB 13 kB/s
     data_sent......................: 224 kB 21 kB/s
     http_req_blocked...............: avg=204.24µs min=1µs    med=4µs     max=3.19ms   p(90)=648.2µs p(95)=1.84ms  
     http_req_connecting............: avg=169.85µs min=0s     med=0s      max=2ms      p(90)=604.2µs p(95)=1.8ms   
     http_req_duration..............: avg=57.26ms  min=1.77ms med=18.19ms max=648.52ms p(90)=80.87ms p(95)=429.95ms
       { expected_response:true }...: avg=57.72ms  min=3.61ms med=18.31ms max=648.52ms p(90)=83.96ms p(95)=431.8ms 
     http_req_failed................: 0.81%  9 out of 1100
     http_req_receiving.............: avg=119.9µs  min=0s     med=77µs    max=1.73ms   p(90)=242.1µs p(95)=367.09µs
     http_req_sending...............: avg=18.49µs  min=4µs    med=12µs    max=1.07ms   p(90)=33µs    p(95)=44µs    
     http_req_tls_handshaking.......: avg=0s       min=0s     med=0s      max=0s       p(90)=0s      p(95)=0s      
     http_req_waiting...............: avg=57.12ms  min=1.76ms med=18.04ms max=648.37ms p(90)=80.74ms p(95)=429.73ms
     http_reqs......................: 1100   102.470193/s
     iteration_duration.............: avg=1.05s    min=1s     med=1.01s   max=1.65s    p(90)=1.08s   p(95)=1.43s   
     iterations.....................: 1100   102.470193/s
     vus............................: 110    min=110          max=110
     vus_max........................: 110    min=110          max=110

 

k6를 사용하면 이러한 결과가 나오고 receiving 부분에서 tps와 처리 속도를 보며 확인하면된다.

 

테스트의 종류에는

  1. 스모크 테스트
    • 초기 테스트: 서버가 기본적으로 잘 작동하는지 확인.
  2. 부하 테스트
    • 주요 테스트: 일반적인 사용량을 처리할 수 있는지 확인.
  3. 스트레스 테스트
    • 시스템의 최대 처리 용량과 한계점을 알고 싶을 때.
  4. 스파이크 테스트
    • 갑작스러운 트래픽 증가를 시뮬레이션.
  5. 소크 테스트
    • 장기적인 안정성 확인

 

이렇게 있다. 이 테스트를 k6를 사용하여 해결했다.

1. 스모크 테스트

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  vus: 1, // 1명의 사용자
  duration: '30s', // 30초 동안 실행
};

export default function () {
  http.get('http://your-api/movies?movieName=Inception&genre=Sci-Fi');
  sleep(1);
}

 

2. 부하 테스트

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  stages: [
    { duration: '1m', target: 50 }, // 1분 동안 50명의 유저 도달
    { duration: '3m', target: 50 }, // 3분 동안 유지
    { duration: '1m', target: 0 },  // 1분 동안 종료
  ],
};

export default function () {
  http.get('http://your-api/movies?movieName=Inception&genre=Sci-Fi');
  sleep(1);
}

 

3. 스트레스 테스트

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 50 },  // 50명의 유저로 시작
    { duration: '2m', target: 200 }, // 200명의 유저까지 증가
    { duration: '2m', target: 500 }, // 500명의 유저로 테스트
    { duration: '1m', target: 0 },   // 종료
  ],
};

export default function () {
  http.get('http://your-api/movies?movieName=Inception&genre=Sci-Fi');
  sleep(1);
}

 

4. 스파이크 테스트

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  stages: [
    { duration: '10s', target: 200 }, // 10초 동안 200명의 유저 도달
    { duration: '20s', target: 200 }, // 20초 동안 유지
    { duration: '10s', target: 0 },   // 10초 동안 종료
  ],
};

export default function () {
  http.get('http://your-api/movies?movieName=Inception&genre=Sci-Fi');
  sleep(1);
}

 

5. 소크테스트

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  vus: 50, // 50명의 유저
  duration: '1h', // 1시간 동안 실행
};

export default function () {
  http.get('http://your-api/movies?movieName=Inception&genre=Sci-Fi');
  sleep(1);
}

 

반응형

'Spring > Redis' 카테고리의 다른 글

태태개발일지 - redis  (1) 2025.01.27
태태개발일지 -REDIS  (1) 2024.11.12
Spring redis 총정리  (0) 2024.05.27
태태 개발일지(No sql)  (0) 2023.08.03
태태 개발일지 Redis편  (0) 2023.08.02