메뉴

Redis Persistent Volume

2022-04-26 01:55:25

목차

Motivation

Joinc는 Redis를 문서에 대한 Cache로 사용하고 있다. 프로세스는 아래와 같다.
  1. 유저가 문서를 요청하면 캐시에 문서가 있는지 조회 한다.
    1. 캐시에 문서가 있다면 즉시 리턴하고 완료한다.
  2. 데이터베이스를 조회해서 문서를 읽는다.
  3. Wiki 포멧의 문서를 HTML, Javascript, CSS 형태로 변환한다. 이때 plugin 형식의 코드도 호출한다.
  4. 변환된 문서를 캐시에 저장하고
  5. 유저에게 전송한다.
Redis를 사용함으로써 데이터베이스의 부하를 줄일 수 있고, 서비스의 속도와 안정성을 크게 높일 수 있었다. 문제는 Redis는 In-Memory 데이터베이스로, 프로세스가 내려가면 데이터가 날아가 버린다는 것이었다.

해서 애플리케이션, 프로세스, 서버, Redis 가 재시작하더라도 데이터를 그대로 유지하는 방법을 찾기로 했다.

Redis Persistence volume

Redis는 메모리에 있는 데이터를 디스크에 쓰는 방법으로 지속성(persistence)를 제공한다. Redis는 2가지의 지속성 옵션을 제공한다.

Redis 준비

테스트를 위해서 Docker 기반으로 Redis를 준비했다.
# docker run --name redis-test -p 6379:6379 redis

RDB 간단 테스트

RDB는 간단하고 빠르게 사용할 수 있는 "백업 기반"의 persistence 옵션이다. 일정 시간간격으로 스냅샷을 찍기 때문에 데이터가 일부 유실될 수 있다는 문제가 있기는 하지만 Redis를 쓰는 대부분의 워크로드에서는 큰 문제가 되지는 않을 거라서 널리 사용하는 방법이다.

사용자는 save명령을 이용해서 원하는 시간에 스냅샷을 만들 수 있다. 테스트해보자. redis-cli로 테스트해보자.
127.0.0.1:6379> set yun dream
OK
127.0.0.1:6379> set bus banana
OK
127.0.0.1:6379> keys *
1) "bus"
2) "yun"
127.0.0.1:6379> save
OK
save 명령을 내리면 설정된 디렉토리에 dump.db라는 백업파일을 저장한다. 내가 사용한 redis docker image는 /data디렉토리에 파일을 저장한다. redis 컨테이너에 접속해서 살펴보자.
# docker exec -it 0fac71833cc4 /bin/bash
root@0fac71833cc4:/data# ls
dump.rdb
dump.rdb 파일이 만들어진걸 확인 할 수 있다. 이제 컨테이너를 재 시작하더라도 save 시점에 저장되었던 데이터들을 읽을 수 있게 됐다.

docker에서의 RDB 사용 : docker volume

요즘 애플리케이션들은 모두 docker를 기반으로 배포를 하고 있어서, 아래와 같이 docker 파일을 만들었다.
version: '3.8'
services:
  cache:
    image: redis
    restart: always
    ports:
      - '6379:6379'
    command: redis-server --save 20 1 
    volumes: 
      - cache:/data
volumes:
  cache:
    driver: local
중요 부분을 살펴보자. save 옵션을 이용해서 백업 주기를 설정 할 수 있다. 옐르 들어 60초 동안 10개의 데이터가 변경될 경우 저장하고 싶은 경우
save 60 10
로 하면 된다. 첫번째 필드는 "초" 두번째 필드는 "업데이트된 데이터 갯수다". docker-compose의 설정은 20초 동안 1개라도 데이터 변경이 있을 경우 저장하라는 의미가 되겠다.

redis는 /data 디렉토리에 dump.rdb를 저장한다고 했으니, 이 /data를 실제 디스크에 mount 혹은 bind 해서 기록할 수 있도록 해야 할 것이다.
volumes:
  cache:
    driver: local
local volume driver를 이용해서 cache 라는 이름의 볼륨을 만들었다. 이 볼륨은 파일시스템에 있기는 하지만 도커가 직접 관리하는 파일 시스템이다.

컨테이너를 실행해 보자.
# docker-compose up     
Creating volume "redis_cache" with local driver
Recreating redis_cache_1 ... done
Attaching to redis_cache_1
cache_1  | 1:C 29 Apr 2022 04:14:48.235 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
cache_1  | 1:C 29 Apr 2022 04:14:48.235 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
cache_1  | 1:C 29 Apr 2022 04:14:48.235 # Configuration loaded
cache_1  | 1:M 29 Apr 2022 04:14:48.235 * monotonic clock: POSIX clock_gettime
cache_1  | 1:M 29 Apr 2022 04:14:48.236 * Running mode=standalone, port=6379.
cache_1  | 1:M 29 Apr 2022 04:14:48.236 # Server initialized
cache_1  | 1:M 29 Apr 2022 04:14:48.236 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
cache_1  | 1:M 29 Apr 2022 04:14:48.237 * Ready to accept connections

docker volume 명령으로 컨테이너가 만든 volume을 확인 할 수 있다.
# docker volume ls
local     fa3f36ec51fcdf7a2ea23db9f9ec5fd60bf22d11ed4dbaf21455ade0f4c1184d
local     fab2996c29a9439ef68d016c48ccd54094872f68434e54381c2caec503835e21
local     redis_cache
reedis에 접근해서 데이터를 남기고 container를 리스타트해도 기존 데이터가 유지되는 걸 확인 할 수 있다.

docker에서의 RDB 사용 : bind-mount

bind-mount는 호스트의 파일 시스템을 그대로 사용한다. 호스트의 파일시스템을 사용하기 때문에 훨씬 유연하게 사용 할 수 있다. 위에서 사용했던 docker-compose 설정을 bind-mount 방식으로 수정했다.
version: '3.8'
services:
  cache:
    image: redis
    restart: always
    ports:
      - '6379:6379'
    command: redis-server --save 20 1 
    volumes: 
      - $HOME/red-scache:/data
홈디렉토리의 red-scache 디렉토리를 redis의 /data 메 마운트 시켰다. 도커를 실행하면 red-scache 디렉토리 밑에 dump.rdb 파일이 만들어지는 걸 확인 할 수 있을 것이다.
# echo $PWD 
/home/yundream/red-scache

# ls -al
합계 12
drwxr-xr-x  2 systemd-coredump root             4096  4월 29 14:33 .
drwxr-x--- 42 yundream         yundream         4096  4월 29 14:34 ..
-rw-r--r--  1 systemd-coredump systemd-coredump  137  4월 29 14:33 dump.rdb

AOF

AOF 방식의 persistent 옵션은 다른 문서로 자세히 살펴보겠다.

참고