[Redis] Redis 기초
본문 바로가기

Development/Tip

[Redis] Redis 기초

Redis는 매우 빠른 성능과 다양한 기능으로 인해 현대적인 애플리케이션 개발에서 중요한 역할을 하고 있습니다. 이 글에서는 Redis가 무엇인지, Redis의 특징과 활용 사례를 살펴보고자 합니다.

Redis

Redis는 REmote DIctionary Server의 약자로, 데이터를 키-값 쌍으로 저장하는 인메모리 데이터베이스이다. 이는 Java의 Map 인터페이스와 비슷한 방식으로 데이터를 저장하고 조회할 수 있는 기능을 제공한다. Redis는 단순한 키-값 저장소를 넘어서 다양한 데이터 구조를 지원하며, 고성능과 유연한 사용성을 제공하는 것으로 널리 알려져 있다.

Redis의 특징

인메모리 데이터베이스

이미지 출처: Db2 for i: In Memory

Redis는 데이터를 메모리(RAM)에 저장하는 인메모리 데이터베이스이다. 이로 인해 디스크 기반 데이터베이스에 비해 매우 빠른 데이터 읽기 및 쓰기 성능을 제공한다.

일반적인 관계형 데이터베이스(RDBMS)는 데이터의 영속성을 보장하기 위해 데이터를 디스크(SSD 또는 HDD)에 저장한다. 이러한 저장 방식은 안정성을 제공하지만, 디스크 입출력(I/O)에 의한 지연으로 인해 성능이 저하될 수 있다.

 

반면에 Redis는  모든 데이터를 메모리에 저장하여 복잡한 I/O 작업을 피할 수 있으며, 이는 데이터베이스 작업의 빠른 처리 속도를 가능하게 한다. 따라서 Redis는 빠른 업데이트가 필요한 데이터(예: 페이지 뷰 카운트), 사용자 세션 정보, 실시간 분석 데이터, 그리고 캐싱 등에 적합하다. 이러한 특성 때문에 Redis는 데이터의 지속성이 중요하지 않거나, 데이터의 유효 기간이 짧은 경우에 특히 유용하다.

NoSQL

Redis는 NoSQL 데이터베이스의 한 종류로, 전통적인 관계형 데이터베이스와는 달리 테이블과 스키마에 얽매이지 않는 유연한 데이터 저장 방식을 제공한다. NoSQL 데이터베이스는 다음과 같은 특성을 가지고 있다:

  • 스키마리스(Schemaless): 미리 정의된 스키마가 없으므로 데이터 구조가 유연하다. 새로운 필드를 쉽게 추가할 수 있어, 데이터 모델링이 자유롭다.
  • 수평적 확장성: 데이터베이스 노드를 추가함으로써 쉽게 확장이 가능하다. 이는 대규모 데이터와 높은 트래픽을 처리하는 데 유리하다.
  • 비정형 데이터 처리: 비정형 데이터(Unstructured data)나 반정형 데이터(Semi-structured data, e.g. JSON)를 효율적으로 저장하고 처리할 수 있다.

다양한 데이터 구조 지원

Redis는 단순한 문자열뿐만 아니라 리스트(List), 셋(Set), 해시(Hash), 정렬된 셋(Sorted Set), 비트맵(Bitmap), 하이퍼로그로그(HyperLogLog), 스트림(Stream) 등의 다양한 데이터 구조를 지원한다. 이러한 데이터 구조는 특정한 애플리케이션 요구사항에 맞게 데이터 처리를 최적화할 수 있도록 한다.

  • 리스트(List): Linked List를 사용하여 삽입 및 삭제가 빠른 데이터 구조를 제공한다.
  • 셋(Set): 집합 연산을 위한 기능을 제공하며, 유니크한 값을 저장한다.
  • 정렬된 셋(Sorted Set): Score를 기반으로 정렬된 데이터 셋을 제공하여 랭킹 시스템 구현에 유용하다.
  • 해시(Hash): 필드와 값으로 이루어진 데이터를 저장할 수 있어, 사용자 프로필 정보와 같은 데이터를 관리하는 데 적합하다.

데이터 지속성 옵션

Redis는 인메모리 데이터베이스임에도 불구하고, 데이터 지속성을 위한 옵션을 제공한다. Redis는 RDB(Redis Database Backup)와 AOF(Append Only File) 두 가지 방식으로 데이터 지속성을 설정할 수 있다.

  • RDB 스냅샷: 특정 시점에 메모리에 있는 데이터를 디스크에 덤프 하여 백업한다. 이는 주기적으로 백업을 수행하여 데이터 복구 시 사용된다.
  • AOF(Append Only File): 모든 쓰기 작업을 로그 파일에 기록하여 데이터의 변경 사항을 지속적으로 저장한다.

복제 및 고가용성

Redis는 Master-Slave 복제를 지원하여 데이터를 여러 인스턴스에 복제할 수 있다. 이를 통해 읽기 성능을 높이고, 데이터의 고가용성을 제공한다. 또한, Redis Sentinel을 사용하여 장애 발생 시 자동으로 장애 조치를 수행하고, 클러스터링을 통해 수평 확장을 지원한다.

Redis의 활용 사례

  1. 캐싱(Caching):
    • Redis는 메모리에 데이터를 저장하므로 빠른 응답 시간이 요구되는 데이터 캐싱에 최적화되어 있다. 웹 페이지의 캐시, 데이터베이스 쿼리 결과의 캐시 등에 널리 사용된다.
  2. 세션 관리(Session Management):
    • 사용자 로그인 정보나 쇼핑몰의 장바구니와 같은 세션 정보를 저장하고 관리하는 데 유용하다. 이는 Redis의 TTL(Time-To-Live) 기능을 활용하여 세션 만료를 자동으로 처리할 수 있다.
  3. 메시지 브로커(Message Broker):
    • Redis는 Pub/Sub 기능을 통해 메시지 브로커로 사용할 수 있다. 이는 채팅 애플리케이션이나 알림 시스템에서 실시간 메시징을 지원한다.
  4. Fast Data Ingest (빠른 데이터 수집)
    • 높은 처리량과 실시간 데이터 분석이 가능하며 대량의 데이터를 실시간으로 수집 및 처리한다.
  5. Feature Stores (피처 스토어)
    • 머신러닝 모델에 필요한 feature 데이터를 저장하고 관리한다.
  6. Vector Search (벡터 검색)
    • 벡터 공간에서 가장 가까운 벡터를 찾아 유사한 항목을 검색한다.
    • 예시: 이미지 유사도 검색, 추천 시스템, NLP 문장 유사도 계산.

 

Redis 데이터 구조 및 명령어

문자열 (String)

가장 기본적인 자료형으로, Java의 Map <String, String>처럼 동작한다. 저장할 수 있는 최대 크기는 512MB이다.

  • SET key value: 새로운 데이터를 삽입한다.
  • GET key: 문자열 데이터를 가져온다.
  • INCR, DECR: 정수로 저장된 문자열 값을 증가 또는 감소시킨다.
  • MSET, MGET: 여러 키-값을 한 번에 설정하거나 가져온다.
# SET 명령어로 문자열 데이터 저장
SET mykey "Hello, Redis!"

# GET 명령어로 문자열 데이터 가져오기
GET mykey
# 출력: "Hello, Redis!"

# INCR 명령어로 숫자 증가
SET counter 1
INCR counter
# 출력: (integer) 2

# MSET 및 MGET 명령어로 여러 값 설정 및 가져오기
MSET key1 "value1" key2 "value2"
MGET key1 key2
# 출력: 1) "value1"  2) "value2"

리스트 (List)

Linked List 형태로 여러 문자열 데이터를 저장한다. 주로 스택이나 큐와 같은 구조로 활용된다.

  • LPUSH, RPUSH: 왼쪽 또는 오른쪽에 데이터를 추가한다.
  • LPOP, RPOP: 왼쪽 또는 오른쪽에서 데이터를 제거한다.
  • LLEN: 리스트의 길이를 반환한다.
  • LRANGE: 특정 범위의 원소를 반환한다.
# LPUSH 및 RPUSH로 리스트에 데이터 추가
LPUSH mylist "one"
RPUSH mylist "two"

# LPOP 및 RPOP으로 리스트에서 데이터 제거
LPOP mylist
# 출력: "one"
RPOP mylist
# 출력: "two"

# LPUSH로 여러 데이터 추가 후 LLEN으로 리스트 길이 확인
LPUSH mylist "1" "2" "3"
LLEN mylist
# 출력: (integer) 3

# LRANGE로 특정 범위의 데이터 가져오기
LRANGE mylist 0 -1
# 출력: 1) "3"  2) "2"  3) "1"

집합 (Set)

순서가 없는 유일한 문자열의 집합이다. 중복된 값을 허용하지 않는다.

  • SADD: 집합에 요소를 추가한다.
  • SREM: 집합에서 요소를 제거한다.
  • SMEMBERS: 집합의 모든 요소를 반환한다.
  • SISMEMBER: 특정 요소의 존재 여부를 확인한다.
  • SCARD: 집합의 크기를 반환한다.
  • SINTER, SUNION: 여러 집합의 교집합, 합집합을 구한다.
# SADD로 집합에 요소 추가
SADD myset "apple" "banana" "cherry"

# SMEMBERS로 집합의 모든 요소 가져오기
SMEMBERS myset
# 출력: 1) "banana"  2) "apple"  3) "cherry"

# SISMEMBER로 특정 요소의 존재 여부 확인
SISMEMBER myset "apple"
# 출력: (integer) 1

# SREM으로 요소 제거
SREM myset "banana"
SMEMBERS myset
# 출력: 1) "apple"  2) "cherry"

# SCARD로 집합의 크기 확인
SCARD myset
# 출력: (integer) 2

해시 (Hash)

필드-값 쌍으로 이루어진 데이터 구조로, 한 키에 여러 필드를 저장할 수 있다.

  • HSET: 해시에 필드-값 쌍을 추가한다.
  • HGET: 특정 필드의 값을 가져온다.
  • HMGET: 여러 필드의 값을 가져온다.
  • HGETALL: 모든 필드-값 쌍을 반환한다.
  • HKEYS: 모든 필드 이름을 반환한다.
  • HLEN: 필드의 개수를 반환한다.
# HSET으로 해시에 필드-값 쌍 추가
HSET user:1001 name "Alice"
HSET user:1001 email "alice@example.com"

# HGET으로 특정 필드의 값 가져오기
HGET user:1001 name
# 출력: "Alice"

# HGETALL로 모든 필드-값 쌍 가져오기
HGETALL user:1001
# 출력: 1) "name"  2) "Alice"  3) "email"  4) "alice@example.com"

# HMGET으로 여러 필드의 값 가져오기
HMGET user:1001 email name
# 출력: 1) "alice@example.com"  2) "Alice"

# HLEN으로 필드의 개수 확인
HLEN user:1001
# 출력: (integer) 2

정렬된 집합 (Sorted Set)

Unique 한 값과 점수(실수)를 함께 저장하여 점수에 따라 정렬된 데이터를 제공한다.

  • ZADD: 요소를 추가하고 점수를 설정한다.
  • ZINCRBY: 점수를 증가시킨다.
  • ZRANK, ZREVRANK: 요소의 순위를 반환한다.
  • ZRANGE, ZREVRANGE: 특정 범위의 요소를 반환한다.
# ZADD로 정렬된 집합에 요소 추가
ZADD leaders 100 "Alice"
ZADD leaders 200 "Bob"
ZADD leaders 150 "Charlie"

# ZRANGE로 정렬된 집합의 요소 가져오기
ZRANGE leaders 0 -1
# 출력: 1) "Alice"  2) "Charlie"  3) "Bob"

# ZRANK로 특정 요소의 순위 확인
ZRANK leaders "Bob"
# 출력: (integer) 2

# ZREVRANGE로 역순으로 요소 가져오기
ZREVRANGE leaders 0 -1
# 출력: 1) "Bob"  2) "Charlie"  3) "Alice"

# ZINCRBY로 점수 증가
ZINCRBY leaders 50 "Alice"
ZRANGE leaders 0 -1 WITHSCORES
# 출력: 1) "Charlie"  2) "150"  3) "Bob"  4) "200"  5) "Alice"  6) "150"

공용 명령어

  • DEL: 키를 제거한다.
  • EXPIRE: 키의 만료 시간을 설정한다.
  • EXPIRETIME: 키의 만료 시간을 반환한다.
  • KEYS pattern: 특정 패턴에 일치하는 키를 검색한다.
  • FLUSHDB: 모든 키를 제거한다.
# SET 및 EXPIRE로 데이터 만료 시간 설정
SET tempkey "temporary value"
EXPIRE tempkey 10

# DEL로 키 제거
DEL tempkey

# KEYS로 모든 키 가져오기 (테스트 환경에서만 사용)
KEYS *
# 출력: 각 키의 목록이 반환됨

# FLUSHDB로 모든 키 제거 (테스트 환경에서만 사용)
FLUSHDB
# 출력: OK

라이선스 변경 사항

2024년 3월 20일 기준으로 Redis는 라이선스가 변경되어 더 이상 완전한 오픈소스 소프트웨어라고 하기 어렵다. 새로운 라이선스는 특정 상업적 사용에 제한을 두고 있기 때문이다. 그러나 대부분의 일반적인 사용 사례에 대해서는 여전히 무료로 사용할 수 있다.

참고