Coding History/Team Project

팀플) 별자리 데이터 캐싱 구현 (Redis)

BlackBirdIT 2024. 11. 19. 10:11

지금 어느정도 설계는 다 완료 되었는데 캐싱 시스템이 있으면 좋을 것 같음.

과도한 요청이 사용자 경험에 영향을 끼치니까 만약 사용자가 자주 요청하는 것들은 기억해두고 처리하면 아주 좋을 것 같으니까 구현해두면 경험적으로도 비용적으로도 유리하다는 생각.


그래서 이걸 Redis로 처리할거고 먼저 로컬에서 설치하고 나중에 배포할 때는 Docker로 할지 고민인데..
지금 개발 단계긴하지만 하고 있는게 팀플이기 때문에 Docker로 처리하는게 접근성면에서 조금 더 유리할 것 같다. 나중에 배포할 때도 한번 더 안거쳐도 되고..

근데 그냥 잘 생각해보니까 스프링 리액트에다가 도커까지 엮어서 뭐 하기 귀찮다 지금 그게 중요한게 아니니까 나는 우선 로컬에서 설치해서 진행하자.

brew install redis

정상 작동 확인하고

혹시 모르니 기본 포트를 사용하는지까지 확인하고.

redis-cli
> INFO | grep tcp_port
127.0.0.1:6379>

yml 설정에 redis 작성해주고.. 의존성 주입까지 함.

    //Redis 설정
    implementation ("org.springframework.boot:spring-boot-starter-data-redis")

일단은 서버가 정상 구동이 되는지 실행 시켜보고..

서버도 정상적으로 돌아가고 내가 구현한 기능들도 다 점검 해보니 이상없음을 확인함.

이제 캐싱 구현 시작.

CacheConfigRedisConfig를 작성하고

ConstellationService클래스에 요청을 보내는 매서드에다가

@Cacheable(value = "constellations", key = "#latitude + '-' + #longitude + '-' + #startDate + '-' + #endDate")

이거 한줄 추가해서 끝!

그래서 CacheConfigRedisConfig의 역할이 뭐냐면

1. CacheConfig

  • 역할: Spring의 캐싱 시스템을 설정.
  • 주요 기능:
    • Spring의 캐싱 기능 활성화 (@EnableCaching).
    • Redis를 Spring Cache의 기본 구현체로 등록.
    • 캐시 만료 시간(TTL, Time-To-Live)이나 기타 기본 캐시 동작을 설정.

2. RedisConfig

  • 역할: Redis 서버와 직접적인 연결을 설정.
  • 주요 기능:
    • Redis 서버와의 연결을 생성 (RedisConnectionFactory).
    • Redis 데이터를 직렬화/역직렬화하는 방식 지정 (RedisTemplate).

이렇다.

일단 기본적으로 되어있는 걸 갖다 쓰는거니까 나중에 필요하면 수정이 될듯.


코드는 이까지 하고 Redis가 정확히 뭘 하는지도 알아야겠지?

Redis 캐싱의 기본 원리

  1. In-memory 데이터 저장:
    • Redis는 RAM에 데이터를 저장해 디스크 기반 데이터베이스보다 훨씬 빠르게 데이터를 읽고 쓸 수 있음.
    • 데이터가 메모리에 저장되므로 캐시 조회 속도가 마이크로초 단위로 매우 빠름.
  2. Key-Value 구조:
    • Redis는 데이터를 Key-Value 쌍으로 저장.
    • Key는 고유한 식별자이고, Value는 저장하려는 데이터.
    • 예: "user:1:name" => "John"
  3. TTL (Time-to-Live):
    • 데이터에 유효 시간을 설정 가능.
    • TTL이 지나면 해당 데이터는 자동으로 삭제돼, 오래된 캐시가 시스템에 남아 있는 것을 방지.
  4. 직렬화:
    • 데이터를 Redis에 저장하기 위해 객체를 직렬화(Serialize)해서 문자열 또는 바이너리 형태로 변환.
    • Spring에서는 GenericJackson2JsonRedisSerializer를 사용해 JSON 형식으로 직렬화/역직렬화 가능.

그래서 이걸 지금 내 프로젝트에서는 어떤식으로 동작하냐면

Spring Cache와 Redis 연동

Spring의 CacheManagerRedis를 연결해 캐싱을 처리:

  1. 캐시 조회 (@Cacheable):
    • 캐시 키를 기반으로 Redis에서 데이터를 조회.
    • 예: get constellations::37.5665-126.9780-2024-11-20
  2. 캐시 저장 (@Cacheable):
    • Redis에 데이터가 없는 경우, 데이터 조회 후 캐시에 저장.
    • 데이터 저장 시 TTL(유효 시간) 설정.
  3. 캐시 삭제 (@CacheEvict):
    • 데이터가 변경되거나 유효하지 않으면 Redis에서 해당 키를 삭제.
  4. 캐시 갱신 (@CachePut):
    • 특정 데이터가 항상 최신 상태를 유지해야 할 때 Redis에 강제로 값을 갱신.

이런식으로 동작함.


여튼 캐싱에 대한 것은

        // 캐시 목록별 TTL 설정
        Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();

        // 별자리 데이터 캐시 - TTL: 30분
        cacheConfigurations.put("constellations",
                RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)));

        // 행성 가시성 데이터 캐시 - TTL: 10분
        cacheConfigurations.put("planetVisibility",
                RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)));

        // 기타 캐시 데이터 - TTL: 1시간
        cacheConfigurations.put("generalData",
                RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)));

CacheConfig에서 이렇게 설정해줬고 나중에 더 필요하면 더 추가 될 예정. 목록별로 나눠서 설정해줄 수 있음.

일단 코드는 짜놨으니까 이게 제대로 돌아가는지 확인도 해야됨.


캐싱 잘 되나?

ㅇㅇ 잘 됨.

이제는 행성 데이터 요청 준비 하면 됨.