728x90
반응형
ZSetOperations
- ZSetOperations는 Redis에서 제공하는 sorted set(정렬된 집합)에 대한 작업을 수행하는 인터페이스이다.
- ZSetOperations을 이용하여 레디스에서 정렬을 구현할수 있다.
레디스를 선택한 이유
- 트래픽이 많이 발생하는 상황에서 QPS를 줄이기 위해 사용한다.
- 뉴스 데이터는 객체에대해서 CRUD 가 많이 발생하지 않는다.
- 뉴스 데이터를 '카테고리별' 최신순으로 가져와야한다.
- 뉴스 데이터는 30일 까지만 보관한다.
ZSetOperations에서 사용할 기능
Boolean add(K key, V value, double score);
- key: 유니크한 값
- value: 키에 대한 값
- score: 키에 대한 스코어 점수
reverseRange(K key, long start, long end)
- key: 유니크 값
- start: index 시작값
- end: index 종료값
rangeByScore(K key, double min, double max)
- key: 유니크 값
- min: 검색할 score 의 최소값
- max: 검색할 score의 최대값
ZSetOperations 예제
1. 뉴스아이디를 카테고리별 등록시간별로 저장
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
// 뉴스 아이디 1, 2번은 16시에 등록
LocalDateTime localDateTime = LocalDateTime.of(2024, 10, 5, 16, 0, 0);
long regDttmMilli = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
zSetOperations.add("news:category:issue", "1", regDttmMilli);
zSetOperations.add("news:category:issue", "2", regDttmMilli);
// 뉴스 아이디 3, 4번은 17시에 등록
LocalDateTime localDateTime2 = LocalDateTime.of(2024, 10, 5, 17, 0, 0);
long regDttmMilli2 = localDateTime2.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
zSetOperations.add("news:category:issue", "3", regDttmMilli2);
zSetOperations.add("news:category:issue", "4", regDttmMilli2);
2. 카테고리 Issue 에서 최신등록된 뉴스 3개 가져오기
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
LocalDateTime localDateTime = LocalDateTime.of(2024, 10, 5, 16, 0, 0);
long regDttmMilli = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
zSetOperations.add("news:category:issue", "1", regDttmMilli);
zSetOperations.add("news:category:issue", "2", regDttmMilli);
LocalDateTime localDateTime2 = LocalDateTime.of(2024, 10, 5, 17, 0, 0);
long regDttmMilli2 = localDateTime2.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
zSetOperations.add("news:category:issue", "3", regDttmMilli2);
zSetOperations.add("news:category:issue", "4", regDttmMilli2);
Set<String> newsByCategory = zSetOperations.reverseRange("news:category:issue", 0, 2);
for (String newsId : newsByCategory) {
System.out.println("newsId : ".concat(newsId));
}
결과
4번 3번 2번 순으로 최근 등록된 뉴스를 가져왔다.
newsId : 4
newsId : 3
newsId : 2
3. 카테고리 Issue 에서 등록된 시간으로 조회하기
rangeByScore를 이용하여 등록된 시간으로 조회를 한다.
min, max 에 값은 값을 넣어주면 해당 값으로 조회를 할 수 있다.
LocalDateTime localDateTime = LocalDateTime.of(2024, 10, 5, 16, 0, 0);
long regDttmMilli = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Set<String> newsByCategory2 = zSetOperations.rangeByScore("news:category:issue", regDttmMilli, regDttmMilli);
for (String newsId : newsByCategory2) {
System.out.println("newsId : ".concat(newsId));
}
결과
16시에 등록한 뉴스 2개의 아이디 값을 조회 한다.
newsId : 1
newsId : 2
전체코드
@Repository
@RequiredArgsConstructor
public class NewsRepository {
private final RedisTemplate<String, String> redisTemplate;
private ValueOperations<String, String> valueOperations;
private ZSetOperations<String, String> zSetOperations;
private final ObjectMapper objectMapper;
private final String NEW_BY_DATE_KEY = "news_by_date";
@PostConstruct
public void init() {
valueOperations = redisTemplate.opsForValue();
zSetOperations = redisTemplate.opsForZSet();
}
public void save(News news) throws JsonProcessingException {
Integer seq = news.getSeq();
String category = "news:category:".concat(news.getCategory());
String redisMemberId = "news:".concat(String.valueOf(seq));
String jsonStringData = objectMapper.writeValueAsString(news);
long regDttm = Instant.now().toEpochMilli();
long regDt = LocalDate.now().toEpochDay();
valueOperations.set(redisMemberId, jsonStringData);
zSetOperations.add(category, redisMemberId, regDttm);
zSetOperations.add(NEW_BY_DATE_KEY, redisMemberId, regDt);
}
public Set<String> findByCategory(String category, int limit) {
String categoryKey = "news:category:".concat(category);
// Sorted Set에서 최신 등록순으로 가져오기 (역순으로 조회)
return zSetOperations.reverseRange(categoryKey, 0, limit - 1);
}
public Set<String> findByRegDt(LocalDate localDate) {
long epochDay = localDate.toEpochDay();
// Sorted Set에서 저장 순으로 가져오기
return zSetOperations.rangeByScore(NEW_BY_DATE_KEY, epochDay, epochDay);
}
public <T> T converObject(String json, Class<T> clazz) throws JsonProcessingException {
return (T)objectMapper.readValue(json, clazz);
}
}
728x90
반응형
'DataBase > Redis' 카테고리의 다른 글
[Redis] Redis Spring boot 간단예제 (0) | 2023.02.21 |
---|---|
[Redis] Redis 시작하기 (0) | 2023.02.21 |
[Redis] Redis 란? (0) | 2023.02.08 |
댓글