개발 기록

>[Redis] Spring boot 3 Redis Sentinel 환경 구성 및 구현 - 3. 캐싱 구현 : RedisRepository, RedisTemplate 본문

SQL&NoSQL

>[Redis] Spring boot 3 Redis Sentinel 환경 구성 및 구현 - 3. 캐싱 구현 : RedisRepository, RedisTemplate

1z 2024. 1. 8. 17:59

 

 

1. RedisRepository

 

(1) Repository 

 

(2) Redis 에 저장할 자료구조 Class 생성

- Redis는 byte code로 데이터를 담기 때문에 Serializable을 구현해줘야 한다.

- Domain Object를 redis hash 자료구조로 변환하여 저장

1. @RedisHash

 - value :데이터에 대한 key가 생성될 때 prefix 로 지정 

 - Hash 의 key는 value+@Id로 형성된다.

2. @Id  :  null로 저장될 경우 랜덤 값으로 설정된다.

3. @Indexed : keyspace:인덱스를 적용한 필드:해당 필드의 값

4. @TimeToLive : TTL을 적용 => TimeToLive에 적용되는 시간은 '초' 단위이며, default 값은 -1L

 

(3) Service

 

 


 

 

 

2. RedisTemplate

(1)  RedisTemplate 자료 구조별 메서드

opsForValue Strings Serialize / Deserialize 해주는 Interface
opsForList List Serialize / Deserialize 해주는 Interface
opsForSet Set Serialize / Deserialize 해주는 Interface
opsForZSet ZSet Serialize / Deserialize 해주는 Interface
opsForHash Hash Serialize / Deserialize 해주는 Interface

 

(2) RedisTemplate utils class 생성

package server.spring.guide.cache.redis;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

// RedisTemplate을 사용 할 경우
/** 레디스 템플릿은 사용하는 자료구조마다 제공하는 메서드가 다르기 때문에
 * 객체를 만들어서 레디스의 자료구조 타입에 맞는 메소드를 사용한다.
 */
// 자료구조별 접근 기능 :  opsForList(), opsForSet(), opsForZSet()등의 Redis의 자료구조별 접근 기능
@Component
public class RedisUtils {
    private final RedisTemplate<String, Object> redisTemplate;

    public RedisUtils(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void setData(String key, String value,Long expiredTime){
        // String 자료구조에 'key1'을 key로하는 데이터 set
        redisTemplate.opsForValue().set(key, value, expiredTime, TimeUnit.MILLISECONDS);
    }

    public String getData(String key){
       // redisTemplate.opsForHash().get("key1", "hashKey2"); // Hash 자료구조 데이터 조회
        return (String) redisTemplate.opsForValue().get(key);
    }

    public void deleteData(String key){
        redisTemplate.delete(key);
    }
}

 

 

3. @Cacheable

-캐시를 적용하고 싶은 메서드에 @Cacheable 을 선언한다

- unless == null 설정으로 메서드 반환값이 null, Optional.empty()가 아닌 경우만 캐싱을 진행

1. @Cacheable : 캐시 레이어에서 데이터를 조회하고, 조회한 결과가 없으면 메서드 로직 수행

2. @CacheEvit : 캐시 정보 삭제

3. @CachePost : 캐시 정보 저

-결과 : “major”라는 캐시 항목에 key는 majorId, value에는 조회 결과 데이터로 캐시된다.

 

@Cacheable(
        value = "major",
        key = "#majorId",
        unless="#result.size()==0")
    public void getMajorDataWithTemplate(String majorId) {
        redisUtil.getData(majorId);
}

 

 


 

 

3. 결과  확인 

API 호출 후 Redis CLI 에서 직접 저장된 데이터 확인

(1) 접속

   # 외부접속(비밀번호 X)
    redis-cli -h [접근 서버 IP] -p [레디스 실행 프로세스 포트]

    # 외부접속(비밀번호 O)
    redis-cli -h [접근 서버 IP] -p [레디스 실행 프로세스 포트] -a [비밀번호]

 

(2) key 확인 

 

(3) 해당 key의 Data 확인 

 

(4) error 

원인 : 레디스의 자료구조에 맞지 않는 명령어를 수행하려해서 발생

 ex. SortedSets 자료구조의 데이터를 GET으로 조회시 error 

 

*참고*

1. String → GET 

2. Hash → HGETALL

3. Lists → Irange

4. Sets → smembers

5. Sorted Sets → ZRANGE

 

 

(5) API PostMan 호출 결과

 

 

 

 

 

 

 

참고

https://bcp0109.tistory.com/

https://sabarada.tistory.com/105