[Redis]Spring Data Redis Repository

yeonjoo913·2023년 5월 22일
0

Redis

목록 보기
1/7

Spring Data Redis는 2가지 방식의 적용이 가능하다.
1. RedisTemplate
2. RedisRepository

오늘은 두번째로 소개한 redisRepository 방식을 사용할 것이다.

redisRepository는 Spring Data JPA와 같이 객체를 기반으로 redis에 적재되는 방식이다.

환경 설정

의존성(Dependency)

config 설정

다른 블로그에도 많으니 기본셋팅만 적어본다.

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        return redisTemplate;
    }
}

장점

  1. TTL 설정이 쉽다.
  2. 쉽게 domain객체를 RedisHash로 변환가능하다.
  3. secondary indexes를 추가로 이용하여 primary key access만 제공하는 key-value의 한계를 극복하였다.

코드 적용 예시

오늘 예시에 사용할 Item 객체를 생성해준다.Item은 id를 redisKey로 가진다.
RedisRepository로 사용하기 위해 @RedisHash 어노테이션을 사용하여 Key설정을 해준다. prefix는 config를 커스텀하여 설정한다.

@Data
@RedisHash(timeToLive = 60L,value="SHOP:ITEM")
public class Item {

    @Id
    private Long id;
    private String itemName;
    private int price;
    private int dcPrice;

    @Builder
    public Item(Long id, String itemName, int price, int dcPrice) {
        this.id = id;
        this.itemName = itemName;
        this.price = price;
        this.dcPrice = dcPrice;
    }
}

이 도메인 객체를 기준으로 repository를 생성한다.

public interface ItemRepository extends extends CrudRepository<Item, String> {}

interface로 만들고 CrudRepository를 상속받으면 된다.
CrudRepository는 spring data commos 모듈에 선언된 인터페이스로 데이터베이스를 다루는데 필요한 메소드를 모아둔 인터페이스이다. 도메인 클래스 타입과 ID타입을 제네릭 인자로 전달하고 CrudRepository 인터페이스를 상속하면 데이터 조회와 갱신 기능을 편하게 사용할 수 있다. Spring Data Redis Repository 역시 인터페이스에 선언된 모든 메소드를 오버라이딩 하여 Redis Hash 데이터에 쉽게 접근 할 수 있다.


@Autowired
private RedisRepository redisRepository;

public void saveItem() {
        redisRepository.save(
                new Item.Builder()
                        .id(1L)
                        .itemName("상품명")
                        .price(2000)
                        .dcPrice(1000)
                        .build()
        );
 }

Item객체를 저장했으니, redis를 확인해보도록 한다. redis에는 2개의 key가 생성되었음을 확인 할 수 있다. SHOP:ITEMSHOP:ITEM:1 이다.
이 두가지를 자세히 알아보자.

1.SHOP:ITEM

  • shop의 item과 관련된 모든것을 관리한다.
  • key 값만 저장한 Set type으로 해당요소가 있는지 확인할 때 용이하다.
    key가 별도의 set에 저장되고 데이터를 삭제하면 대응되는 key가 set에서 삭제된다.

2.SHOP:ITEM:1

  • item의 id와 매칭된 값을 관리한다.
  • Hash type이다.

위와 같은 로직으로 redisRepository를 사용하여 redis에 데이터를 저장하는 방식을 확인 할 수 있었다.


이슈사항

Time To Live (TTL)
@RedisHash(timeToLive = 60L) 어노테이션을 통해 데이터의 TTL을 설정한면 오류가 발생하기 시작한다.
TTL 시간이 지나면 저장된 데이터는 제거되지만, key목록을 관리하는 Set의 element는 제거되지 않기 때문에 데이터의 정합성이 깨지게 된다.
@EnableRedisRepositories(enableKeyspaceEvents = ON_STARTUP) 선언을 추가하는 것으로 redis로부터 expired이벤트를 수신할 수 있다. 이를 통해 set의 크기를 적당하게 유지할 수 있지만 변경필요하다.

이유1. CrudRepository인테페이스에 선언된 대부분의 기능을 사용하지 않고 있다.
이유2. 불필요한 오버헤드 동작이 내부적으로 존재한다.
이유3. 관리하지 않으면 무한정 쌓이는 set 데이터를 처리하기 귀찮다.


결론

대부분의 로직에서 redis on/off를 처리하기 위해 redisTemplate을 커스텀하여 구성하고, 앞서 말한 이유와 상관없이 항상 redis를 통해 처리해야할 것들을 위해 redisRepository를 사용해 보았는데, set과 관련된 이슈로 인해 redisTempalte을 다시 커스텀하여 사용하는 방향으로 다시 생각해봐야겠다.

profile
주니어 백엔드 개발자. 까먹는다 기록하자!

0개의 댓글