Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[WIL]20240818 팀 프로젝트 마무리! Redis와 캐싱&세션 본문

개발Article

[WIL]20240818 팀 프로젝트 마무리! Redis와 캐싱&세션

최밤빵 2024. 8. 18. 21:25

팀 프로젝트가 끝났다. 늦게 합류하기도 했고, 나는 기능적으로 한 게 없고, 프로젝트에 대해 많이 아는것도 없기때문에 그냥 같이 흐르는 중! 팀 프로젝트를 계속 진행 할 예정이라, 고급기능에 대해서 생각해야하는데 해보고싶은게 있어서 고민중이고, 전에 Redis를 다루면서 캐싱에 관련한 부분이 많아서 이번주 WIL 내용으로 쓰기로했다. 

Redis는 인메모리 데이터 저장소로, 고속의 읽기 및 쓰기 성능을 제공하여 캐싱과 세션 관리를 효과적으로 수행할 수 있다. Spring Boot와 Redis를 연동하여 애플리케이션의 성능을 최적화하고, 사용자 세션을 관리하는 방법을 이해하기위해 노력했다! 

🫨Spring Boot와 Redis의 연동

Spring Boot와 Redis를 연동하기 위해서는 Spring Data Redis 라이브러리를 사용하면 된다. 이를 통해 Redis 서버와 손쉽게 통신하고, 데이터 저장과 조회를 수행할 수 있다. 먼저 build.gradle 파일에 Redis 의존성을 추가한다.

 

▷ Redis 의존성 추가

// build.gradle에 추가
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}

 

▷ Redis 설정 파일 작성

Redis를 사용할 수 있도록 Spring Boot 설정 파일(application.properties)에 Redis 연결 설정을 추가해야 한다.

# application.properties에 추가
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=6000

→ 위 설정에서는 Redis 서버가 localhost:6379에 있다고 가정한다. 이 값을 환경에 맞게 설정하면 된다.

 

▷ 왜 6379?

→ 6379는 Redis의 기본 포트 번호이다. Redis 서버는 기본적으로 이 포트를 사용하여 클라이언트와 통신한다.

8080은 HTTP서버에서 사용되는 기본포트라서 Redis는 TCP 프로토콜을 사용해서 통신하기 때문에 Redis 전용 포트 6379와 HTTP 전용포트 8080은 서로 다른 목적으로 사용된다. 만약 8080을 레디스 포트로 사용하게 되면 기존에 HTTP서버가 동작하고 잇을 경우 충돌이 발생할 수 있다. 필요하다면 다른 포트를 사용할 수 있지만 일반적으로 겹치지 않는 포트를 사용하는 것이 바람직하다. ( 6379는 "NERD"라는 단어를 숫자로 변환한 것이기도 하다. 이는 Redis의 개발자인 Salvatore Sanfilippo가 재미있게 선택한 포트 번호😆)

 

▶캐싱을 위한 Spring Boot와 Redis

캐싱을 사용하면 데이터베이스에 반복적으로 접근하는 대신, 자주 조회되는 데이터를 메모리(여기서는 Redis)에 저장해 두고 빠르게 조회할 수 있어 성능이 개선된다.

 

▷캐싱 활성화

Spring Boot 애플리케이션에서 캐싱을 활성화하려면 @EnableCaching 어노테이션을 사용한다.

// CachingConfig.java
package com.example.demo.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching // 캐싱 기능 활성화
public class CachingConfig {
}

 

▷캐싱 예시 코드

아래 예시에서는 간단한 UserService 클래스에서 Redis 캐싱을 활용하여 사용자 정보를 가져오는 예시를 보여준다. 데이터베이스에서 가져온 사용자 정보를 Redis에 캐싱해두고, 이후 동일한 요청이 들어오면 Redis에서 데이터를 가져오도록 한다.

// UserService.java
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Cacheable(value = "users", key = "#userId") // 캐싱을 적용할 메서드
    public User getUserById(Long userId) {
        // 데이터베이스에서 사용자 정보를 가져오는 메서드
        System.out.println("Fetching user from DB with id: " + userId);
        return userRepository.findById(userId).orElse(null);
    }
}

위 예시에서 @Cacheable 어노테이션을 사용하여 getUserById() 메서드에 캐싱을 적용하였다. users라는 이름의 캐시 저장소에 userId를 키로 하는 데이터를 저장한다. 캐시가 존재하면 메서드를 호출하지 않고, 캐시에서 데이터를 반환한다.

 

▶세션 관리를 위한 Spring Boot와 Redis

세션 관리에서는 애플리케이션이 사용자의 상태를 유지할 수 있도록 도와준다. 기본적으로 Spring Boot에서는 세션을 서버 메모리에 저장하지만, Redis를 활용하면 분산 환경에서도 세션을 관리할 수 있다.

 

▷ Redis를 이용한 세션 설정

Redis를 세션 저장소로 사용하려면, Spring Boot 설정 파일에 아래와 같은 설정을 추가한다.

# application.properties에 추가
spring.session.store-type=redis
spring.redis.host=localhost
spring.redis.port=6379

이 설정은 세션을 Redis에 저장하도록 구성한다. Redis는 세션 정보를 저장하고 관리하며, 여러 대의 서버 간 세션을 공유할 수 있게 해준다.

 

▷세션 예시 코드

다음은 Redis를 이용하여 세션을 관리하는 간단한 로그인 기능의 예시 코드이다. 사용자가 로그인하면 Redis에 세션 정보를 저장하고, 로그아웃하면 세션 정보를 삭제한다.

// AuthController.java
package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpSession;

@RestController
public class AuthController {

    @PostMapping("/login")
    public String login(HttpSession session) {
        // 로그인 로직 수행 후 세션에 사용자 정보 저장
        session.setAttribute("user", "user123");
        return "User logged in";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        // 로그아웃 시 세션 무효화
        session.invalidate();
        return "User logged out";
    }

    @GetMapping("/session")
    public String getSession(HttpSession session) {
        // 현재 세션에 저장된 사용자 정보 반환
        String user = (String) session.getAttribute("user");
        return user != null ? "Logged in as: " + user : "No active session";
    }
}

위의 코드에서 HttpSession 객체를 사용하여 로그인 시 세션을 설정하고, 로그아웃 시 세션을 무효화하는 로직을 구현하였다. 세션은 Redis에 저장되기 때문에 서버가 재시작되어도 세션 정보가 유지된다.

 

▶캐싱과 세션 관리의 장단점

 

▷장점:

→성능 향상:

자주 사용하는 데이터를 캐싱함으로써 데이터베이스에 대한 접근을 줄이고, 애플리케이션의 성능을 크게 향상시킬 수 있다.

→ 확장성:

Redis를 통해 세션을 관리하면 여러 대의 서버 간에 세션을 공유할 수 있어 확장성이 높다.

→ 유연성:

Redis는 다양한 데이터 구조를 지원하므로 다양한 종류의 데이터를 저장하고 관리할 수 있다.

 

▷단점:

→ 데이터 일관성 문제:

캐시와 데이터베이스 간의 데이터 불일치가 발생할 수 있다.

→ 복잡한 설정:

Redis와 같은 외부 시스템을 설정하고 관리하는 데 추가적인 노력이 필요하다.

→ 단일 장애점(Single Point of Failure):

Redis 서버가 다운되면 세션 정보나 캐싱된 데이터에 접근할 수 없다. 이를 위해 Redis Sentinel이나 클러스터링 설정이 필요하다.

 

▶정리

Redis를 사용해서 캐싱과 세션 관리에 대해서 공부하려고 내용을 정리하고, 코드를 구현하는데 정말 이렇게 간단하게 구현이 되는걸까? 싶기도하고 일부러 간단하게 코드를 작성해달라고 했는데, 이게 맞는방법인지도 아직 잘 모르겠지만 코드 뜯어보면 맞는거같기도하고...? 프로젝트하면서 레디스에 대해서 내가 손댈일이 있기나할까 싶지만 이해를 아직 한게 아니라서 되도록이면 손대지 않는걸로...! 어떤건지는 알겠는데 이걸 적용한다고 생각하면 또 얼마나 느릿느릿 많은시간이 걸릴지 모르겠다🥺