Redis 운용 관리

S_H_H·2025년 3월 7일
0

실전 레디스

목록 보기
3/7
post-thumbnail

데이터 영속성

레디스는 인메모리 DB의 특성상 기본적으로 모든 데이터를 메모리에서 처리하기 때문에 서버가 재시작되면 데이터가 유실될 수 있습니다. 레디스에는 영속성을 위한 설정이 있지만, 영속성 관련 기능을 모두 활성화하는 것은 권장하지 않습니다. 성능과 내구성의 타협점을 찾고 그에 맞춰 설정해야 합니다.

레디스는 스냅숏, AOF, 두 가지 방법으로 데이터의 영속성을 보장합니다. 그리고 두 가지 방법을 조합해서 스냅숏, AOF, 스냅숏 + AOF, 사용하지 않음 총 4 가지 방식으로 영속성 전략을 짤 수 있고, 이 방식을 사용해 백업을 만들 수도 있습니다. 기본적으로 AOF는 비활성화, 스냅숏은 다음과 같은 조건이 기본값으로 설정되어 있습니다.

  • 1시간 내에 최소 하나 이상의 키가 변경되는 경우
  • 5분 내에 최소 100개 이상의 키가 변경되는 경우
  • 1분 내에 최소 10,000개 이상의 키가 변경되는 경우

스냅숏은 특정 시점의 DB 내용을 RDB 형식의 파일로 저장하며, 복원하는 형태로 데이터를 재사용할 수 있습니다.
AOF는 레디스에 쓰기 작업을 수행하면 이 파일에 데이터를 차례로 기록하는 형식으로 진행됩니다. 파일을 기반으로 레디스가 시작할 때 로그 파일 데이터를 재생하는 방식으로 복원합니다.

스냅숏

스냅숏은 특정 시점의 DB 내용을 RDB 형식의 파일로 저장하며, 복원하는 형태로 데이터를 재사용할 수 있습니다. 자동 혹은 수동으로 생성할 수 있습니다.

SAVE 명령어는 동기 방식으로 다른 요청을 차단하므로 실제 운영환경에서는 사용을 권장하지 않습니다.
BGSAVE 명령어는 다음 순서로 처리합니다.

  • 처리순서

    • 요청 처리 중인 프로세스에서 RDB 파일을 덤프하기 위한 자식 프로세스 fork
    • 자식 프로세스는 데이터 세트 전체를 임시 RDB 파일로 덤프
    • 덤프가 완료되면 설정한 RDB 파일 명으로 수정
  • 고려사항

    • 스냅숏을 사용하기 위한 메모리가 충분하지 확인
    • 문제없이 레플리카에서 스냅숏을 가져올 수 있는지 확인
    • 서비스에 지장이 없는 시간에 스냅숏을 생성하는지 확인

    백그라운드에서 스냅숏 저장 처리에 실패하면 레디스는 기본적으로 쓰기 작업 요청을 수락하지 않습니다.
    데이터 손실 가능성이 있음으로 영속성을 위해 문제를 관리자에게 알리려고 하기 때문입니다.
    stop-writes-on-bgsave-error로 설정할 수 있습니다.

AOF

AOF는 거의 실시간 백업처럼 작성 중인 파일 끝에 계속 추가하여 기록하기 떄문에 내구성이 높다는 특징이 있습니다. 하지만 파일의 끝에 계속 추가하여 기록하는 특성 때문에 AOF 파일은 각 스냅숏으로 생성한 RDB 파일보다 크기가 커지는 경향이 있습니다. 재시작 시 AOF 파일의 명령어 내용을 다시 재생하여 메모리에 적재하는 형식이므로 파일 크기에 따라 재시작 시간이 길어질 수 있습니다.

요청받은 명령어를 파일에 기록하기 위해서 우선 버퍼에 유지하는데 이 버퍼를 AOF 버퍼라고 합니다. 이후 레디스 ro OS가 버퍼에 있는 데이터를 플러시하여 디스크 내의 파일에 영구적으로 저장합니다.

AOF는 자동 생성만 할 수 있으며, 자동 생성 시점을 설정할 수 있습니다.

  • always
    쓰기작업 마다 데이터를 버퍼에서 디스크로 플러시
  • everysec
    pthread에서 백그라운드 스레드를 생성하여 매초마다 버퍼에서 디스크로 데이터를 플러시
  • no
    OS가 설정한 적절한 시점에 실행

파일 크기가 커지면 자동으로 AOF 재작성 기능을 통해 BGREWRITEOF 명령어 처리가 수행 됩니다. 이미 삭제되거나 만료된 키, 같은 키에 여러 작업을 하는 경우 등을 통합하여 파일 크기를 줄이는 작업이 수행됩니다. AOF 재작성 처리 흐름은 다음과 같습니다.

  • 요청 처리 중인 프로세스에서 AOF를 재작성하기 위해 프로세스를 포크하여 생성
  • 자식 프로세스는 새로운 AOF 파일을 생성한 후 재작성 결과를 저장
  • 자식 프로세스가 새로운 AOF 파일의 재작성을 완료하면 부포 프로세스에 신호를 보냄
  • 신호를 받은 부모 프로세스는 포그 이후의 쓰기 작접 내용을 AOF 재작성 버퍼에 저장해두었다가 이를 자식 프로세스에 전송
  • 오래된 AOF 파일을 새 AOF 파일로 교체

멀티파트 AOF는 기존 AOF 메모리 소비나 디스크의 입출력이 많아지는 문제를 해결하기 위해 파일을 분할하여 처리합니다.

데이터 삭제 패턴

레디스는 데이터 영속화 기능이 있지만, 데이터가 메모리에만 저장된 상태에서는 예기치 않게 데이터가 삭제될 가능성이 있습니다. 이 현상이 장애 때문인지 아니면 의도하지 않은 조작 떄문인지 원인을 파악하고 있어야 합니다.

  • 엔진 재시작
  • 레디스 서버 전체 장애
  • 명령어 실행
    • DEL/HDEL/XDEL 명령어
    • FLUSHALL/FLUSHDB 명령어
    • UNLINK 명령어
  • TTL 만료
    • EXPIRE/EXPIREAT/PEXPRIE/PEXPIREAT 명령어
    • SET 명령어의 EX 옵션
  • 강제 제거
  • 비동기 레플리케이션
  • 레디스 클러스터의 네트워크 단절
  • 기타
    • 키 이름 재설정
    • 잘못된 DB 선택
    • 데이터가 저장되지 않는 경우

캐시 서버로서 레디스 아키텍처

실제 환경에서 다양한 상황이 발생할 수 있지만, 읽기 작업과 쓰기 작업 관점으로 분류하여 설명합니다.

읽기 관점 아키텍처

읽기 관점은 2 가지 패턴이 있습니다.

지연 로딩 패턴

지연 로딩 패턴은 데이터를 읽어오는 관점에서 접근한 아키텍처 입니다. 원본 데이터는 DB에 저장하고 레디스는 앞에 위치하여 흐름을 처리합니다

  • APP은 레디스에 데이터 요청

  • 레디스에 존재하는지, 유효 기간 내인지에 따라 처리 내용을 분기

    • 레디스에 존재하고 유효 기간 내에 있는 경우인 경우 데이터 반환
    • 레디스에 존재하지 않거나, 존재하더라도 유효 기간이 지난 경우
      • DB에서 데이터를 가져옴
      • 가져온 데이터를 레디스 캐시 갱신
  • 장점

    • 레디스 캐시 노드 장애 시 다운타임을 줄일 수 있으며, 지연 시간의 영향을 최소화
    • 요청된 데이터만 캐시에 저장하므로, 사용하지 않는 데이터를 캐시로 사용하는 공간이 적다
  • 단점

    • 가져온 데이터가 오래되었을 수도 있다.
    • 캐시 미스 시 오베헤드가 크다.

Read-Through 패턴

Read-Through 패턴은 지연 읽기 패턴의 변형과 같은 아키텍처 입니다. 지연 읽기과 가장 큰 차이점은 DB에서 데이터를 읽어오는 작업을 APP에서 직접 처리할 필요가 없다는 점. 대신에 라이브러리 등을 사용하여 DB에서 레디스로 데이터를 읽어오는 과정을 처리해야 합니다.

레디스의 내장 기능으로는 제공되지 않으므로, 서드파티 소프트웨어나 모듈 등을 통해 기능이 가능한지 확인할 필요가 있습니다.

쓰기 관점 아키텍처

Write-Through 패턴

Write-Through 패턴은 데이터 쓰기 작업을 할 때의 관점에서 접근한 아키텍처입니다. 이 패턴에서 APP은 다음과 같은 흐름으로 처리합니다.
1. APP은 DB에 데이터를 저장합니다.
2. APP은 1번과 같은 데이터를 레디스 서버에도 저장합니다.

  • 장점
    • 레디스 서버 내의 캐시 데이터가 항상 최신 데이터
    • 읽기 작업 시 오버헤드가 적다
  • 단점
    • 사용하지 않는 캐시 데이터 생성 가능성이 있다
    • 쓰기 작업 시 DBB와 캐시에 모두 쓰기를 해야 하므로 오버헤드가 크다.

Write-Back 패턴

Write-Back 패턴은 캐시에 저장 후, 일정 시간이 지연되면 DB를 비동기 방식으로 주기적인 업데이트를 하는 방식입니다. DB가 RDBMS인 경우 데이터를 영구적으로 저장하는 시점에 정규화하여 테이블에 저장합니다.

오버헤드를 줄일 수 있지만, 데이터 손실 위험이 있기 때문에 특성을 고려하여 도입해야 합니다.

  • 장점
    • 레디스 서버 내의 캐시 데이터가 항상 최신 상태를 유지
    • 쓰기 작업을 빠르게 처리
  • 단점
    • 데이터 손실 위험이 높다

Write-Around 패턴

Write-Around 패턴은 데이터를 직접 DB에 저장하는 방식입니다. AWS DMS or CDC 기능을 사용하여 DB에서 레디스로 변경 내용을 레플리케이션하고, 레디스에서 직접 데이터를 읽어올 수도 있습니다.

설정 파일 redis.conf

레디스 서버는 설정 파일을 통해 Customize할 수 있고, 각종 기능 활성화/비활성화 및 튜닝에 주로 사용됩니다. 설정 파일을 작설할 때는 기본적으로 제공되는 redis.conf를 편집하거나 이를 복사하여 편집하거나 또는 처음부터 직접 서정을 작성할 수 있습니다. 사용자 정의한 파일을 배치할 위치는 상관없으며, 파일 이름도 원하는 대로 지정하면 됩니다. redis-server <경로>를 실행하여 레디스 서버를 실행하면 설정이 적용됩니다.

이미 실행 중인 레디스 서버의 설정 파일이 기본값이 아닌지 확인할려면 INFO Server 명령어의 config_file을 확인하면 됩니다.

설정 변경은 CONFIG SET 명령어나 redis-server 명령어 옵션으로 전달하는 방법도 있습니다. 이 방법은 테스트 목적으로 간단한 동작을 확인할 때 사용하는 것은 괜찮지만, 실제 운영 환경에서 이 방법으로 모든 것을 관리하는 것은 추천하지 않습니다.

Config 옵션은 redis-config Docs 에서 확인해보자 redis-config-file-example

네트워크, TLS, 프로세스, 스냅숏, AOF, 레플리케이션, 클러스터, ACL 기능, 클라이언트 추적, 보안, 클라이언트, 메모리, 동적 단편화, 타이머, Laze free, 멀티 스레드, 커널 OOM, 슬로우 로그, 지연 모니터, 지연 트래킹, 알림, 내부 인코딩, 셧다운 등등 설정 항목이 있다.

보안

레디스는 신뢰할 수 있는 환경에서만 접근할 수 있도록 설계되었습니다. 신뢰할 수 없는 환경에서 레디스에 접근할 때는 ACL기능을 사용하거나 사용자 입력을 검증하는 중간 계층을 추가하는 방식을 권장합니다.

보안 설정

네트워크 보안

bind 설정을 통해 IP 주소를 지정할 수 있습니다.
데이터 전송 시 암호화는 OSS 버전의 레디스에서는 6.0 이상부터 사용할 수 있습니다. TLS 기능을 사용할려면 클라이언트 측에서도 이 기능을지원해야 하므로 사용하는 클라이언트에 TLS 관련 옵션이 있는 지 확인해야 합니다.
또한 기본적으로 보호 모드가 활성화되어 있습니다. 이 모드가 활성화되어 있을 때는 루프백 인터페이스와 유닉스 도메인 소켓에서만 접근할 수 있습니다.

명령어 제한

외부로부터 명령어 실행을 방지하기 위해 특정 명령어를 비활성화할 수 있습니다.

인증

레디스에서는 requirepass 명령어를 통해 설정 파일에 패스워드를 설정함으로써 인증할 수 있는 기능을 제공합니다.
6.0 이상에서는 ACL 기능을 통해 인증 패스워드를 설정할 수 있으며, 실행할 명령어와 접근 가능한 키 연결을 세밀하게 제한할 수 있게되었습니다.

외부 클라이언트 공격

외부 클라이언트가 시스템 취약점을 노리고 만든 특별한 데이터로 공격할 수도 있습니다. 이를 방지하기 위해 실핼할 때마다 의사 난수 함수의 시드를 사용하는 방법이 있습니다.

코드 보안

CONFIG 명령어를 통해 RDB 파일 디렉터리 등의 경로를 변경할 수 있으므로 이것이 보안 문제로 이어질 수 있습니다. 레디스 운영에는 기본적으로 루트 권한이 필요하지 않습니다. 이때는 불필요한 권한이 없는 레디스 전용 사용자를 생성하여 이 사용자의 권한으로 운영함으로써 대처할 수 있습니다.

ACL 기능

레디스 6.0부터 도입된 ACL 기능을 통해 레디스에서도 접근 제한 기능을 구현할 수 있게 되었습니다. 이는 보안 측면에서 매우 중요한 기능을 하고 있습니다.

ACL의 주요 케이스입니다.

  • 신뢰할 수 없는 클라이언트에게 접근을 허용하지 않고, 신뢰할 수 있는 클라이언트에게만 최소한의 접근 권한을 부여
    • 특정 목적으로 연결된 클라이언트가 사용할 수 있는 명령어나 키만을 지정하여 접근을 허용
  • 사용자의 실수를 예방
    • S/W 버그로 인해 의도하지 않은 키 조작을 방지
  • 관리형 서비스
    • 다양한 클라우드 제공 업체나 관리형 서비스로서 레디스가 제공되는 경우, 제공 업체 측에서 일부 관리하고 있어 사용자 측에서는 일부 명령어나 하위 명렁어가 제한될 수 있습니다.

레디스의ACL 기능은 실행 가능한 명령어, 접근 가능한 Pub/Sub 채널 이름, 접근 가능한 키 범위 등 크게 3 가지 관점에서 접근을 제어합니다.
레디스 7.0 이후에는 기능이 개선되었습니다. 버전 2에는 크게 다음 기능이 추가 되었습니다.

  • 한 사용자에게 여러 독립적인 규칙을 지정할 수 있는 선택자 기능
  • 읽기 전용 혹은 쓰기 전용을 지정할 수 있는 키 허용 기능

ACL 기능을 통한 제어 내용

ACL LIST 명령어를 실행하여 레디스 서버 내의 사용 가능한 사용자 및 각 접근 제어 상세 내용을 확인합니다. 기본 상태는 default라는 사용자 이름으로 패스워드 인증 없이 모든 키에 모든 명령어를 실행할 수 있는 상태입니다. 이 default 사용자는 ACL 기능 생기기 이전 레디스 버전과 호환되기 위해 제공됩니다.

각 사용자에 설정된 ACL 규칙은 다음과 같은 포맷으로 구성되어 있습니다.

> ACL LIST
> "user default on nopass ~* &* +@all"

user USERNAME <on/off> [sanitize-payload/skip-sanitize-payload] PASSWORD ~key_PATTERN &PUBSUB_PATTERN <+/->COMMAND_PATTERN

각 항목은 어떤 순서로든 지정할 수 있지만, 실제 사용자에게 적용되는 규칙은 왼쪽에서 오른쪽 순으로 해석됩니다. 규칙의 순서가 중요하다는 것을 기억하기 바랍니다.

  • USERNAME 사용자
  • PASSWORD 사용자 패스워드
    • SHA256으로 해싱한 패스워드를 추가 or 제거
    • 패스워드 앞에 '#' 추가 and '!' 제거
  • KEY_PATTERN 접근을 허용할 키의 범위를 지정
    • sess: 으로 시작하는 키에 대한 접근을 허용할려면 ~sess:* 으로 작성
  • &PUBSUB_PATTERN Pub/Sub 기능에서 사용자가 접근할 수 있는 채널의 범위를 지정
  • <+/->COMMAND_PATTERN 접근을 허용할 명렁어를 지정
    • GET 명령어를 허용하려면 +get 으로 표시, 취소는 -get으로 표시
    • 특정 명령어의 하위 명령어만 추가하려면 '|' 구분자 사용 +client|setname
    • ACL CAT 명령어로 사용 가능한 카테고리 확인
    • ACL CAT <name> 으로 포함된 명령어 확인

ACL 기능 설정 방법

  • ACL SETUSER 명령어 사용
  • 설정 파일에 user 지정
  • 설정 파일에 aclfile 통해 acl.conf와 같은 외부 파일을 지정합니다.

자세한 ACL 기능 관련 명령어는 redis-acl 페이지에서 확인하자

벤치 마크

레디스 처리 속도는 CPU, 네트워크 대역폭, 데이터 크기, 캐시 히트율, RTT 등 다양한 요인의 영향을 받습니다. app 특성을 고려하여 처리 속도를 확인하는 것이 중요합니다.

레디스 클라이언트 수, 데이터 크기, 사용하는 명령어 등을 변경하며 상황을 설정할 수 있습니다. 또한 파이프라인을 사용할 때의 성능 향상 정도도 확인할 수 있습니다. 이 결과를 바탕으로 레디스 서버의 다양한 메트릭의 경향과 문제 발생 여부를 검토할 수 있습니다.

redis-benchmark 명령어에는 다양한 옵션이 있으며 --help 옵션을 사용하면 실행 방법과 예시를 포함하여 상세 내용을 확인할 수 있습니다.

벤치마크를 실행할 때 몇 가지를 주의해야 합니다. 벤치마크는 어디까지나 가상적인 상황을 재현하여 테스트하는 것이기 때문에 실제로 어플리케이션을 배포하고 트래픽을 받을 때는 벤치마크로 커버되지 않는 상황에 직면할 수 있습니다. 따라서 벤치마크는 대략적인 참고용으로만 사용하고, 가능 한 실제 운영환경과 유사한 환경에서 테스틑하는 것이 좋습니다.

멀티 스레드 처리

레디스는 주로 싱글 스레드로 요청을 처리하지만 부분적으로 멀티 스레드로 처리합니다.

공식적으로는 스레드화된 I/O는 CPU를 많이 소모하기 때문에 성능 문제가 발생할 경우에만 멀티 스레드로 처리할 것을 권장하고 있으며, 기본적으로 비활성화되어 있습니다. 또한 4코어 이상의 기계에서만 기능을 사용하고, 여분으로 최소 1 개의 코어를 남기고 스레드를 사용하는 설정을 제안하고 있습니다.

클라우드나 관리 서비스를 사용하는 경우에는 멀티 스레드 기능을 사용하지 않고, 레디스 6.0 이전부터 사용 가능한 독자적인 멀티 스레드 처리가 적용될 수 있습니다. TLS 환경에서도 멀티 스레드 처리를 사용할 수 있는 경우도 있으므로, 사용하는 서비스의 문서 등에 해당 기능이 없는지 확인하는 것을 추천합니다.

profile
LEVEL UP

0개의 댓글