개요
[Spring] Spring에 Redis를 사용하는 방법
개요 개인 프로젝트에서 Refresh Token 정보를 In-memory DB로 저장하기로 결정하였다. 이 글에서는 Spring에서 Redis를 사용하는 방법을 알아보고, 프로젝트에 어떻게 적용시켰는지 설명하려고 한다. Sprin
davidy87.tistory.com
저번 글에서 Spring에 Redis를 연동하여 사용하는 방법에 대해 알아보았다. 글의 내용 중에서 Redis를 프로젝트에 사용하는 방법에는 RedisTemplate과 RedisRepository가 있다고 설명하였다.
이후에 문득, RedisTemplate과 RedisRepository를 사용하는 것은 과연 성능 차이가 있을까? 라는 궁금증이 생겼고, 이를 해결하기 위해 이 두 방법을 사용한 Spring 애플리케이션을 통해 간단한 성능 테스트를 진행해보기로 하였다.
설정
프로젝트 환경
먼저 테스트는 아래와 같은 환경에서 진행하였다.
- Java 17
- Spring Boot 3.2.4
프로젝트 코드
먼저, 아래와 같이 Redis Entity 코드를 작성했다.
@ToString
@Getter
@NoArgsConstructor
@RedisHash("refresh-token")
public class RefreshToken {
@Id
private String id;
private String token;
private LocalDateTime refreshTime;
@Builder
public RefreshToken(String id, String token, LocalDateTime refreshTime) {
this.id = id;
this.token = token;
this.refreshTime = refreshTime;
}
}
그리고, 테스트에 사용할 유틸리티 클래스도 작성했다.
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class TestUtils {
public static String getRandomId() {
SplittableRandom random = new SplittableRandom();
return String.valueOf(random.nextInt(1, 20_001));
}
public static String getRandomUUID() {
return UUID.randomUUID().toString();
}
}
RedisRepository
그 다음에는 RedisRepository 테스트를 위한 controller와 repository 코드를 작성했다.
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {
}
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/redis-repository")
@RestController
public class RedisRepositoryApiController {
private final RefreshTokenRepository refreshTokenRepository;
@PostMapping("/save")
public String saveToRedisRepository() {
RefreshToken refreshToken = RefreshToken.builder()
.id(TestUtils.getRandomId())
.token(TestUtils.getRandomUUID())
.refreshTime(LocalDateTime.now())
.build();
log.info(">>>>> [save] refresh token: {}", refreshToken);
refreshTokenRepository.save(refreshToken);
return "success";
}
@GetMapping("/get")
public String getFromRedisRepository() {
refreshTokenRepository.findById(TestUtils.getRandomId());
return "success";
}
}
RedisTemplate
마지막으로, RedisTemplate 테스트를 위한 configuration과 controller 코드를 작성하였다.
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
@RequiredArgsConstructor
@RequestMapping("/redis-template")
@RestController
public class RedisTemplateApiController {
private final RedisTemplate<String, Object> hashRedisTemplate;
private final StringRedisTemplate stringRedisTemplate;
@PostMapping("/save")
public String saveToHashRedisTemplate() {
RefreshToken refreshToken = RefreshToken.builder()
.id(TestUtils.getRandomId())
.token(TestUtils.getRandomUUID())
.refreshTime(LocalDateTime.now())
.build();
Jackson2HashMapper mapper = new Jackson2HashMapper(true);
Map<String, Object> hash = mapper.toHash(refreshToken);
hashRedisTemplate.opsForHash().putAll("refresh-token:" + refreshToken.getId(), hash);
return "success";
}
@GetMapping("/get")
public String getFromHashRedisTemplate() {
String id = TestUtils.getRandomId();
hashRedisTemplate.opsForHash().get("refresh-token:" + id, id);
return "success";
}
}
RedisTemplate은 RedisRepository가 entity를 저장하는 방식과 최대한 유사하게 맞추기 위해 hash로 저장하는 방식을 사용했다.
테스트 도구
성능 측정 도구로는 Apache Jmeter를 사용하였다. 간단한 성능 테스트이기 때문에 다른 도구는 사용하지 않았고, Jmeter를 통해 측정된 수치로만 비교하였다.
측정 및 결과
측정 전, Jmeter에서 Thread group은 아래와 같이 설정했다.
매 loop당 2000개의 thread가 작업을 실행하고 총 10번을 반복하도록 설정했다.
RedisRepository
저장 성능 측정
RedisRepository로 데이터를 저장했을 때, 다음과 같은 측정 결과가 나왔다.
- Average response time: 180ms
- Throughput: 5505.1/sec
조회 성능 측정
RedisRepository로 데이터를 조회했을 때는 다음과 같은 측정 결과가 나왔다.
- Average response time: 27ms
- Throughtput: 9319.7/sec
RedisTemplate
저장 성능 측정
RedisTemplate으로 데이터를 저장했을 때는 다음과 같은 측정 결과가 나왔다.
- Average response time: 338ms
- Throughput: 3172.6/sec
조회 성능 측정
RedisTemplate으로 조회했을 때는 다음과 같은 측정 결과가 나왔다.
- Average response time: 21ms
- Throughput: 9358.9/sec
결과 비교
측정 결과를 비교해보면 조회 성능은 RedisRepository와 RedisTemplate 둘 다 비슷한 결과를 보여줬지만, 저장 성능은 RedisRepository가 더 뛰어나다는 것을 확인할 수 있었다.
'Spring > Spring Data' 카테고리의 다른 글
[Spring] Spring에 Redis를 사용하는 방법 (0) | 2024.03.28 |
---|