티스토리 뷰
이전 글에서 자세히 다루지 못 했던 Redis Configuration을 뜯어보려고 한다.
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
redisConfiguration.setHostName(host);
redisConfiguration.setPort(port);
return new LettuceConnectionFactory(redisConfiguration);
}
@Primary
@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
RedisConnectionFactory이란?
RedisConnectionFactory는 Redis 데이터베이스와의 연결을 설정하는 역할이다.
Redis 서버와의 연결을 만들고 관리를 담당하며,
Spring Data Redis에서는 LettuceConnectionFactory와 JedisConnectionFactory가 가장 일반적으로 사용된다.
Lettuce vs Jedis
참고 URL : https://redis.com/blog/jedis-vs-lettuce-an-exploration/
위는 Redis 공식 사이트에서 Lettuce와 Jedis를 설명한 글 중 Lettuce의 일부를 캡쳐한 내용이다.
Lettuce는 비동기(동기도 지원함) 및 리액티브 프로그래밍을 지원하여 더 뛰어난 성능과 확장성을 제공한다고 한다.
스프링부트에서는 LettuceConnectionFactory를 이용해 Lettuce 라이브러리를 기반으로 Redis와 연결한다.
public class LettuceSetGet {
private static final String YOUR_CONNECTION_STRING = "redis://:foobared@yourserver:6379/0";
public static void main(String[] args) {
RedisClient redisClient = RedisClient.create(YOUR_CONNECTION_STRING);
StatefulRedisConnection<String, String> connection = redisClient.connect();
RedisCommands<String, String> sync = connection.sync();
sync.set("foo", "bar");
String result = sync.get("foo");
connection.close();
redisClient.shutdown();
System.out.println(result); // "bar"
}
}
얼핏 보기에 상당히 단순 연결을 수행하는데만 해도 복잡하다고 느껴진다.
이렇게 복잡한 이유는 connection이 비동기 기능을 지원하기 때문이다.
비동기를 구현한 코드를 보면, 처음 단일 연결 할 때 주어진 커넥션으로 비동기적인 부분을 해결할 수 있다.
public class LettuceAsync {
private static final String YOUR_CONNECTION_STRING = "redis://:foobared@yourserver:6379/0";
public static void main(String[] args) {
RedisClient redisClient = RedisClient.create(YOUR_CONNECTION_STRING);
StatefulRedisConnection<String, String> connection = redisClient.connect();
RedisAsyncCommands<String, String> async = connection.async();
final String[] result = new String[1];
async.set("foo", "bar")
.thenComposeAsync(ok -> async.get("foo"))
.thenAccept(s -> result[0] = s)
.toCompletableFuture()
.join();
connection.close();
redisClient.shutdown();
System.out.println(result[0]); // "bar"
}
}
위 역시 Redis 공식 사이트에서 발췌한 글이다.
더 적은 기능을 제공하지만 더 쉽게 Redis 클러스터와의 연결을 지원한다고 한다.
public class JedisSetGet {
private static final String YOUR_CONNECTION_STRING = "redis://:foobared@yourserver:6379/0";
public static void main(String[] args) {
Jedis jedis = new Jedis(YOUR_CONNECTION_STRING);
jedis.set("foo", "bar");
String result = jedis.get("foo");
jedis.close();
System.out.println(result); // "bar"
}
}
코드를 보면 확실히 Lettuce보다 쉽고 직관적이다.
위와 코드와 같이 Jedis는 쉬운 사용성이 장점이지만, 동기적으로 동작한다는 한계가 있다.
비동기적인 부분을 지원하긴 한다. JedisPool을 이용해 멀티쓰레드 환경에서 동작하도록 할 수 있다.
public class JedisMultithreaded {
private static final String YOUR_CONNECTION_STRING = "redis://:foobared@yourserver:6379/0";
public static void main(String[] args) {
JedisPool pool = new JedisPool(YOUR_CONNECTION_STRING);
List<String> allResults = IntStream.rangeClosed(1, 5)
.parallel()
.mapToObj(n -> {
Jedis jedis = pool.getResource();
jedis.set("foo" + n, "bar" + n);
String result = jedis.get("foo" + n);
jedis.close();
return result;
})
.collect(Collectors.toList());
pool.close();
System.out.println(allResults); // "bar1, bar2, bar3, bar4, bar5"
}
}
하지만, Jedis가 동기적으로 동작한다는 부분에는 변함이 없어
모든 풀이 사용 중일 경우 요청과 응답 사이에 블로킹이 발생해 어느정도의 유휴상태에 빠질 수 있다고 한다.
그래서 뭘 쓸꺼야?
위 참고 URL을 쭉 읽어보면, "상황에 따라" 결정하라고하며 어떤게 더 좋다고 결정짓지는 않았다.
하지만 동기적 연결만 지원한다는 건 극단적인 환경(트래픽이 몰리는 상황)에서 병목을 발생시키는 등 한계를 보일 수 있는 문제라 생각이 든다.
또한 Jedis는 Redis의 클러스터 모드를 지원하지 않는다고 한다.
그래서인지 최신 버전의 Spring Data Redis에서는 비동기 및 리액티브 프로그래밍을 지원하는
Lettuce를 사용한 LettuceConnectionFactory가 권장된다고 한다.
RedisTemplate이란?
설정만하고 직접사용하지 않기 때문에 글로만 짧게 정리하고 넘어간다.
RedisTemplate는 Redis 데이터베이스와 상호작용하기 위한 설정을 담은 클래스이다.
이 클래스는 Redis 연결을 통해 데이터를 저장하고 검색하기 위한 다양한 메서드를 제공한다.
RedisTemplate을 이용해 직접 Redis와 연결 후 CRUD를 실행 할 수도 있지만
Spring Data의 CrudRepository를 이용하면 더 간단하게 사용할 수 있기 때문에 직접 사용하는 경우는 드물다.
마치며
별 생각없이 Lettuce를 쓰고 있었는데, 다른 개발자분이 GPT한테 물어보니 Jedis를 썼다고 해서 이 내용을 조금 더 알아봤다.
Configuration부분은 늘 숨겨져 있어 자세히 알기 힘들었던 부분 같다.
아는만큼 보인다는걸 다시한번 느꼈다.
'개발 > Redis' 카테고리의 다른 글
Windows 환경에서 스프링부트 + Redis 사용하기 (0) | 2023.08.02 |
---|
- Total
- Today
- Yesterday
- OpenFeign
- 스프링부트
- CloudFront
- elasticsearch
- 후쿠오카
- docker
- MySQL
- cache
- JWT
- openAI API
- ChatGPT
- GIT
- AOP
- serverless
- EKS
- 오블완
- OpenAI
- Log
- Kotlin
- 티스토리챌린지
- java
- springboot
- Elastic cloud
- AWS
- 람다
- Spring
- terraform
- AWS EC2
- lambda
- S3
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |