/인프라/Redis MISCONF unable to persist on disk 에러 5분 복구 런북
인프라Redis MISCONFunable to persist on disk

Redis MISCONF unable to persist on disk 에러 5분 복구 런북

Redis가 'MISCONF unable to persist on disk'로 쓰기를 전부 거부할 때 쓰는 5분 복구 런북. 디스크 full·overcommit_memory·dir 권한 3대 원인을 진단 명령으로 특정하고 임시조치부터 영구 해결까지 복붙으로 끝냅니다.

Redis MISCONF unable to persist on disk 에러 5분 복구 런북

Redis MISCONF RDB snapshots 에러 5분 긴급 복구 런북 (원인별 진단)

CODE
MISCONF Redis is configured to save RDB snapshots, but it is
currently unable to persist on disk. Commands that may modify the
data set are disabled, because this instance is configured to report
errors during writes if RDB snapshotting fails.

지금 이 에러 원문을 그대로 구글에 붙여넣고 도착하셨다면, 심호흡부터 하시죠. 서비스 쓰기가 전부 막혀서 급하겠지만, 이건 메모리 부족(OOM)도 아니고 Redis가 죽은 것도 아닙니다. Redis는 멀쩡히 살아 있고 읽기(GET)도 정상입니다. 단지 RDB 스냅샷을 디스크에 저장(BGSAVE)하는 데 실패했고, stop-writes-on-bgsave-error yes 설정 때문에 "저장이 안 되면 쓰기를 받지 않겠다"며 SET/LPUSH/INCR 같은 쓰기 명령을 거부하는 상태입니다.

이 글은 개념 설명을 최소화하고 명령 → 결과 해석 → 다음 행동 흐름으로만 갑니다. 순서대로 복붙하세요.

1단계: 지금 당장 쓰기부터 살린다 (임시조치)

원인 분석은 잠시 미루고, 서비스 출혈부터 멈춥니다. 아래 한 줄이면 쓰기가 즉시 복구됩니다.

Bash
redis-cli CONFIG SET stop-writes-on-bgsave-error no

실행하면 OK가 뜨고, 방금까지 막혔던 SET/LPUSH가 다시 통과합니다. 인증이 걸려 있다면 redis-cli -a <password> 또는 -h <host> -p <port>를 붙이세요.

🔴 경고: 이건 진통제일 뿐입니다. 이 설정은 "RDB 저장이 계속 실패해도 조용히 넘어가라"는 뜻입니다. 즉 디스크 저장은 여전히 안 되고 있고, 이 상태에서 Redis가 재기동되면 마지막 성공한 스냅샷 이후의 데이터가 통째로 유실됩니다. 반드시 아래 2~3단계로 근본 원인을 잡은 뒤, 5단계에서 yes로 되돌려야 합니다. 여기서 멈추면 다음 장애는 "데이터 증발"로 옵니다.

2단계: 진짜 원인 3분류 진단 표

MISCONF의 근본 원인은 실무상 세 갈래로 수렴합니다. 아래 표에서 내 로그 문구를 찾으세요.

#원인대표 증상·로그 문구확인 명령근본 조치
디스크 full·권한No space left on device, Permission denied, Failed opening the RDB filedf -h, ls -ld <dir>공간 확보 / chown redis:redis <dir>
fork 시 메모리 부족Can't save in background: fork: Cannot allocate memory, overcommit 경고cat /proc/sys/vm/overcommit_memory (값 0)vm.overcommit_memory=1 영구 적용
dir 경로 문제경로 부재·오타·읽기전용 마운트(Read-only file system)redis-cli CONFIG GET dirdir 재설정 + CONFIG REWRITE

3단계: 진단 복붙 플로우

어느 갈래인지 명령으로 특정합니다. 순서대로 실행하세요.

Bash
# (1) 저장 상태 확인 — 실패 여부와 마지막 성공 시각
redis-cli INFO persistence | grep -E \
  "rdb_last_bgsave_status|rdb_last_save_time|aof_last_bgrewrite_status"

rdb_last_bgsave_status:err 이면 확진입니다. rdb_last_save_time을 사람이 읽는 시각으로 바꾸면 마지막 성공 스냅샷 시점을 알 수 있습니다(date -d @<값>).

Bash
# (2) RDB 저장 경로의 디스크 여유 확인 → 원인 ① 판별
RDB_DIR=$(redis-cli CONFIG GET dir | tail -1)
echo "dir = $RDB_DIR"
df -h "$RDB_DIR"

# (3) 경로 존재·권한 확인 → 원인 ①·③ 판별
ls -ld "$RDB_DIR"

df 결과 Use%가 100%면 원인 ①(디스크 full), ls에서 소유자가 redis가 아니거나 경로가 없으면 ①·③입니다.

Bash
# (4) 시스템 로그에서 근본 에러 문구 확보
journalctl -u redis -n 50 --no-pager | grep -iE "background saving|fork|space|permission"
# systemd가 아니라면:
grep -iE "Background saving error|fork|No space" /var/log/redis/redis-server.log | tail -20

여기서 fork: Cannot allocate memory가 보이고 cat /proc/sys/vm/overcommit_memory0이면 원인 ②로 확정됩니다.

4단계: 원인별 영구 복구 명령

케이스 ① 디스크 full·권한

Bash
# 공간 잡아먹는 범인 찾기 (오래된 로그, dump.rdb 백업 등)
du -sh "$RDB_DIR"/* 2>/dev/null | sort -rh | head
# 불필요한 로그/백업 정리 후 (또는 볼륨 확장 후) 권한 교정
sudo chown redis:redis "$RDB_DIR"
sudo chmod 755 "$RDB_DIR"
# 수동 저장으로 즉시 검증
redis-cli BGSAVE
redis-cli INFO persistence | grep rdb_last_bgsave_status   # ok 확인

케이스 ② fork 시 메모리 부족 (overcommit)

Redis는 BGSAVE 시 프로세스를 fork하는데, overcommit_memory=0이면 커널이 "메모리 부족"으로 fork를 거부합니다. 즉시 + 영구 적용합니다.

Bash
# 즉시 적용
sudo sysctl vm.overcommit_memory=1
# 재부팅 후에도 유지되도록 영구화
echo 'vm.overcommit_memory=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 검증
redis-cli BGSAVE
redis-cli INFO persistence | grep rdb_last_bgsave_status

케이스 ③ dir 경로/권한 문제

Bash
# 존재하고 쓰기 가능한 경로로 재설정 (예시 경로는 환경에 맞게)
redis-cli CONFIG SET dir /var/lib/redis
sudo chown redis:redis /var/lib/redis
redis-cli BGSAVE
# 런타임 설정을 redis.conf에 영구 반영 (재기동 시 원복 방지)
redis-cli CONFIG REWRITE

읽기전용 마운트(Read-only file system)라면 저장 경로를 쓰기 가능한 볼륨으로 옮기는 게 정석입니다.

실무 경험 한 마디: 저는 장애의 8할이 케이스 ②였습니다. 평소엔 조용하다가 트래픽이 늘어 메모리 사용량이 물리 메모리의 절반을 넘는 순간, fork가 거부되며 어느 날 갑자기 터집니다. "어제까지 멀쩡했는데"의 정체가 바로 이겁니다. 신규 Redis 세팅 시 vm.overcommit_memory=1은 반드시 넣고 시작하세요.

컨테이너·k8s 환경이라면

k8s에서는 emptyDir나 PV 용량 초과, initContainer의 파일 권한(fsGroup 미설정)으로 ①·③이 자주 재현됩니다. 이 경우 kubectl exec로 위 진단을 그대로 돌리되, 근본 조치는 PVC 용량 상향과 securityContext.fsGroup 설정으로 갑니다. ElastiCache 등 관리형 Redisstop-writes-on-bgsave-error와 overcommit을 사용자가 만질 수 없으므로, MISCONF보다는 파라미터 그룹·노드 타입·스토리지 지표를 콘솔에서 점검하는 방향이 맞습니다.

5단계: 재발 방지 체크리스트 + stop-writes 원복

근본 원인을 잡았다면, 1단계에서 껐던 안전장치를 반드시 다시 켜야 합니다. 그래야 다음에 저장이 실패할 때 "조용한 데이터 유실" 대신 즉시 알람이 뜹니다.

Bash
redis-cli CONFIG SET stop-writes-on-bgsave-error yes
redis-cli CONFIG REWRITE   # 재기동 후에도 yes 유지
  • rdb_last_bgsave_status:ok 최종 확인
  • vm.overcommit_memory=1 기본 세팅 (/etc/sysctl.conf 영구화)
  • 디스크 사용량 알림 임계 80% 설정 (root와 RDB dir 볼륨 각각)
  • rdb_last_bgsave_status / aof_last_bgrewrite_status 모니터링 헬스체크 등록
  • dir 소유자 redis:redis, 마운트 쓰기 가능 여부 정기 점검
  • stop-writes-on-bgsave-error yes 원복 확인 ← 이 줄을 빼먹으면 다음 장애가 최악이 됩니다

참고: 공식 문서

이 글에서 다루는 동작·설정·에러의 1차 출처는 다음 공식 문서입니다. 버전별 옵션과 정확한 동작은 여기서 확인하세요.

자주 묻는 질문 (FAQ)

Q. stop-writes-on-bgsave-error no로 계속 두면 안 되나요? A. 권장하지 않습니다. 저장 실패를 조용히 넘겨 재기동 시 데이터 유실 위험을 방치하는 것입니다. 임시조치로만 쓰고 원인 해결 후 yes로 되돌리세요. RDB 없이 순수 캐시로만 쓰고 유실을 감수한다면 저장(save "") 자체를 끄는 게 더 명확합니다.

Q. 디스크도 넉넉하고 권한도 정상인데 계속 MISCONF가 떠요. A. 십중팔구 fork 메모리 부족(원인 ②)입니다. journalctl에서 fork: Cannot allocate memory를 확인하고 vm.overcommit_memory=1을 적용하세요. Redis 데이터가 물리 메모리의 절반을 넘길 때 자주 발생합니다.

Q. ElastiCache에서도 이 런북이 통하나요? A. CONFIG SET이나 sysctl에 접근할 수 없어 그대로는 안 됩니다. 관리형에서는 스토리지·메모리 지표와 파라미터 그룹, 노드 스케일업으로 대응하며, MISCONF 자체가 뜨는 경우는 드뭅니다.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 자료 조사와 1차 초안 작성을 담당하고, 사람 편집자가 사실관계·출처·톤과 맥락을 검토한 뒤 발행했습니다. 환경(OS·버전)에 따라 결과가 다를 수 있으니 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.

초안 · AI (Content Reviewer)·검토 · Nodelog 편집자·발행 ·
관련 공식 문서Redis 공식 문서

댓글

첫 번째 댓글을 남겨보세요.