[Redis] 레디스 사용 및 배포

2024. 8. 12. 12:25Java/Spring

Redis 사용 이유

  • 빠른 성능: Redis는 메모리에 데이터를 저장하여 매우 빠른 데이터 접근 속도를 제공합니다. 읽기 및 쓰기 작업이 나노초 단위로 처리될 수 있어, 실시간 애플리케이션에서 매우 유용합니다.
  • 데이터 구조 지원: Redis는 단순한 키-값 저장소가 아니라, 리스트, 셋, 해시, 정렬된 셋, 비트맵, 하이퍼로그로그 등의 다양한 데이터 구조를 지원합니다. 이를 통해 복잡한 데이터 모델링이 가능하며, 애플리케이션 요구 사항에 맞게 다양한 작업을 효율적으로 처리할 수 있습니다.
  • 높은 가용성 및 확장성: Redis는 복제(Replication), 클러스터링(Clustering), 퍼시스턴스(Persistence) 기능을 통해 데이터의 가용성과 신뢰성을 보장합니다. 이를 통해 장애가 발생하더라도 데이터 손실 없이 서비스를 지속할 수 있습니다.
  • 캐싱: Redis는 데이터를 인메모리에 저장하기 때문에, 자주 조회되는 데이터를 캐시하여 데이터베이스 부하를 줄이고 애플리케이션 성능을 높이는 데 매우 효과적입니다.

Redis 사용예

리프레쉬 토큰을 쓴다고 할때

 

  • 리프레시 토큰의 길이: 일반적으로 리프레시 토큰은 문자열 형태로 저장됩니다. 예를 들어, JWT(JSON Web Token) 형태의 리프레시 토큰이라면, 약 200-300바이트 정도일 수 있습니다.
  • 추가적인 메타데이터: 토큰 생성 시간, 만료 시간, 사용자 ID와 같은 추가적인 정보도 함께 저장할 수 있습니다. 이런 경우 추가적인 메모리 사용이 발생합니다. 예를 들어, 사용자 ID와 같은 정보를 함께 저장한다면, 각 토큰에 몇십 바이트에서 몇백 바이트 정도가 추가될 수 있습니다.
  • 저장되는 토큰의 수: 시스템에서 동시에 유지해야 하는 리프레시 토큰의 수가 메모리 사용량에 직접적인 영향을 미칩니다.
  • Redis 오버헤드: Redis는 데이터를 효율적으로 저장하지만, 자체적으로 키 관리 및 데이터 구조 관리에 약간의 오버헤드가 발생합니다.

가정해보면

  • 리프레시 토큰의 길이: 128바이트
  • 추가 메타데이터(예: 사용자 ID, 만료 시간): 64바이트
  • Redis 오버헤드: 약 50바이트 (단순 계산을 위해 이 수치를 사용)

하나의 리프레시 토큰 저장에 필요한 메모리:

  • 128바이트 + 64 바이트 + 50바이트 = 242바이트

만약 시스템에서 100만 개의 리프레시 토큰을 저장해야 한다면:

  • 100만 개 * 242 바이트 = 약 242 MIB

인스턴스 백엔드와 하나를  쓴다고 해도 크개 문제가 없을 정도다 .

 

Redis 사용법

나는 쓰기 쉽도록 도커의 컴포즈를 썼다.

 

docker-compose.yml

version: "3.8"
services:
  redis:
    image: redis:6.2.6
    container_name: ${REDIS_HOST}
    platform: linux/x86_64
    restart: always
    ports:
      - ${REDIS_PORT}:6379
    environment:
      TZ: Asia/Seoul
      REDIS_PASSWORD: ${REDIS_PASSWORD}
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--appendonly", "yes"]

 

 

.env

REDIS_HOST=호스트 이름
REDIS_PORT=포트
REDIS_PASSWORD=비밀번호

 

application.yml

spring:
  redis:
    host: ${REDIS_HOST:localhost}  # 환경 변수로부터 Redis 호스트 설정, 기본값은 'localhost'
    port: ${REDIS_PORT:6379}       # 환경 변수로부터 Redis 포트 설정, 기본값은 '6379'
    password: ${REDIS_PASSWORD:}   # 환경 변수로부터 Redis 비밀번호 설정, 비밀번호가 없을 경우 기본값은 빈 문자열
    timeout: 2000ms                # Redis 연결 시간 초과 설정
    lettuce:
      pool:
        max-active: 8              # 최대 활성 연결 수
        max-idle: 8                # 최대 유휴 연결 수
        min-idle: 0                # 최소 유휴 연결 수
        max-wait: -1ms             # 최대 대기 시간 (-1은 무제한 대기)
    database: 0                    # 사용할 Redis 데이터베이스 인덱스 (0부터 시작)

# Redis 캐시 설정 (선택 사항)
cache:
  type: redis
  redis:
    time-to-live: 600000           # 캐시의 TTL(Time to Live), 600000ms = 10분
    key-prefix: myapp::            # 모든 캐시 키 앞에 붙는 접두사

# 로깅 설정 (선택 사항)
logging:
  level:
    org.springframework.data.redis: DEBUG   # Redis 관련 로그 레벨 설정

application.yml

 

그리고 레디스가 어떤 엔티티와 리포지토리가 자신의 것인지 알기위해

엔티티

package com.sparta.elevenbookshelf.domain.auth.entity;

import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.TimeToLive;

@Getter
@RedisHash("refreshToken")
public class RefreshToken  {

    @Id
    private final Long userId;

    private final String refreshToken;

    @TimeToLive
    private final long timeToLive;

    public RefreshToken(String refreshToken, Long userId, long timeToLive) {
        this.refreshToken = refreshToken;
        this.userId = userId;
        this.timeToLive = timeToLive;
    }
}
  • 레디스가 인식하는 방법은
  • @RedisHash("refreshToken")
    
  • @Entity 가 아닌  @RedisHash("refreshToken") 을 쓴다.

 

리포지토리

package com.sparta.elevenbookshelf.domain.auth.repository;

import com.sparta.elevenbookshelf.domain.auth.entity.RefreshToken;
import org.springframework.data.repository.CrudRepository;

public interface RefreshTokenRepository extends CrudRepository<RefreshToken, Long> {
}
  • 기존에 쓰던 Jparepository 가 아닌 Crudrepository 을 쓴다

이후 구성은 MySQL와 동일하다.

'Java > Spring' 카테고리의 다른 글

MVC (Model-View-Controller) 구조  (0) 2024.06.25
영속성 컨텍스트  (0) 2024.06.24
DTO, DAO, VO, Record 개념 및 차이  (0) 2024.06.24
@Controller와 @RestController 의 설명 과 차이  (0) 2024.06.24
@Transactional  (0) 2024.06.24