일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- BOJ 11726
- 플로이드 와샬
- priority_queue
- springboot
- BOJ 4948
- DP
- BOJ 2146
- spring security
- javascript
- serverless
- Coercion
- BOJ 1912
- BOJ 6593
- MySQL
- BOJ 2167
- BOJ 1926
- BOJ 2234
- 다익스트라
- 조합 알고리즘
- BOJ 2407
- BOJ 2213
- BOJ 2012
- Lambda
- BOJ 5568
- BOJ 1074
- BOJ 5791
- BOJ 1697
- AWS
- BOJ 4485
- 분할과 정복
- Today
- Total
고인물을 지양하는 블로그
[Spring Data Redis] Redis Repository로 저장한 도메인 Redis Template로 접근 본문
[Spring Data Redis] Redis Repository로 저장한 도메인 Redis Template로 접근
yunjaeGong 2022. 9. 22. 23:54Spring Boot Redis를 이용해 Redis에 접근하는 방법에는 크게
1. RedisTemplate
를 이용하는 방법
2. RedisRepository
를 이용하는 방법
두 가지 방법이 있다.
Redis Template
을 이용하는 방법
https://sabarada.tistory.com/105?category=856943
[Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisTemplate 편
[Redis] 캐시(Cache)와 Redis [Redis] Redis의 기본 명령어 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisTemplate 편 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisRepository..
sabarada.tistory.com
Redis Repository
를 이용하는 방법
https://sabarada.tistory.com/106?category=856943
[Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisRepository 편
[Redis] 캐시(Cache)와 Redis [Redis] Redis의 기본 명령어 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisTemplate 편 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisRepository..
sabarada.tistory.com
Spring-Redis-Document와 위 블로그에 각 방법을 이용하는 방법이 잘 나와있지만, 이 글에서는 한 번에 둘 다 이용하는 방법을 알아보고자 한다.
RedisTemplate
Serializer 설정
1. Serializer
가 필요한 이유
Java에서 사용하는 data type은(e.g., int, Person, Meeting Class) 자바 애플리케이션 내에서는 선언한 타입처럼 취급되지만, 외부에서는 단순히 이진 데이터일 뿐, 그 자체가 의미를 가지지는 못한다.
Java 애플리케이션에서 Redis로 데이터가 전달될 때, Redis에서 이진 데이터가 Redis Data Type으로 취급되고, 그 역도 가능하게 하기 위해 Serializer가 위 업무를 수행한다.
Spring-Data-Redis는 여러가지 Serializer를 제공하고 있다.
2. Serializer 종류 및 트러블슈팅
1) 기본 설정
JdkSerializationRedisSerializer
RedisTemplate, RedisCache의 기본 Serializer이다.
2) SpringSerializer
bytebuffer에 읽 byte[]
3) SpringRedisSerializer
사람이 읽기 쉽도록 String 기반 인코딩을 통해 Key Value를
* RedisConnection 이용하는 경우에는 StringRedisConnection 이용
Redis Repository를 이용하면 쉽게 도메인 객체를 Serialize 및 저장할 수 있으며, CrudRepository
를 구현하는 레포지토리는

save(), deleteBy...(), removeBy...() 메서드를 통해 기본적인 CRUD 기능을 제공하며, findBy...() 메서드로 탐색 부가기능까지 제공하며, Spring-Data-JPA와 같은 인터페이스로, 애플리케이션 개발 시 편리하다.
반면에 Redis Template은 Redis 인스턴스 이용에 있어 다양한 접근 방법을 제공하는데,
Key Type Operations | |
GeoOperations | Redis geospatial operations, such as GEOADD, GEORADIUS,… |
HashOperations | Redis hash operations |
HyperLogLogOperations | Redis HyperLogLog operations, such as PFADD, PFCOUNT,… |
ListOperations | Redis list operations |
SetOperations | Redis set operations |
ValueOperations | Redis string (or value) operations |
ZSetOperations | Redis zset (or sorted set) operations |
Key Bound Operations | |
BoundGeoOperations | Redis key bound geospatial operations |
BoundHashOperations | Redis hash key bound operations |
BoundKeyOperations | Redis key bound operations |
BoundListOperations | Redis list key bound operations |
BoundSetOperations | Redis set key bound operations |
BoundValueOperations | Redis string (or value) key bound operations |
BoundZSetOperations | Redis zset (or sorted set) key bound operations |
위처럼 redis datatype 각각에 대응하는 접근 메서드를 제공하고 있다.
그렇다면, RedisTemplate로 아래와 같이 저장된 값을 Redis Template을 통해 어떻게 읽을 수 있을까?
redis cli 기본 명령
type 'key'


'key'에 대응하는 엔트리가 가지는 값의 타입 반환
https://redis.io/docs/data-types/
Redis data types
Overview of data types supported by Redis
redis.io
hget 'key' 'hashkey'

key와 hashkey에 해당하는 레코드가 가지는 값 반환
hgetall 'key'

해당 'key'에 연관된 hashkey, 값을 (hashkey, value, hashkey, value 순으로) 반환
hkeys 'key'

해당 'key'에 연관된 hashkey를 반환
hvals 'key'

해당 'key'에 연관된 값을 반환
keys 'pattern'

redis가 가지는 'key' 중, 해당 'pattern'에 대응하는 key들을 반환
Redis Repository를 이용한 영속화

위와 같은 Meeting class를 redis에 저장하자.
Redis Repository 이용
// Redis Repository를 이용하는 방법
Meeting meeting = new Meeting();
meeting.setTitle("New Meeting 1");
meeting.setStartAt(new Date());
meetingRepository.save(meeting);
위 명령을 통해 Redis에는 두 개의 Meeting 클래스의 오브젝트가 저장돼 있다 가정하자

key와 hashkey

Meeting과 관련된 모든 키를 관리하는 Meetings의 데이터 타입은 set이다.
그리고 저장된 레코드의 데이터 타입은 hash이다.

우리가 찾는 Meeting 오브젝트와 관련된 프로퍼티는 hash타입 Meetings:xxxxxxx-xxxx-... 에 저장돼 있다.
위 예시를 통해 두 가지 사실을 알 수 있다.
1. Redis Repository를 통해 저장된 오브젝트는 엔티티의 @RedisHash('key') 어노테이선에 명시한 key와 id를 조합한 hash 타입으로 저장된다.
-> Redis Repository를 통해 저장된 오브젝트의 'key'는 {Meetings:@id 프로퍼티 값} 이다.
2. Meeting 오브젝트들은 hash 타입들의 set 형태로 저장된다.
따라서 오브젝트의 프로퍼티들은 hash 명령을 통해 접근할 수 있다.


이 사실을 통해, Meetings 키에는 set 관련 명령, Meetings: + id 키에는 hash 관련 명령을 사용해야 한다는 것을 알 수 있다.
추가 정보
Spring Data Redis
Some commands (such as SINTER and SUNION) can only be processed on the server side when all involved keys map to the same slot. Otherwise, computation has to be done on client side. Therefore, it is useful to pin keyspaces to a single slot, which lets make
docs.spring.io
Redis Repository와 Redis Template 동시에 사용하기
저장된 오브젝트의 데이터 타입에 대한 정보를 바탕으로, Redis Repository를 이용해 저장된 값을 RedisTemplate를 이용해 읽는 방법은 다음과 같다.
* Serializer의 종류 트러블슈팅에서 다룬 것처럼, java 애플리케이션에서 쓴 값을 Redis cli에서 편히 읽기 위해서는 Serializer 설정이 필요하다.
* Redis Template과 Redis Cache의 기본 Serializer인 JdkSerializationRedisSerializer 대신, StringRedisSerializer를 사용했다.
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
// serializer 변경
return redisTemplate;
}
Redis Repository로 저장한 객체 불러오기
void redisTemplate_opsForHash_approach() {
Map<Object, Object> results =
redisTemplate.opsForHash().entries("Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5");
// key에 연관된 모든 hashkey, value의 반환
System.out.println("----------redisTemplate_opsForHash_approach----------");
System.out.println("entry size: " + results.size()); // 엔트리 크기
results.forEach((k, v) -> System.out.println(
"key: \"" + k.toString()
+ "\" val : \"" + v.toString() + "\""));
}

hgetall Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5
명령을 이용한 것과 같은 결과임을 알 수 있다.

번외
Redis Template 이용해 값 수정
void redisTemplate_opsForHash_modify_property() {
System.out.println("----------redisTemplate_opsForHash_modify_property----------");
// given
Map<Object, Object> results =
redisTemplate.opsForHash().entries("Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5");
assertNotNull(results);
System.out.println(results);
String orig_title = results.get("title").toString();
// when
redisTemplate.opsForHash().put("Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5", "title", "RedisTemplate modification");
System.out.println("----------After Modification----------");
// then
results = redisTemplate.opsForHash().entries("Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5");
assertNotNull(results);
assertNotNull(results.get("title").toString(), "RedisTemplate modification");
System.out.println(results);
redisTemplate.opsForHash().put("Meetings:94c9e99e-94a6-4c08-8137-7782dc744ca5", "title", orig_title);
}

도큐먼트를 보며 공부하다 Redis Repository를 이용해 저장한 값을 Redis Template을 통해 어떻게 접근할까?라는 궁금증에 Redis Template과의 싸움을 시작했고 글로 남기게 되었습니다.
2022/11/07 추가
Spring Data Redis 도큐먼트를 살펴보다 StringRedisSerializer와 관련된 RedisTemplate / RedisConnection 관련 클래스를 찾을 수 있었습니다.
Spring Data Redis
Some commands (such as SINTER and SUNION) can only be processed on the server side when all involved keys map to the same slot. Otherwise, computation has to be done on client side. Therefore, it is useful to pin keyspaces to a single slot, which lets make
docs.spring.io
항목에서, String 위주(String key, value를 가지는) 작업을 수행할 때, 별도 Serializer 설정 없이 사용할 수 있는 클래스로, StringRedisTemplate, StringRedisConnection 클래스를 제공하고 있다는 것을 알게 되었습니다.
위 예시는 StringRedisTemplate + StringRedisSerializer 설정을 통해 사람이 읽을 수 있는 String 작업을 수행하고 있지만, 바로 위에서 소개한 클래스를 이용하면 별도 설정 없이도 기본 Serializer로 StringRedisSerializer를 이용하는 것으로 보입니다.