인텔리제이에서 스프링 부트와 Redis 를 연결하고
Sorted set 자료구조를 이용해 인기 검색어 순위를 저장하고 조회하는 테스트를 해봤다.
spring boot kotlin
redisTemplate
Redis 설정
1 설치
2 dependencies
implementation ("org.springframework.boot:spring-boot-starter-data-redis:2.3.1.RELEASE")
3 인텔리제이 데이터베이스 연결
4 application.yml 설정 (로컬)
spring:
data:
redis:
port: 6379 // 기본 포트
host: localhost
5 RedisConfig
package com.sparta.bubbleclub.global.config
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
class RedisConfig {
@Value("\${spring.data.redis.port}")
private val port = 0
@Value("\${spring.data.redis.host}")
private val host: String = ""
@Bean
fun redisConnectionFactory(): RedisConnectionFactory {
return LettuceConnectionFactory(host, port)
}
@Bean
fun redisTemplate(): RedisTemplate<String, String> {
val redisTemplate: RedisTemplate<String, String> = RedisTemplate()
redisTemplate.keySerializer = StringRedisSerializer() //key 깨짐 방지
redisTemplate.valueSerializer = StringRedisSerializer() //value 깨짐 방지
redisTemplate.connectionFactory = redisConnectionFactory()
return redisTemplate
}
}
코드
Controller
package com.sparta.bubbleclub.domain.keyword.controller
import com.sparta.bubbleclub.domain.bubble.dto.request.SearchKeywordRequest
import com.sparta.bubbleclub.domain.bubble.dto.response.BubbleResponse
import com.sparta.bubbleclub.domain.keyword.dto.response.KeywordResponse
import com.sparta.bubbleclub.domain.keyword.service.KeywordService
import jakarta.validation.Valid
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Slice
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("api/v1/keywords")
class KeywordController(
private val keywordService: KeywordService
) {
...
// 키워드로 검색
@GetMapping("/search")
fun searchByKeyword(
@Valid request: SearchKeywordRequest
): ResponseEntity<String> {
keywordService.setKeywordScore(request.keyword)
return ResponseEntity.ok().body("")
}
// 인기 검색어 조회
@GetMapping("/ranks")
fun searchKeywordRanking(): List<KeywordResponse> {
return keywordService.searchKeywordRankingByRedis()
}
}
Service
package com.sparta.bubbleclub.domain.keyword.service
import com.sparta.bubbleclub.domain.bubble.dto.request.SearchKeywordRequest
import com.sparta.bubbleclub.domain.keyword.dto.response.KeywordResponse
import com.sparta.bubbleclub.domain.keyword.repository.KeywordRepository
import jakarta.transaction.Transactional
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.stereotype.Service
@Service
class KeywordService(
private val keywordRepository: KeywordRepository,
private val redisTemplate: RedisTemplate<String, String>
) {
...
private val zSetOperations = redisTemplate.opsForZSet()
companion object {
private const val REDIS_KEY = "keyword"
}
// keyword 저장
@Transactional
fun setKeywordScore(keyword: String): Boolean {
// redis 에 keyword 있는지 검사, 없으면 추가
zSetOperations.addIfAbsent(REDIS_KEY, keyword, 0.0)
// increaseScore() 호출
increaseScore(keyword)
return true
}
// score ++
private fun increaseScore(keyword: String) {
zSetOperations.incrementScore("keyword", keyword, 1.0)
}
// 인기 검색어 조회
fun searchKeywordRankingByRedis(): List<KeywordResponse> {
val rank =zSetOperations.reverseRange("keyword", 0, 9) ?: emptySet()
return rank.map { KeywordResponse(keyword = it) }
}
}
구조
특정 검색어 $keyword 로 데이터 조회 api
-> 검색어 $keyword 가 "keyword" 라는 key 에 value 로 있는지 확인, 없으면 추가
-> "keyword" key 에 $keyword value 의 score 값을 1씩 더함
검색어 순위 조회 api
-> "keyword" key의 높은 것부터 낮은 것 순으로 0번째부터 9번째까지 10개의 데이터를 가져와서 반환함
결과
키워드로 검색을 할 때마다 각각의 score가 1씩 올라가고
순위를 조회하면 score 가 높은 것부터 차례대로 반환된다.
어떻게 흘러가나 궁금해서 저장할 때랑 조회할 때 찍고 안에 들어가봤는데 뭐가 뭔지 하나도 모르겠다
안에 까보면서 즐거움 느끼는 사람들 대단....
해야할 것
redis 를 사용할 때 명령어가 어떻게 날아가는지 확인
데이터가 영구적으로 저장되므로 삭제시켜주어야한다 -> 만료시간 설정
redis cache 사용 -> 유효시간 설정 -> 삭제된 후에 기존의 순위는 어떻게 나타내지??
'왕초보일지' 카테고리의 다른 글
240220 TIL | 더미 데이터 집어넣기 (0) | 2024.02.20 |
---|---|
240219 TIL | (0) | 2024.02.19 |
240216 TIL | (1) | 2024.02.16 |
240215 TIL | (0) | 2024.02.15 |
240214 TIL | (0) | 2024.02.14 |