Spring/Issue

[SpringBoot] Redis Hash 구조로 변경하기

블로그 주인장 2024. 1. 5.

Issue

이전 포스팅에서 레디스와 스케쥴러를 이용해서 DB에 주기적으로 업데이트를 진행했다.

https://miiro-under.tistory.com/261

 

레디스와 스케쥴러를 이용한 조회수 증가

Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션(Session)을 사용했다. https://miiro-under.tistory.com/260 조회수 기능 구현하기 - 중복 방지(Session) Issue 이전 포스팅에서 조회수 기능을 중

miiro-under.tistory.com

 

해당 로직에 대한 피드백을 받았는데,

 

기존에는 redisService.hasKeys(VIEW_PREFIX + "*") 연산을 진행했었다.

 

해당 연산은 VIEW_PREFIX 라는 키를 가진 모든 키를 로드하는 방식이다.

 

기존 로딩 방식이었던 와일드 카드('*') 방식에 대해 알아보겠습니다.

 

1. 주로 특정 패턴을 가진 모든 키를 조회하고자 할 때 사용된다.

2. 와일드 카드를 사용하면 특정 패턴과 일치하는 모든 키를 가져올 수 있다.

3. 예시로, redisTemplate.keys("user:*")는  "user:"로 시작하는 모든 키를 가져옵니다.

 

이 방식으로 사용하면 가장 문제점은

패턴과 일치하는 모든 키를 가져오기 때문에 성능에 영향을 줄 수 있다는 것이다.

현재 나의 경우에는 작은 프로젝트라서 상관없겠지만 큰 서비스의 경우에는 부하에 영향을 줄 수 있다는 것이다.

 

Solution

성능에 부하를 줄 수 있기 때문에 레디스에서 값을 받아올 때 Hash 구조로 받아오는 것으로 변경해보겠습니다.

 

그럼 Hash 구조로 조회하는 방식에 대해 알아보겠습니다.

 

1. Hash 는 특정 키 하나에 여러 필드-값 쌍으로 저장하는 데이터 구조입니다.

2. 특정 키에 조회가 필요한 경우, 해당 키의 모든 필드- 쌍을 가져올 수 있습니다.

3. 예시로, redisTemplate.opsForHash().entries("user:123")는 "user:123" 키의 모든 필드-값을 가져옵니다.

 

해시 구조는 특정 키에 필드-값을 효율적으로 저장하고 조회할 수 있습니다.

특히, 엔티티에 대한 다양한 속성을 저장하는 데에 유용합니다.

 

 

코드에 적용을 해보겠습니다.

 

RedisTemplate을 커스텀한 RedisService 로직입니다.

 

increaseHashData( ) 의 경우 해시키와 해당 키를 넣으면 +1 씩 증가하게 됩니다.

 

hasHashKeys() 는 해당 key 에 해당 되는 모든 필드-키 값을 가져옵니다.

 

deleteHashKey() 는 해당 해시-필드 값에 해당하는 모든 키 값을 삭제합니다.

 

 

스케쥴링을 이용해서 DB에 저장하는 로직입니다.

 

Redis의 Hash에 저장된 모든 조회수를 조회합니다.

 

Hash에 저장된 key값과 value 값을 받아옵니다.

받아온 후에는 DB에 반영하고 데이터를 적용했다면 기존 데이터는 삭제를 시킵니다.

 

만약 해쉬값이 없다면 진행하지 않게 됩니다.

 

테스트를 진행해보겠습니다.

post를 1개의 값을 변경했을 때의 차이점입니다.

 

빨간색의 네모는 기존 로직입니다.

 

기존 로직의 경우에는 와일드카드(*) 방식이기 때문에 모든 키를 조회해서 값을 업데이트를 하게 됩니다.

 

노란색 네모는 변경된 로직입니다.

 

변경된 로직은 해시 구조로 하나의 해시를 찾아서 필드-값이 있는 값만 적용하게 업데이트가 됩니다.

 

 

한 줄 마무리

redis를 사용할 때 무작정 key-value 구조로만 사용했었는데, Hash 구조로 사용해보니까 중복은 없고

성능 측면에서도 기존 로직보다 불필요한 I/O 연산을 하지 않아서 새삼 Hash 구조를 사용하길 잘한 거 같다.

대용량 데이터를 사용한다면 또, redis를 사용한다면 Hash 구조를 사용해서 다른 프로젝트에 구현하고 싶다.

 

 

본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다.

반응형

댓글