본문 바로가기
Study OR Book/실전 레디스

[실전 레디스] Chaprter 03_고급 기능

by Baest 2025. 6. 9.

 

 

이 장에서는 레디스의 고급 기능인 파이프라인, 루아 스크립팅, 레디스 함수, 트랜잭션, 모듈 기능 중심으로 다룬다.

 

 

3.1 파이프라인

  • 파이프라인은 이전 요청의 응답을 기다리지 않고 새로운 요청을 보낼 수 있는 기능
  • 여러 명령어를 동시에 송신하여 네트워크 RTT를 절약 가능
  • MSET/MGET도 여러 키를 한번에 작업할 수 있지만 파이프라인이 더 범용적
  • 조건 분기 등을 적용할 수 없어서 다소 복잡한 로직에는 부적합
  • 다른 클라이언트가 연결된 상황에서는 다른 명령어가 간섭할 가능성도 있으므로 스크립트의 원자적 처리를 보증할 수 없음

복잡한 로직과 원자적 처리가 필요할 때는 아래 기술을 사용한다.

 

  1. 트랜잭션: 원자적 처리
  2. 루아 스크립팅: 복잡한 로직 구현, 원자적 처리
  3. 모듈: 복잡한 로직 구현, 원자적 처리

 

redis-cli나 다른 레디스 라이브러리는 대량의 데이터를 삽입하기 위한 기능을 지원한다.

--pipe 옵션을 사용해 실행하면 실행에 성공한 명령어 개수(replies), 오류가 발생한 명령어 개수(errors)가 표시된다.

 

3.2 루아

루아 스크립트

  • Redis는 내장 스크립트 언어로 Lua를 채택
  • Redis 서버에서 직접 실행되는 스크립트
  • 원자성(Atomicity) 보장 - 스크립트 전체가 하나의 트랜잭션처럼 동작

루아를 사용하는 이유

  • 네트워크 라운드트립 감소: 여러 명령어를 한 번에 실행
  • 원자성 보장: 중간에 다른 클라이언트의 개입 불가
  • 복잡한 로직 구현: Redis 명령어만으로 어려운 처리 가능
  • 성능 향상: 서버 사이드에서 직접 실행

 

앞서 언급된 파이프라인은 편하지만 다음과 같은 문제가 있고, 이때 루아의 특징으로 커버가 가능하기 때문에 좋은 선택지가 될 수 있다.

 

파이프라인의 문제

  • 여러 종류의 명령어를 처리할 수 있으나 조건 분기 등 로직 기반 처리 불가능
  • 쓰기, 읽기 모두 포함된 작업을 진행할 때, 쓰기 작업 이전에 읽기 작업 결과를 기다려야함. 이로 인해 지연 시간 발생

루아의 특징

  • 조건 분기와 같은 복잡한 로직을 기술 할 수 있음
  • 쓰기와 읽기 지연 시간을 최소화하도록 설계

 

이페머럴 스크립트

레디스는 오랫동안 이페머럴 스크립트로 루아를 실행할 수 있었지만, 레디스 7.0 이후 레디스 함수로 루아 실행이 가능해졌다.

이페머럴 스크립트의 문제점은 스크립트가 레디스 서버 측 캐시에 저장될 뿐 언제든 삭제될 수 있다. 

그외 문제점

 

  • SHA1의 다이제스트 값은 직접적으로 어떤 의미를 나타내지 않기 때문에 디버깅이 어려움
  • KEYS와 ARGV를 제대로 사용하지 않고 스크립트를 그대로 렌더링하는 안티 패턴을 따를 가능성 있음

 

레디스 함수

레디스 함수는 7.0의 대표 기능이며, 이페머럴 스크립트의 문제점을 극복하기 위한 대체 기능이다.

만약 기존에 적용된 이페머럴 스크립트를 사용하는 상황이 아니라면, 레디스 7.0과 루아를 사용할 때 레디스 함수를 사용하는 것이 좋다.

 

  • 이페머럴 스크립트로 작성된 루아를 대체하는 기능이므로 원자적 처리가 보장
  • 실행 중에는 다른 처리를 블록하기 때문에 장시간 실행하는 것은 피해야함
  • 함수가 마스터에서 레플리카로 복제
  • 스냅숏이나 AOF로 영속화되어 데이터와 동등한 내구성을 가짐
  • 라이브러리라는 개념 도입하여, 코드 공유가 간소화

 

3.3 트랜잭션

분리하면 안 되는 여러 작업을 하나의 그룹으로 묶어서 다루는 단위

Redis 트랜잭션의 특징

  • 개별 명령어 수준에서의 원자적 처리를 보장
  • MULTI/EXEC 명령어 실행 중에는 다른 클라이언트의 간섭 없이 원자적 처리 가능
  • 트랜잭션은 MULTI 명령어 뒤에 선언된 명령러를 큐에 넣어서 처리
    • 레디스의 트랜잭션은 실행한 명령어를 큐에 넣기만하고, 데이터 세트를 변경하는 것은 아님
    • 도중에 계산한 결과값을 바탕으로 다음 작업이 진행되는 경우 부적합 -> 루아 작업 검토 필요
  • RDBMS에서 제공하는 롤백 기능을 지원하지 않고, 명령어 실패 시 그대로 남은 작업 이어서 처리

 

3.4 모듈

  • 레디스 4.0부터 모듈 기능 제공
  • 레디스 소스코드를 수정하지 않고도 C언어로 구현하여 레디스 서버에 독립적 추가 가능
    • 확장성 뛰어난 시스템이 됐다고 말할 수 있는 근거
    • 간단히 말하면, 레디스 기능을 확장할 수 있는 동적 라이브러리
  • 레디스 서버 버전에 의존하지 않도록 호환성 고려하여 구현
    • 모듈만을 위한 API 만들어서 레디스와 연동 가능
    • 레디스 모듈의 API 버전과 레디스 서버의 버전은 일치하도록 만드는 과정 필요

 

3.5 키 공간 알림

  • Redis 키의 변경 사항을 실시간으로 알림받는 기능
  • Pub/Sub 메커니즘을 활용
  • 키 생성, 수정, 삭제, 만료 등의 이벤트 감지

 

3.6 클라이언트 측 캐싱

클라이언트 측 캐싱

  • Redis 6.0에서 도입된 기능
  • 클라이언트 애플리케이션에서 Redis 데이터를 로컬 캐시
  • 네트워크 지연 시간 최소화 및 Redis 서버 부하 감소

동작 원리

  1. 클라이언트가 데이터 요청
  2. Redis 서버가 데이터와 함께 무효화 메시지 채널 정보 전송
  3. 클라이언트가 로컬에 캐시 저장
  4. 데이터 변경 시 Redis가 무효화 메시지 전송
  5. 클라이언트가 로컬 캐시 무효화