기존 RDBMS 방식을 탈피한 데이터베이스를 의미
기존의 관계형 DB가 가지고 있는 특성뿐만 아니라 다른 특성들을 부가적으로 지원
RDBMS가 가지고 있는 한계를 극복하기 위한 데이터 저장소의 새로운 형태로, 수평적 확장성을 가지고 있음 문서, 그래프, 키 값, 인 메모리, 검색을 포함해 다양한 데이터 모델을 사용
Remote Dictionary Server의 약자로, 원격 Dictinary 자료구조 서버.
레디스는 세계에서 가장 인기있는 Key-Value Store 중 하나
Key로 올 수 있는 자료형은 기본적으로 String이지만, Value는 다양한 타입을 지원
둘 다 key-value 기반이고, 메모리 베이스며, 원하는 value를 원하는 표현 방식으로 넣을 수 있음
서버가 1대 있다는 가정에선 Redis의 장점이 크게 보이지 않지만, 분산 환경을 대입하면 장점이 보임
Redis란? Spring boot 를 활용한 redis 사용
$ brew install redis # Redis 설치
$ brew services start redis # Redis 실행
$ brew services stop redis # Redis 중지
$ brew services restart redis # Redis 재시작
$ redis-cli # CLI 사용

Spring Boot 에서 Redis 를 사용하는 방법은 RedisRepository 와 RedisTemplate 두 가지
이를 사용하기 위해서는 공통 의존성 주입이 필요

build.gradle 에 spring-boot-starter-data-redis 추가하고 빌드
spring:
data:
redis:
host: localhost
port: 6379
application.yaml 에 host 와 port 를 설정localhost:6379 는 기본값이기 때문에 만약 Redis 를 localhost:6379 로 띄웠다면 따로 설정하지 않아도 연결이 됨@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
}
Spring Data Redis 의 Redis Repository 를 이용하면 간단하게 Domain Entity 를 Redis Hash 로 만들 수 있음
하지만 트랜잭션을 지원하지 않기 때문에 만약 트랜잭션을 적용하고 싶다면 RedisTemplate 을 사용
RedisTemplate 을 사용하면 특정 Entity 뿐만 아니라 여러가지 원하는 타입을 넣을 수 있음
template 을 선언한 후 원하는 타입에 맞는 Operations 을 꺼내서 사용
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
RedisTemplate 에 LettuceConnectionFactory 을 적용해주기 위해 설정@SpringBootTest
public class RedisTemplateTest {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
void testStrings() {
// given: 테스트 준비 단계, Redis에서 값을 설정하고 가져오기 위한 ValueOperations 객체를 생성합니다.
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
// 사용할 Redis 키를 정의합니다.
String key = "stringKey";
// when: 테스트 실행 단계, 정의한 키에 값을 설정합니다.
valueOperations.set(key, "hello");
// then: 테스트 검증 단계, Redis에서 값을 가져와서 예상한 값과 일치하는지 확인합니다.
String value = valueOperations.get(key);
// 가져온 값이 "hello"와 같은지 검증합니다.
assertThat(value).isEqualTo("hello");
}
@Test
void testSet() {
// given
SetOperations<String, String> setOperations = redisTemplate.opsForSet();
String key = "setKey";
// when
setOperations.add(key, "h", "e", "l", "l", "o");
// then
Set<String> members = setOperations.members(key);
Long size = setOperations.size(key);
assertThat(members).containsOnly("h", "e", "l", "o");
assertThat(size).isEqualTo(4);
}
@Test
void testHash() {
// given
HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
String key = "hashKey";
// when
hashOperations.put(key, "hello", "world");
// then
Object value = hashOperations.get(key, "hello");
assertThat(value).isEqualTo("world");
Map<Object, Object> entries = hashOperations.entries(key);
assertThat(entries.keySet()).containsExactly("hello");
assertThat(entries.values()).containsExactly("world");
Long size = hashOperations.size(key);
assertThat(size).isEqualTo(entries.size());
}
}