레디스(Redis)는 "Remote Dictionary Server"의 약자로, Key-Value 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈소스 기반의 비 관계형 데이터베이스 관리 시스템(DBMS)이다
- 장점
- 다양한 데이터 구조를 지원한다. (String, List, Set, Sorted Set, Hashes)
- 메모리 + 디스크 활용을 통한 영속적인 데이터 보존 가능.
- 서버 측 복제 및 샤딩 지원.
- 다양한 API를 지원. - 단점
- 메모리 사용량이 많다.
기본적으로 memcached 대비 데이터 용량을 지원하기 때문이기도 하지만, 동작 방식에서 오는 메모리 사용량이 많다.
- 대규모 트래픽에 대한 응답속도 불안정.
대규모의 트래픽 발생에 따라 많은양의 데이터가 Update 되면 메모리 할당 방식 차이에 따른 메모리 파편화 및 응답속도 저하가 발생된다 (memcached 대비), 다만 응답속도 저하는 극단적인 환경에서 발생한다고 하며 대규모 서비스에서도 Redis를 많이 도입하는 것을 보면 일반적인 상황에서는 문제가 없을 것으로 판단된다.
스프링 부트로 REST API를 설계하는 도중 사용자의 요청이 들어올 때 마다 토큰이 유효한지 계속 판별할 때 DB에 접근하는 방법은 불필요하게 DB 접근 횟수를 늘리는 것 같아 방법을 고민하던 중 캐시를 활용해보라는 조언을 듣고 처음에는 스프링에 내장되어있는 캐시를 사용했더니 프로젝트가 꺼지면서 같이 사라지는 바람에...
레디스를 사용해보기로 결심했다.
1. 내 컴퓨터에 Redis를 설치해준다.
https://github.com/microsoftarchive/redis/releases
2. build.gradle에 redis를 추가해서 설치해준다.
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
3. application.yml 설정
spring:
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
application.yml 설정을 해주자. 레디스는 포트 번호 6379를 사용한다.
3. 모든 설정이 끝났다. 이제 간단한 어노테이션을 활용하면 Redis 캐시를 사용할 수 있다.
@Service
public class CacheTestService {
@Cacheable("key1")
public int getCachedInt() {
System.out.println("getCachedInt 호출됨");
return 5;
}
}
CacheTest를 위한 Service를 작성해봤다.
@Autowired
private CacheTestService cacheTestService;
@Test
@DisplayName("캐시 사용")
void t1() throws Exception {
int rs = cacheTestService.getCachedInt();
assertThat(rs).isGreaterThan(0);
System.out.println(rs);
rs = cacheTestService.getCachedInt();
assertThat(rs).isGreaterThan(0);
System.out.println(rs);
}
이 테스트를 진행하면 원래 같으면 "getCachedInt 호출됨" 이 두번 실행될 것이다. 테스트 결과를 확인해보자.
테스트를 실행해보니 "getCachedInt 호출됨"은 한번 실행되었다.
@Cacheable 덕분에 캐시에 값이 저장되어 두번째 부터는 굳이 함수를 실행시키지 않고 캐시에서 가져와 결과값만 받아온 것이다. 레디스에 접속해서 확인해보자. 설치받은 Redis 폴더에 redis-cli.exe를 실행시켜주면된다.
레디스 접속 후 key를 확인해보니 key1이 새로 생겼다.
@CacheEvict("key1")
public void deleteCacheKey1() {
}
@CacheEvict 으로 키 값을 삭제 할 수 있다. 이외에 @CachPut 등 여러 어노테이션이 존재하며 사용법이 다르다.
@Test
@DisplayName("래퍼런스 매개변수")
void t5() throws Exception {
Person p1 = new Person(1, "홍길동1");
Person p2 = new Person(1, "홍길동2");
System.out.println(p1.equals(p2));
String personName = cacheTestService.getName(p1, 5);
System.out.println(personName);
personName = cacheTestService.getName(p2, 10);
System.out.println(personName);
}
만약에 타입으로 레퍼런스가 들어왔는데 캐시를 타고 싶다면 key 값을 지정해줄 수 있다.
@Cacheable(value = "getName", key = "#p.id")
public String getName(Person p, int random) {
System.out.println("== getName 실행됨 ==");
return p.getName();
}
key 값이 같기 때문에 실행 결과 캐시를 통해 값을 얻은 것을 확인할 수 있다.
밸덩 사이트에 더 많은 예시가 있으니 필요하면 참고하도록 하자!!
'IT' 카테고리의 다른 글
접근 제어자 (0) | 2022.11.09 |
---|---|
자바 동일성과 동등성("==", "Equals") (0) | 2022.11.09 |
동시성 문제(synchronized, pessimistic lock, optimistic lock) (0) | 2022.11.07 |
스프링 batch + scheduler 정산 시스템 구현 (0) | 2022.11.03 |
JWT(JSON WEB TOKEN ) (0) | 2022.10.08 |