500===Dev Database/Redis

Redis 핵심 개념 정리 😋

블로글러 2025. 2. 2. 05:55

오늘은 초고속 인메모리 데이터 스토어로 유명한 Redis의 핵심 개념을 알아보겠습니다!
일반적인 데이터베이스와는 달리 메모리를 기반으로 동작하기 때문에, 매우 빠른 읽기/쓰기 성능을 제공하는 것이 특징입니다. 또한 다양한 데이터 구조를 지원하고 확장성이 높아 캐싱, 세션 관리, 메시지 브로커 등 여러 가지 상황에서 유용하게 활용할 수 있습니다.


1. Redis란? 🤔

🔹 개념 요약

Redis는 Remote Dictionary Server의 줄임말로, Key-Value 형태의 저장소입니다. C언어로 개발되었으며, 한 번에 하나의 요청을 처리하는 싱글 스레드 방식이지만, Event Loop 구조를 통해 아주 빠른 처리를 보장합니다.

🔹 실생활 예시

  • 인터넷 쇼핑몰에서 장바구니 정보를 캐싱해두면, 사용자가 페이지를 이동할 때마다 DB를 재조회할 필요 없이 즉시 로딩할 수 있습니다.
  • 게시판의 ‘좋아요’ 수나 조회 수도 Redis에 저장해두면, 실시간으로 업데이트하며 빠르게 보여줄 수 있습니다.

🔹 어떤 문제를 해결하는가?

  1. 고성능 요구 사항을 충족해야 하는 서비스: 데이터 조회나 삽입이 매우 잦고, 속도가 곧 사용자 만족도로 이어지는 분야(예: 실시간 채팅).
  2. 간단한 데이터 구조를 빠르게 읽고 써야 하는 경우: 간단한 키-값 형태나 리스트/해시/셋과 같은 구조도 빠르게 다룰 수 있습니다.
  3. 메시지 큐 시스템: Pub/Sub 모델을 지원해 메시지 브로커처럼 이벤트를 송수신할 수 있습니다.

2. 어떻게 동작하나요? 🎬

1) 기본 개념

Redis는 데이터를 디스크가 아닌 메모리(RAM)에 상주시킵니다. 필요에 따라 AOF(Append Only File)RDB(Redis Database Backup) 방식을 통해 영속성을 제공하기도 합니다.

간단한 명령어 예시

# Redis 실행 후
redis-cli 

# 키-값 삽입
SET greeting "Hello Redis"

# 키 조회
GET greeting  # 결과: "Hello Redis"

2) 실제 적용 예시

예를 들어, Java 환경에서 Jedis 라이브러리를 사용해 Redis에 접근한다고 가정해봅시다:

import redis.clients.jedis.Jedis;

public class RedisExample {
    public static void main(String[] args) {
        // Redis 서버 접속 (기본 포트 6379)
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // 데이터 추가
            jedis.set("user:1:name", "Alice");
            jedis.set("user:1:age", "20");

            // 데이터 읽기
            String name = jedis.get("user:1:name");
            String age = jedis.get("user:1:age");

            System.out.println("Name: " + name);
            System.out.println("Age: " + age);

            // 리스트 예시
            jedis.lpush("fruits", "apple", "banana", "cherry");
            System.out.println("Fruits: " + jedis.lrange("fruits", 0, -1));
        }
    }
}

🚀 동작 원리

  1. 인메모리 저장: 데이터를 메모리에 적재해 매우 빠른 응답 시간을 확보합니다.
  2. 싱글 스레드 기반: 요청을 직렬화해 처리하지만, CPU가 아닌 메모리 접근이 병목이기에 대부분의 상황에서 매우 빠릅니다.
  3. 데이터 구조별 명령어 지원: String, List, Set, Hash, Sorted Set 등 다양한 구조를 네이티브로 제공하며, 각 구조에 최적화된 명령어가 있습니다.
  4. 옵션 영속성: RDB, AOF 등의 방식을 통해 데이터를 영구 보관할 수 있습니다. 원하는 시점에 스냅샷을 찍거나 모든 변경 이력을 파일에 순차적으로 기록합니다.

3. 주요 장점 🌟

  1. 초고속 처리: 메모리 기반이기에 마이크로초 단위의 응답이 가능합니다.
  2. 다양한 자료구조 지원: 단순 키-값뿐 아니라, 해시, 리스트, 셋, 정렬된 셋 등을 유연하게 다룰 수 있습니다.
  3. 복제 및 클러스터링: 여러 노드로 확장이 가능해, 대규모 트래픽을 처리하거나 고가용성을 구성하기에 좋습니다.
  4. Pub/Sub 기능: 메시지 큐처럼 이벤트 송수신에 활용할 수 있어, 별도의 브로커 없이 간단한 실시간 알림/채팅 구현이 가능합니다.

4. 주의할 점 ⚠️

  1. 메모리 사용량: 모든 데이터를 메모리에 올려두므로, 대용량 데이터를 저장하기엔 비용이 높아질 수 있습니다.
  2. 단순한 쿼리 한계: 복잡한 SQL 쿼리처럼 조인을 수행할 수 없으며, Key-Value 접근 방식에 익숙해야 합니다.
  3. 영속성 설정 주의: RDB나 AOF 설정을 잘못하면, 재시작 시점에서 데이터 유실이 발생할 수 있습니다. 또한, AOF 파일이 매우 커지는 문제도 주의해야 합니다.
  4. 싱글 스레드 제약: 일반적인 상황에서는 충분히 빠르지만, CPU 연산이 많거나 대규모 동시 연결 시 병목이 발생할 수 있습니다.

5. 실제 사용 예시 📱

아래는 Spring Boot에서 Redis를 활용하여 간단히 캐싱 기능을 구현하는 예시입니다.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties

spring.redis.host=localhost
spring.redis.port=6379

간단한 캐시 예제 코드

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value = "userCache", key = "#userId")
    public User getUserById(String userId) {
        // 실제 DB에서 사용자 정보를 가져오는 로직
        // 예시로 가정
        System.out.println("DB 접근 중...");
        return new User(userId, "Alice", 20);
    }
}

// 메인 Application 클래스에서 @EnableCaching 활성화
@SpringBootApplication
@EnableCaching
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }
}

위와 같이 Cache 어노테이션을 사용하면, 최초 호출 시에는 DB에 접근하지만 이후에는 Redis에서 캐시 데이터를 읽어오므로 응답 속도가 크게 향상됩니다.


6. 마치며 🎁

Redis는 인메모리를 기반으로 빠르고 유연한 데이터 처리를 가능하게 해주는 훌륭한 솔루션입니다. 간단한 키-값 캐싱에서부터 Pub/Sub 기능을 이용한 메시지 브로커까지 폭넓은 활용이 가능하다는 점이 최대 장점이지요.

"이 기술을 사용하면 고성능 실시간 서비스를 구현할 수 있습니다!"
만약 빠르고 효율적인 캐시 계층이 필요하거나, 단순하면서도 확장 가능한 구조가 필요한 분들께 Redis를 추천합니다.


참고 자료 및 출처

728x90