심화/DB

[DB] Redis 실습 1

annovation 2026. 3. 4. 23:54

블로그 별 조회수를 Redis로 확인하기

💡구현 기능

  • 아래와 같은 조건의 '내 블로그 글 별 조회수'를 Redis로 확인하는 기능을 만드려고 한다.
1. 블로그 URL의 PATH는 /articles/{id} 형식이다.
2. 로그인 여부와 상관없이 새로고침 될때마다 조회수가 하나 증가한다.
3. 이를 관리하기 위해 적당한 데이터 타입을 선정하고,
4. 사용자가 임의의 페이지에 접속할 때 실행될 명령을 작성해보자.

 

💡Redis 명령어

  • Redis의 String 타입은 숫자 카운터로 사용할 수 있고 값을 증가(INCR) 또는 감소(DECR)시키는 연산을 제공한다.

1) 특정 게시글 조회수 증가

INCR articles:{id}

 

2) 특정 게시글 조회수 증가 예시

INCR articles:1
INCR articles:2
INCR articles:3
  • 1번 게시글 조회수 +1

3) 오늘의 조회수 따로 관리

INCR articles:1:today
  • 1번 게시글의 오늘 조회수 +1

4) 하루가 지나면 날짜 키로 변경

RENAME articles:1:today articles:2026-03-05
  • 오늘 카운터를 날짜 기준 기록으로 변경

💡Spring 사용 예시

  • 조회수 증가 Service
@Service
@RequiredArgsConstructor
public class ArticleViewService {

    private final StringRedisTemplate redisTemplate;

    public Long increaseView(Long articleId) {

        String key = "articles:" + articleId;

        return redisTemplate
                .opsForValue()
                .increment(key);
    }
}
  • redisTemplate : Spring이 제공하는 API (RedisTemplate)를 통해 Redis 명령을 실행
  • opsForValue() : Redis의 String 자료형을 다루는 API
  • increment() : 내부적으로 Redis 명령 'INCR key'를 실행

블로그에 로그인 한 사람들의 조회수와 가장 많은 조회수를 기록한 글을 Redis로 확인하기

💡구현 기능

  • 아래와 같은 조건의 '블로그에 로그인한 사람들의 조회수와 가장 많은 조회수를 기록한 글'을 Redis로 확인하는 기능을 만드려고 한다.
1. 블로그 URL의 PATH는 `/articles/{id}` 형식이다.
2. 로그인 한 사람들의 계정은 영문으로만 이뤄져 있다.
3. 이를 관리하기 위해 적당한 데이터 타입을 선정하고,
4. 사용자가 임의의 페이지에 접속할 때 실행될 명령을 작성해보자.
5. 만약 상황에 따라 다른 명령이 실행되어야 한다면, 주석으로 추가해보자.

 

💡Redis 명령어

  • 중복을 허용하지 않는 자료형 Set을 활용할 수 있다.

1) Set에 값 추가 (중복 허용 안 됨)

SADD articles:1 alex
SADD articles:1 brad
SADD articles:1 chad
  • Redis 내부
articles:1 = {alex, brad, chad}

 

2) Set에 들어있는 원소 개수 반환

SCARD articles:1
  • 결과
3

 

3) 중복된 값 저장하는 경우 : SADD 반환값은 0

SADD articles:1 alex brad chad
  • 이미 내부에 alex, brad, chad 가 저장되어 있다면, 반환값은 0이다.

4) 따라서 SADD의 결과에 따라 명령어 실행 여부 결정 가능

# SADD의 결과에 따라 명령 실행
# 0이면 스킵
# 1이면 Sorted Set에 추가

ZADD articles:ranks 1 articles:1

ZINCRBY articles:ranks 1 articles:1
  • ZADD
Sorted Set "articles:ranks"에
member = articles:1
score = 1
로 추가
  • ZINCRBY
articles:1의 score를 1 증가
  • 가장 높은 조회수의 글을 보고 싶다면
ZRANGE articles:ranks 0 0 REV

 

💡Spring 사용 예시

import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ArticleLikeService {

    private final StringRedisTemplate redis;

    public ArticleLikeService(StringRedisTemplate redis) {
        this.redis = redis;
    }

    /**
     * userId가 articleId에 좋아요를 누르면:
     * 1) Set에 userId 추가 (중복이면 0)
     * 2) 새로 추가된 경우에만 Sorted Set 랭킹 점수 +1
     */
    public boolean like(Long articleId, String userId) {
        String likeSetKey = "article:" + articleId + ":likes";     // Set
        String rankKey = "articles:ranks";                         // ZSet
        String member = "articles:" + articleId;                   // ZSet member

        Long added = redis.opsForSet().add(likeSetKey, userId);    // Redis: SADD
        if (added == null) added = 0L;

        if (added == 1L) {
            redis.opsForZSet().incrementScore(rankKey, member, 1); // Redis: ZINCRBY
            return true; // 처음 좋아요 성공
        }
        return false;     // 이미 좋아요 눌렀음
    }

    public Long likeCount(Long articleId) {
        String likeSetKey = "article:" + articleId + ":likes";
        return redis.opsForSet().size(likeSetKey);                 // Redis: SCARD
    }

    public Double rankScore(Long articleId) {
        String rankKey = "articles:ranks";
        String member = "articles:" + articleId;
        return redis.opsForZSet().score(rankKey, member);          // Redis: ZSCORE
    }
}

참고 자료

https://teamsparta.notion.site/1-5-1-2242dc3ef51481478520c62135a0e3c9

 

챕터1-5 : 실습1 | Notion

Redis 설치 및 기본 명령어 사용해보기

teamsparta.notion.site