Remote Dictionary Server의 약어인 Redis는 데이터베이스, 캐시, 메시지 브로커 및 대기열로 사용하는 빠르고 오픈 소스, 인 메모리 키-값 데이터 스토어입니다
Cache란 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 아래와 같은 저장공간 계층 구조에서 확인할 수 있듯이, 캐시는 저장 공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다.
우선 저는 우분투 환경의 PC에서 설치했습니다. 설치는 아주 간단합니다.
doker pull redis:alpine
위 명령어를 실행해서 이미지를 받습니다.
docker network create redis-net
docker run --name redis_db -p 6379:6379 --network redis-net -v d:/dev/docker/db/redis -d redis:alpine redis-server --appendonly yes
docker run -it --network redis-net --rm redis:alpine redis-cli -h redis_db
아래와 같이 포트와 IP 그리고 비밀번호를 설정해줄 수 있습니다.
redis-cli -h 127.0.0.1 -p 6379 -a mysupersecretpassword
build.gradle에 다음 dependency를 추가해줍니다.
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.5.3'
그 다음에 RedisConfig를 만들어줍니다.
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String redisPwd;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisHost);
redisStandaloneConfiguration.setPort(redisPort);
redisStandaloneConfiguration.setPassword(redisPwd); //redis에 비밀번호가 설정 되어 있는 경우 설정해주면 됩니다.
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration);
return lettuceConnectionFactory;
}
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
redis host와 port 그리고 password는 환경변수로 빼줬습니다.
redisConnectionFactory로 레디스와 연결해주고 RedisTemplate을 사용하기위해서 정의해줍니다.
스프링에서 Redis의 사용법에는 2가지가 있습니다.
저는 Redis를 JWT의 Refresh토큰으로 쓰기 위해 사용합니다.
따라서 RefreshToken Entity를 만들어줍니다.
@Data
@RedisHash
public class RefreshToken implements Serializable {
private static final long serialVersionUID = -7353484588260422449L;
private String email;
private String refreshToken;
}
다음, refreshToken을 생성해주고 vop.set(키,객체,만료 시간,시간의 단위)
와 같이 만들어 주면 자동적으로 redis memory에 들아가게됩니다.
RefreshToken refreshTokenEntity = new RefreshToken();
refreshTokenEntity.setEmail(userMaster.getEmail());
refreshTokenEntity.setRefreshToken(refreshToken);
ValueOperations<String, Object> vop = redisTemplate.opsForValue();
vop.set(userMaster.getEmail(), refreshTokenEntity,JWT_REFRESH_TOKEN_VALIDITY, TimeUnit.SECONDS);
아래 사진과 같이 redis container에 들어가서 redis-cli를 입력하면 cli창으로 이동 됩니다. 그 이후에, keys *를 입력하면 모든 키들이 나옵니다. 보시면 잘 들어간것을 볼 수 있습니다.
이제 데이터를 가져올 때는, 다음과 같이 가져와서 사용할 수 있습니다.
ValueOperations<String, Object> vop = redisTemplate.opsForValue();
RefreshToken result = (RefreshToken) vop.get(email);
만약 repo를 사용하지 않을것이라면 spring.data.redis.repositories.enabled=false
로 비활성화를 해주면 됩니다.
CRUD를 상속받아서 만들어줍니다.
public interface RefreshRepository extends CrudRepository<RefreshToken,String> {
RefreshToken findByEmail(String email);
}
그 뒤에 RedisConfig에 redisRepo를 활성화하는 @EnableRedisRepositories 어노테이션을 달아줍니다.
또한, Entity Class에 추가적인 어노테이션을 달아줍니다
@RedisHash(value = "EmailVerification", timeToLive = 300 )
@Builder
@Data
public class RefreshToken {
@Id
private String id; // requestId
@Indexed
String email;
String refreshToken;
}
id는 redis에 등록할 때 자동적으로 생기는 랜덤한 값이고
Email로 인덱싱을 하게됩니다. timeToLive는 expire시간을 정해줍니다.
이제 평범한 JPA를 사용하듯 repo.save()를 사용하면 redis memory에 저장할 수 있습니다.