본문 바로가기
Programming/Docker

Docker 활용기(4) - redis 구성해보기

by ★용호★ 2017. 1. 17.

Custom config 파일 적용하기

redis 이미지를 구동하면 설정이 기본값으로 적용되기 때문에 직접 설정한 redis.conf파일을 적용하려면 docker run 명령 수행시에 -v 옵션을 통해 container 내의 /usr/local/etc/redis/redis.conf 경로로 볼륨을 지정하거나 Dockerfile에 설정파일을 해당 경로로 복사를 수행해주면 된다. 나는 Dockerfile을 사용하여 빌드한 후 docker-compose로 컨테이너를 구동시키기 때문에 아래와 같이 Dockerfile에 설정을 했다.

FROM redis:3.0
MAINTAINER Yongho Choi <yongho1037@gmail.com>

RUN mkdir /var/log/redis

RUN mkdir /usr/local/etc/redis

COPY conf/redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
  • redis.conf 파일에 로그를 남길 경로를 /var/log/redis로 지정했고, Dockerfile 내에 RUN 명령어를 통해 해당 디렉토리를 생성해주었다.
  • config 파일을 복사할 /usr/local/etc/redis 디렉토리를 COPY 명령 전에 수행하여 에러를 방지했다.


명령어

redis 설정파일은 /etc/redis에, redis 실행 파일은 /etc/init.d에, redis 백업파일은 /var/lib/redis에 있다고 가정

  • 데이터 백업

    • 백업 파일 위치 확인
    $ cat /etc/redis/redis.conf | grep '^dir ' | cut -d' ' -f2
    • 백업 파일을 복사하기 전에 현재 데이터 갱신
    $ redis-cli bgsave 또는 save
    • 일자를 기록하여 파일 복사
    $ cp /var/lib/redis/dump.rdb /var/lib/redis/backup/dump.$(date +%Y%m%d%H%M).rdb
    
  • 데이터 복원

    • AOF 모드 확인 (AOF 모드는 명령을 실행할 때마다 파일에 갱신하는 모드. 성능에 영향을 끼칠 수 있음)
    $ cat /etc/redis/redis.conf | grep 'appendonly ' | cut -d' ' -f2
    
    • 위 명령의 실행 결과가 no 인경우 RDB 방식.
      • redis 서버 종료
    $ /etc/init.d/redis-server stop
    
    • 현재 사용 중인 rdb 파일 제거
    $ rm -f /var/lib/redis/dump.rdb
    
    • 백업해둔 rdb 파일 복사
    cp /var/lib/redis/backup/dump.rdb /var/lib/redis/dump.rdb
    
    • 이름은 dump.rdb 이어야 하고 소유자와 그룹이 redis 어야 함.  $ chown redis:redis dump.rdb
      • redis-server 구동
    $ /etc/init.d/redis-server start
    


트러블 슈팅

MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.

redis 관련 테스트에서 hset 명령을 10000000번 수행 하던 중 아래와 같은 에러가 발생하였다.

MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

redis-cli를 통해 info persistence명령을 수행해보니 rdb_last_bgsave_status가 err로 표시되어 있다.

127.0.0.1:6379> info persistence
# Persistence
loading:0
rdb_changes_since_last_save:456099
rdb_bgsave_in_progress:0
rdb_last_save_time:1483424684
rdb_last_bgsave_status:err
rdb_last_bgsave_time_sec:8
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
  • 기본적으로 이 BGSAVE가 실패하게 되면 Redis는 설정에 따라서 Write 커맨드를 전부 거부 해버린다.
  • persistent를 위해서 BGSAVE로 rdb를 만들어내는 것은 성능을 떨어뜨린다.
  • 에러를 제거하려면 config set stop-writes-on-bgsave-error no 를 통해서 해당 설정을 꺼둔다.
  • 에러 발생 원인으로는 vm_overcommit_memory 정책, 디스크 이슈 등이 있다.


3.2.x 버전에서 protected-mode 관련 오류

redis 3.2.x에서 protected-mode는 기본 yes로 설정되어 있는데 docker로 실행 할 경우 아래와 같은 오류가 발생한다.

*** FATAL CONFIG FILE ERROR ***           
Reading the configuration file, at line 80
>>> 'protected-mode yes'                  
Bad directive or wrong number of arguments

그래서 docker에서 redis를 구동할 경우에는 해당 옵션을 no로 설정해줘야 한다.


Can't save in background: fork: Cannot allocate memory

이 에러는 더이상 할당 가능한 메모리가 없을 경우에 발생한다. ps 명령을 사용하여 메모리 사용량을 확인해보았다.

root@17e3e60b912a:/data# ps -eo user,pid,ppid,rss,size,vsize,pmem,pcpu,time,cmd --sort -rss
USER       PID  PPID   RSS  SIZE    VSZ %MEM %CPU     TIME CMD
redis        1     0 781376 866752 879132 76.6 0.7 00:06:48 redis-server 0.0.0.0:6379
root        37     0  3108   464  20228  0.3  0.0 00:00:00 bash
root        43    37  2076   936  17496  0.2  0.0 00:00:00 ps -eo user,pid,ppid,rss,size,vsize,pmem,pcpu,time,cmd --sort -rss

위에 보이는 것 처럼 memory usage가 76% 정도 였는데 allocate 오류가 발생하는 걸 보니 한계치를 설정해둔 것 같았다. 아래 명령으로 해결할 수 있으나 일시적인 방편이라고 한다. (재부팅하면 다시 설정해야함.)

$ sysctl -w vm.overcommit_memory=1

redis 실행 환경이 docker 기반이었기 때문에 메모리 정보를 확인해보니 linux 머신의 경우 memory와 cpu 정보가 host와 동일하게 따라가는데 windows의 경우에는 memory는 1G로 설정이 되고 있고, cpu의 코어수는 1개로 설정되어 있었다.

  • 메모리 정보 확인
$ cat /proc/meminfo
  • cpu 정보 확인
$ cat /proc/cpuinfo

그 이유는 windows에서는 virtualbox 위에서 docker가 동작하는데 virtual box에 생성된 VM의 설정이 그렇게 되어 있었기 때문이다. 즉, docker가 cpu와 memory에 관여하는 것이 아니고, docker 자신이 실행되는 host의 환경을 따라가는 것뿐이다.

  • 사용량 조절하기 (win7)
    1. docker-machine stop <머신 이름>
    2. virtual box에서 설정 조정
    3. docker-machine start <머신 이름>

사용량을 조절하고 나면 docker container에 host 환경을 따라가기 때문에 별도의 수정 없이 변경 사항이 적용된다. 즉, linux 환경에서도 container만 유지된다면 서버 환경이 변경되는 경우 자동으로 머신이 업그레이드 되는 효과를 얻을 수 있다.

댓글