


운영 중인 앱: 축잘알 테스트 (구글 플레이)
🚀 Redis로 유저 랭킹 조회, 정말 더 빠를까?
게임이나 퀴즈 서비스에서 랭킹 기능은 빠질 수 없다.
근데 어떻게 불러오느냐에 따라 체감 속도는 완전히 달라진다.
그래서 직접 MySQL vs Redis 성능을 비교해봤다.
과연 Redis는 정말 빠를까?
✅ 기존 방식: MySQL로 랭킹 조회
처음엔 이렇게 했다:
- 10분마다 랭킹 데이터를 UserRankInfo 테이블에 저장
- 요청이 올 때마다 MySQL에서 다시 조회
@Query(nativeQuery = true, value =
"SELECT * FROM front_user_info WHERE total_quiz_count > 30
ORDER BY percentage_of_answer DESC LIMIT 100")
List<FrontUserInfo> getPlayerTop100();
이 방식은 데이터가 많아질수록 점점 느려졌다.
✅ 개선 방식: Redis 캐싱 (Sorted Set 활용)
🔄 랭킹 업데이트 방식
- 10분마다 Redis에 Top 100 저장
- ZSet으로 정렬 자동 처리
- 유저 정보를 JSON으로 직렬화해서 저장
redisTemplate.opsForZSet().add("quiz:rank", jsonUserRankInfo, score);
score는 정답률이고, ZSet에서 이걸 기준으로 정렬해준다.
🔍 캐싱 조회 방식
- Redis에서 정렬된 TOP 100 데이터를 조회
- JSON을 객체로 변환하여 반환
Set<String> redisSet = redisTemplate.opsForZSet().reverseRange("quiz:rank", 0, 99);
List<UserRankInfo> redisResult = redisSet.stream()
.map(json -> objectMapper.readValue(json, UserRankInfo.class))
.toList();
✅ 테스트 코드
@Test
@DisplayName("✅ MySQL vs Redis 랭킹 조회 성능 비교")
void compareMysqlAndRedisRankLoadPerformance() throws JsonProcessingException {
List<Double> mysqlTimes = new ArrayList<>();
List<Double> redisTimes = new ArrayList<>();
for (int i = 0; i < TEST_REPEAT; i++) {
// MySQL 성능 측정
long mysqlStart = System.nanoTime();
List<UserRankInfo> mysqlResult = userRankRepository.findAll();
long mysqlEnd = System.nanoTime();
mysqlTimes.add((mysqlEnd - mysqlStart) / 1_000_000.0);
// Redis 성능 측정
long redisStart = System.nanoTime();
Set<String> redisSet = redisTemplate.opsForZSet().reverseRange("quiz:rank", 0, 99);
List<UserRankInfo> redisResult = redisSet.stream()
.map(json -> {
try {
return objectMapper.readValue(json, UserRankInfo.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
long redisEnd = System.nanoTime();
redisTimes.add((redisEnd - redisStart) / 1_000_000.0);
}
printStats("MySQL", mysqlTimes);
printStats("Redis", redisTimes);
}
📊 성능 테스트 결과 (평균 100회 반복 측정)
100번 반복 테스트로 평균 시간 비교해봤다:
항목 | 평균 시간 | 최소 | 최대 | 표준 편차 |
MySQL | 6.38 ms | 3.20 ms | 89.31 ms | 8.47 ms |
Redis | 2.11 ms | 0.91 ms | 22.13 ms | 2.24 ms |
📌 결론: 자주 조회되는 랭킹이라면 Redis가 답
✅ 평균 속도 기준으로 Redis는 MySQL보다 약 3배 빠름
✅ 최대 응답 시간도 Redis가 훨씬 더 안정적
✅ 응답 시간 편차도 낮아서 일관된 UX 제공 가능
💡 자주 조회되고, 자주 안 바뀌는 데이터는 무조건 캐싱이 답이다.
ZSet 덕분에 정렬도 따로 할 필요 없이 깔끔하게 처리된다.
🧩 보너스: Redis가 비어 있다면?
Redis는 TTL이나 서버 재시작으로 데이터가 비어 있을 수 있다.
이를 대비한 나의 방법은:
Redis가 비어 있으면 MySQL에서 다시 데이터를 불러와 Redis를 다시 채워 넣는 방식
(이후 찾아보니 Cache-Aside Pattern 패턴이라고 함)
📌 이 방법으로 항상 빠른 랭킹 응답을 보장할 수 있다.
🧠 정리하며
이번 테스트를 통해
랭킹 기능 하나에도 성능, 안정성, 사용자 경험 모두 고려해야 한다는 걸 다시 느꼈다.
빠르고 일관된 응답 속도 = 사용자 만족도라는 걸 실제로 체감했다.
'혼자공부한거' 카테고리의 다른 글
혼자 만든 앱에 무중단 배포 적용해보기 – Jenkins, Docker, Nginx (0) | 2025.04.24 |
---|---|
랜덤 퀴즈 데이터 추출, 어떤 방식이 가장 빠를까? (MySQL vs Redis vs Java) (2) | 2025.04.16 |
키클락 취약점 살펴보기 (CVE-2024-8698) (1) | 2024.12.01 |
SSO 란 무엇일까 (0) | 2024.11.22 |
JWT 토큰 (0) | 2024.05.24 |