Spring

[Spring] Redis 기반 세션 스토리지 구축 (3)- Redis vs MySQL 성능비교

J_Dev 2024. 11. 1. 16:17

서론

  • Redis를 세션 스토리지로 변경한 후, 기존 MySQL(JDBC) 기반 세션 스토리지와의 성능 차이를 비교하였습니다.
  • 모든 테스트는 로컬 환경에서 서버를 구축하여 진행했으며, 부하 테스트 도구로 K6를 사용하였습니다.

테스트 개요

1. 테스트 구성

1). 목표

  • 세션 읽기 속도 성능 비교, K6 사용
  • 특정 시간에 사용자가 몰리는 상황을 가정하고, 정보 인증을 위한 GET 요청을 다수 수행
  • 로그인 후 세션 쿠키를 사용하여 사용자 데이터 요청 시, 응답 시간, TPS, 성공률을 측정하여 비교

2). 부하 단계 (Stages)

  • 워밍업: 5초 동안 100명의 가상 사용자로 시작
  • 램프업: 5초 동안 500명까지 증가
  • 피크 부하: 120초 동안 500명 유지

3). 측정 지표

  • Average,P95 Response Time: MySQL 대비 속도 향상 비교
  • TPS: 초당 처리량 비교
  • Success Rate : 성공률 차이 비교

2. 테스트 시나리오

1). 로그인 단계

  • 각 가상 사용자(VU)는 고유한 userId로 로그인 합니다.
  • 로그인 후 세션 쿠키 발급 여부 를 확인합니다
  • 로그인 성공 여부 를 체크합니다.

2). 데이터 조회 단계

  • 로그인 완료 후 1초 대기합니다.
  • 각 사용자별로 다음 작업을 5회 반복합니다.
      1. 세션 쿠키를 포함한 GET 요청 실행
      1. 요청 간 0.1초 간격 유지
      1. 요청 후 0.5초 대기
      1. 각 요청의 응답 시간 기록

3. 테스트 코드

  • JavaScirpt로 k6 테스트코드 작성
  • 각 사용자가 5회씩 GET 요청을 수행
import http from 'k6/http';
import { check, sleep, group } from 'k6';
import { Trend, Rate } from 'k6/metrics';

// 평균 응답 속도를 측정하기 위한 Trend
const responseTime  = new Trend('response_time');
let successRate = new Rate('success_rate');


export const options = {


    stages: [
        { duration: '5s', target: 100 },   // 워밍업
        { duration: '5s', target: 500 },   // 부하 증가
        { duration: '120s', target: 500 },   // 피크 부하 유지
    ],
    thresholds: {
        'response_time': ['avg<200'], // 평균 응답시간 200ms 미만 목표
        'success_rate': ['rate>0.95'] // 성공률 95% 이상 목표  
    }
};

const loginUrl = 'http://localhost:8080/api/login';
const dataUrl = 'http://localhost:8080/api/user-info';

export default function () {
    const jar = http.cookieJar();
    const userId = `user_${__VU}`; // 각 VU마다 고유한 userId 생성

    // 로그인 요청
    group('Login', function () {
        const loginRes = http.post(`${loginUrl}?userId=${userId}`,null,{jar});

        // 서버가 세션 쿠키를 전송했는지 확인
        check(loginRes, {
            'login successful': (res) => res.status === 200,
        });

        if (loginRes.cookies['SESSIONID']) {
            console.log(`VU ${__VU} logged in, session cookie saved.`);
        } else {
            console.error(`VU ${__VU} login failed, no session cookie received.`);
        }
    });



    // 모든 사용자의 로그인 요청이 완료된 후에만 GET 요청 실행
    sleep(1); // 모든 로그인 요청이 끝날 때까지 잠시 대기

    group('Fetch Data', function () {

        for (let i = 0; i < 5; i++) {
            // 2. GET 요청을 세션 쿠키와 함께 날리기
            const getRes = http.get(dataUrl, { jar });

            // 응답 속도를 측정
            responseTime .add(getRes.timings.duration);

            // 체크 성공 여부
            const isSuccess = check(getRes, {
                'status was 200': (r) => r.status === 200,
            });

            successRate.add(isSuccess);
            if (!isSuccess) {
                console.error(`VU ${__VU} 요청 실패`);
            }
            sleep(0.1); // 0.1초 대기, 요청 간격을 줄여 피크 시간 동안 1000개 요청 유도
        }
        sleep(0.5); // 0.5초 대기
    });
}


export function handleSummary(data) {
    // 현재 날짜와 시간을 얻어와 포맷 지정
    const now = new Date();
    const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
    const timeStr = `${String(now.getHours()).padStart(2, '0')}-${String(now.getMinutes()).padStart(2, '0')}`;

    // 파일명에 날짜와 시간 추가
    const fileName = `results/get/get-_500_130s_${dateStr}_${timeStr}.json`;


    return {
        [fileName]: JSON.stringify(data, null, 2)  // 동적으로 생성된 파일명 사용
    };
}

4. 사전테스트

  • K6 테스트 코드가 로그인 요청 및, 유저 정보 정보 GET 요청이 정상적으로 실행되는지 확인합니다.
  • 테스트 결과 : 모든 요청이 정상적으로 작동함을 확인했습니다.

5. 본 테스트

테스트 결과

1) 평균 응답 시간 (Average Response Time)

  • Redis: 0.45ms
  • MySQL: 2.65ms
  • 성능 차이: Redis가 MySQL보다 약 83.02% 더 빠릅니다.

2) P95 응답 시간 (P95 Response Time)

  • Redis: 0.74ms
  • MySQL: 3.76ms
  • 성능 차이: Redis가 MySQL보다 약 80.43% 더 빠릅니다.

3) 초당 처리량 (TPS)

  • Redis: 1,411.66 TPS
  • MySQL: 1,401.71 TPS
  • 성능 차이: Redis가 약 0.71% 더 높습니다.

4). 성공률 (Success Rate)

  • Redis: 100%
  • MySQL: 100%
  • 성공률은 두 시스템 모두 동일합니다.

 


결론

  • Redis는 MySQL에 비해 83% 더 빠른 응답 속도를 보여줍니다.
  • 처리량(TPS)은 두 시스템이 거의 동일한 성능을 보였으며, 안정성 측면에서도 모두 100% 성공률을 기록했습니다.
  • 이를 통해 Redis를 사용해 빠른 응답시간을 갖느 고성능 Session Storage를 구현하는 데 성공했습니다.