본문 바로가기
Log/Experiment

exp009_Redis Cloud 적용 여부에 따른 성능 변화 관찰

by RIEM 2023. 3. 2.

Title

exp009_Redis Cloud 적용 여부에 따른 성능 변화 관찰

Research Question

  • Redis local에서 Redis cloud로 바꾸면 성능에는 어떤 변화가 나타날까?

Summary

이번 실험을 통해 레디스 클라우드의 우수한 성능을 확인했으나, pm2 클러스터 모드라는 변수에 종속되었다는 점을 고려하여 추가적인 테스트가 필요할 것으로 판단된다. 그리고 현재까지 왜 PM2 클러스터 모드 적용 시 TPS가 개선되지 않는지에 대한 문제는 계속 고민해봐야 겠다.

  • t2 medium PM2 Cluster mode(CPU v2) 성능을 가진 어플리케이션 서버에 레디스 로컬과 레디스 클라우드의 성능 차이를 비교했다
  • 로컬 레디스는 TPS 1121, MTT 852이었던 반면 클라우드 레디스는 TPS 1415, MTT 675로 더 나은 성능을 기록했다.
  • 이를 포화점 관점에서 보면 더 흥미로운데, 로컬 레디스는 포화점이 TPS 1004, VUser 155명인 반면 클라우드 레디스는 TPS 1422, VUser 481명을 기록했다. 포화점 관점에서 한계 처리량(TPS)은 약 41% 증가했고 한계 VUser 수는 약 210% 대폭 증가했다.

Background Information

Situation

  • 부하 테스트 툴 nGrinder을 활용하여 경매 래플 어플리케이션 시스템의 서버 부하 테스트 진행중인 상황.

Current Experiment

  • test-pyramid-20230301-005 : 레디스 Cloud
  • test-pyramid-20230301-006 : pm2 클러스터 모드 + 레디스 Cloud

Related Experiment

  • test-pyramid-20230301-004 : pm2 클러스터 모드 + 레디스 local

Procedures

Screen Shot 2023-03-02 at 12 11 19 AMScreen Shot 2023-03-02 at 12 07 35 AM

  • VUser: 1000명
  • Duration : 10mins

Redis Cloud 적용

Redis를 위한 nest.js모듈은 ioredis를 사용했다. Redis 적용을 도와주는 패키지들이 많아서 이것저것 써봤는데, 신통치 않은 것들이 적지 않았다. 이 npm 패키지는 2023년 3월 1일 기준 위클리 다운 수 5만 이상이고 이 수치도 꾸준히 상승세에 있다. 게다가 문서도 잘 정리되어있어서 편리했다.

https://www.npmjs.com/package/@liaoliaots/nestjs-redis

모듈

...
import { RedisModule } from '@liaoliaots/nestjs-redis';

@Module({
  imports: 
  ...
    RedisModule.forRoot({
      config: {
        host: process.env.REDIS_HOST,
        port: Number(process.env.REDIS_PORT),
        password: process.env.REDIS_PW
      }
    })
 ],
  controllers: [RafflesController],
  providers: [RafflesService, RafflesGateway],
  exports: [RafflesService],
})
export class RaffleModule {}

 

서비스 레이어(컨트롤러는 생략)

import { InjectRedis, DEFAULT_REDIS_NAMESPACE } from '@liaoliaots/nestjs-redis';
import Redis from 'ioredis';

@Injectable()
export class RafflesService {
  constructor(
    @InjectRedis() private readonly redis: Redis,
  ) { }

  async findAllWithRedisCloud() {

    const cachedResult = await this.redis.get('raffles');


    if (cachedResult) {
      console.log(`Raffle result from Redis :D `)
      return JSON.parse(cachedResult);
    }
    const result = await this.raffleRepository
      .createQueryBuilder('raffle')
      .leftJoinAndSelect('raffle.product', 'product')
      .leftJoinAndSelect('raffle.bid', 'bid')
      .select([
        'raffle.raffleId',
        'product.productImage',
        'product.productColor',
        'product.productModel',
        'product.productName',
        'product.releasePrice',
        'raffle.dateEnd',
        'bid.bidId'
      ])
      .orderBy('raffle.dateEnd', 'DESC')
      .addOrderBy('raffle.raffleId', 'DESC')
      .take(10)
      .getMany();

    await this.redis.set('raffles', JSON.stringify(result), 'EX', 10)

    console.log(`normal result`)
    return result;

    }
}

Data Recording & Analysis

test는 총 2개를 진행했다.

  • test-pyramid-20230301-005 : Redis cloud만
  • test-pyramid-20230301-006 : Redis cloud + pm2 cluster모드 적용

테스트를 두개 진행한 이유는 pm2 클러스터 적용 여부에 따라 성능 차이도 알고싶었기 때문이다. 테스트 결과, 동일한 Redis Cloud 사용 했더라도 클러스터 적용하지 않았을 경우 웹 서버 CPU 사용률이 65.4%에 불과했던 반면 클러스터 모드 적용 시에는 94.7%까지 상승했다. 클러스터 모드 사용 시 TPS는 1459에서 1415로 오히려 소폭 감소했다. 클러스터 모드를 통해 특별한 성능 개선점을 찾지 못했다.

하지만 내가 알고싶은 것은 이것이 아니다. 과연 Redis 로컬과 Redis 클라우드의 차이를 알고싶었다.

Screen Shot 2023-03-02 at 3 18 52 AM

레디스 로컬과 클라우드 테스트 2개를 비교해보자.

test-pyramid-20230301-004

  • Redis : local
  • pm2 cluster -i 2
  • TPS : 1121
  • MTT : 852
  • Executed Tests : 643,685

test-pyramid-20230301-006

  • Redis : cloud
  • pm2 cluster -i 2
  • TPS : 1,415
  • MTT: 675
  • Executed Tests : 812,606

가장 눈에 띄는 요소는 TPS다. 로컬 레디스를 적용한 로직은 TPS 1121이었는데, 클라우드 적용 이후 1415 TPS를 기록했는데, 이는 약 26% 증가한 수치다. MTT의 경우 852에서 675로 Latency는 약 20% 감소했다.

Latency가 개선된 부분은 예상하지 못했다. 처음 클라우드 레디스를 적용했을 때 POSTMAN으로 테스트를 해보았는데, 단일 요청에 대한 응답 속도가 200ms 정도 나왔다. 이는 50ms 미만의 로컬 레디스 로직보다 매우 느린 속도여서 클라우드도 어쩔 수 없이 느리긴 느리구나라는 생각을 했었다. 하지만 실제 성능 테스트 결과 1400대 TPS를 기록한 것을 보니 흥미로웠다. 어떻게 로컬이 아니라 외부 DB에서 데이터를 조회하는데 로컬만큼 성능이 나왔을까 궁금하다.

Screen Shot 2023-03-02 at 3 53 45 AM


두 테스트들을 그래프로 비교하면 흥미로운 결과가 또 나타난다. 클라우드 레디스를 적용했을 때는 TPS가 약 1422 부터 더 이상 늘어나지 않는다. 더 이상 TPS가 늘어나지 않는 포화점(Saturation Point)가 1422 TPS 부근이다. 반면 로컬 레디스의 경우 약 1004 TPS부터 상승세를 잃는다. 클라우드 레디스의 시간당 처리량의 한계점이 약 400 TPS 더 높다고 볼 수 있다.

이를 VUser 관점에서 본다면 클라우드 로컬의 경우 유저 포화점(Saturated users)이 155명이다. 155명 이상 모이게 되면 시스템의 처리량이 더 이상 증가하지 않는다는 말이다. 반면 레디스 클라우드의 경우 유저 포화점이 약 3배 지점인 481명이다.

Conclusion

여기서 한 가지 변수를 짚고 넘어가야할 것 같다. 위 테스트 비교는 pm2 클러스터모드를 적용했는데, 클러스터 모드를 적용하지 않은 경우는 아직 고려되지 않은 점은 인정해야 할 것이다. 왜냐하면 Redis local을 싱글 프로세스로 수행했을 때 처리량이 매우 우수했기 때문이다.(test-pyramid-20230301-002 테스트 시, TPS가 약 1634, MTT 593을 기록)

이번 실험을 통해 레디스 클라우드의 우수한 성능을 확인했으나, pm2 클러스터 모드라는 변수에 종속되었다는 점을 고려하여 추가적인 테스트가 필요할 것으로 판단된다. 그리고 현재까지 왜 PM2 클러스터 모드 적용 시 TPS가 개선되지 않는지에 대한 문제는 계속 고민해봐야 겠다.

Summary

  • t2 medium PM2 Cluster mode(CPU v2) 성능을 가진 어플리케이션 서버에 레디스 로컬과 레디스 클라우드의 성능 차이를 비교했다
  • 로컬 레디스는 TPS 1121, MTT 852이었던 반면 클라우드 레디스는 TPS 1415, MTT 675로 더 나은 성능을 기록했다.
  • 이를 포화점 관점에서 보면 더 흥미로운데, 로컬 레디스는 포화점이 TPS 1004, VUser 155명인 반면 클라우드 레디스는 TPS 1422, VUser 481명을 기록했다. 포화점 관점에서 한계 처리량(TPS)은 약 41% 증가했고 한계 VUser 수는 약 210% 대폭 증가했다.

Appendix

test-pyramid-20230301-005(pm2 fork)

nGrinder Report

Screen Shot 2023-03-02 at 12 24 28 AM

 

Screen Shot 2023-03-02 at 12 24 44 AM

Application Server

Screen Shot 2023-03-02 at 12 35 10 AM

RDS

Screen Shot 2023-03-02 at 12 35 46 AM

nGrinder Agent 1

Screen Shot 2023-03-02 at 12 36 17 AM

nGrinder Agent 2

Screen Shot 2023-03-02 at 12 36 31 AM

test-pyramid-20230301-006(pm2 cluster mode)

cluster mode 적용

Screen Shot 2023-03-02 at 1 02 57 AM

nGrinder Report

Screen Shot 2023-03-02 at 1 23 22 AMScreen Shot 2023-03-02 at 1 23 35 AM

Application Server

Screen Shot 2023-03-02 at 1 27 51 AM

RDS

Screen Shot 2023-03-02 at 1 25 42 AM

nGrinder Agent 1

Screen Shot 2023-03-02 at 1 26 11 AM

nGrinder Agent 2

Screen Shot 2023-03-02 at 1 26 38 AM

댓글