Redis 복제 및 장애 조치: 자체 인스턴스 제공

Tier: Free, Premium, Ultimate Offering: Self-managed

GitLab을 클라우드 공급자에서 호스팅하는 경우, Redis를 위한 관리형 서비스를 선택적으로 사용할 수 있습니다. 예를 들어, AWS는 Redis를 실행하는 ElastiCache를 제공합니다.

또는 Linux 패키지와 별도로 자신의 Redis 인스턴스를 관리하도록 선택할 수 있습니다.

요구 사항

다음은 자신의 Redis 인스턴스를 제공하기 위한 요구 사항입니다:

  • 요구 사항 페이지에서 필요한 최소 Redis 버전을 찾으세요.
  • 스탠드얼론 Redis 또는 Sentinel을 통한 Redis 고가용성이 지원됩니다. Redis 클러스터는 지원되지 않습니다.
  • AWS ElastiCache와 같은 클라우드 공급자의 관리형 Redis는 잘 작동합니다. 이러한 서비스가 고가용성을 지원하는 경우, 이는 Redis 클러스터 유형이 아니어야 합니다.

Redis 노드의 IP 주소 또는 호스트 이름, 포트 및 비밀번호(필요한 경우)를 기록해두세요.

클라우드 공급자에서 관리형 서비스로서의 Redis

  1. 요구 사항에 따라 Redis를 설정합니다.
  2. /etc/gitlab/gitlab.rb 파일에 대한 외부 Redis 서비스의 적절한 연결 세부 정보를 사용하여 GitLab 애플리케이션 서버를 구성합니다:

    단일 Redis 인스턴스를 사용하는 경우:

    redis['enable'] = false  
    
    gitlab_rails['redis_host'] = '<redis_instance_url>'  
    gitlab_rails['redis_port'] = '<redis_instance_port>'  
    
    # Redis 노드에서 Redis 인증이 구성된 경우 필요합니다.  
    gitlab_rails['redis_password'] = '<redis_password>'  
    
    # 인스턴스가 Redis SSL을 사용하는 경우 true로 설정합니다.  
    gitlab_rails['redis_ssl'] = true  
    

    별도의 Redis 캐시 및 지속적인 인스턴스를 사용하는 경우:

    redis['enable'] = false  
    
    # 기본 Redis 연결  
    gitlab_rails['redis_host'] = '<redis_persistent_instance_url>'  
    gitlab_rails['redis_port'] = '<redis_persistent_instance_port>'  
    gitlab_rails['redis_password'] = '<redis_persistent_password>'  
    
    # 인스턴스가 Redis SSL을 사용하는 경우 true로 설정합니다.  
    gitlab_rails['redis_ssl'] = true  
    
    # Redis 캐시 연결  
    # SSL을 사용하는 경우 `redis://`를 `rediss://`로 교체합니다.  
    gitlab_rails['redis_cache_instance'] = 'redis://:<redis_cache_password>@<redis_cache_instance_url>:<redis_cache_instance_port>'  
    
  3. 변경 사항이 적용되도록 재구성합니다:

    sudo gitlab-ctl reconfigure  
    

퇴출 정책 설정

단일 Redis 인스턴스를 실행할 경우, 퇴출 정책을 noeviction으로 설정해야 합니다.

별도의 Redis 캐시 및 지속적인 인스턴스를 실행하는 경우, 캐시는 allkeys-lru로 설정된 최소 최근 사용 캐시 (LRU)로 구성되어야 하며, 지속적인 인스턴스는 noeviction으로 설정되어야 합니다.

이를 구성하는 것은 클라우드 공급자 또는 서비스에 따라 다르지만, 일반적으로 다음 설정 및 값이 캐시를 구성합니다:

  • maxmemory-policy = allkeys-lru
  • maxmemory-samples = 5

자체 Redis 서버를 통한 Redis 복제 및 장애 조치

이는 Linux 패키지와 함께 제공되는 번들 Redis가 아닌 Redis를 스스로 설치한 경우 확장 가능한 Redis 설정을 구성하기 위한 문서입니다. Linux 패키지를 사용하는 것이 특히 GitLab에 최적화되어 있기 때문에 강력히 권장하며, Redis를 최신 지원 버전으로 업그레이드하는 것도 저희가 처리합니다.

또한, 구성 파일 문서에 설명된 고급 Redis 설정에 따라 /home/git/gitlab/config/resque.yml의 모든 참조를 재정의하도록 선택할 수 있습니다.

Linux 패키지 Redis HA의 복제 및 장애 조치 문서를 읽는 것의 중요성을 강조하고 싶습니다. 이 문서는 Redis 구성에 대한 귀중한 정보를 제공합니다. 이 가이드를 진행하기 전에 꼭 읽어보세요.

새 Redis 인스턴스를 설정하기 전에 다음 요구 사항을 확인하십시오:

  • 이 가이드의 모든 Redis 서버는 소켓 대신 TCP 연결을 사용하도록 구성되어야 합니다. Redis를 TCP 연결을 사용하도록 구성하려면 Redis 구성 파일에서 bindport를 모두 정의해야 합니다. 모든 인터페이스(0.0.0.0)에 바인딩하거나 원하는 인터페이스의 IP(예: 내부 네트워크에서)를 지정할 수 있습니다.
  • Redis 3.2부터 외부 연결을 수신하기 위해 비밀번호(requirepass)를 정의해야 합니다.
  • Redis와 Sentinel을 사용하는 경우, 동일한 인스턴스 내에서 복제 비밀번호 정의(masterauth)를 위한 동일한 비밀번호를 정의해야 합니다.

또한, Linux 패키지의 Redis 복제 및 장애 조치에 설명된 요구 사항을 읽어보세요.

1단계. 기본 Redis 인스턴스 구성

Redis 기본 인스턴스 IP가 10.0.0.1이라고 가정합니다:

  1. Redis 설치하기.
  2. /etc/redis/redis.conf를 수정합니다:

    ## 다른 머신이 접근할 수 있는 로컬 IP로 지정된 `bind` 주소를 정의합니다.
    ## 외부에서 접근 가능한 IP에 바인딩해야 하는 경우, 
    ## 무단 접근을 방지하기 위해 추가 방화벽 규칙을 추가해야 합니다:
    bind 10.0.0.1
    
    ## 다른 머신이 연결할 수 있도록 Redis가 TCP에서 수신하도록 강제하기 위한 `port`를 정의합니다
    ## (기본 포트는 `6379`입니다).
    port 6379
    
    ## 비밀번호 인증 설정 (모든 노드에서 동일한 비밀번호 사용).
    ## Redis를 Sentinel과 함께 사용하도록 설정할 때, 
    ## 비밀번호는 `requirepass`와 `masterauth`에 대해 동일하게 정의해야 합니다.
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    
  3. 변경 사항을 적용하기 위해 Redis 서비스를 재시작합니다.

2단계. 복제 Redis 인스턴스 구성

Redis 복제 인스턴스 IP가 10.0.0.2라고 가정합니다:

  1. Redis 설치하기.
  2. /etc/redis/redis.conf를 수정합니다:

    ## 다른 머신이 접근할 수 있는 로컬 IP로 지정된 `bind` 주소를 정의합니다.
    ## 외부에서 접근 가능한 IP에 바인딩해야 하는 경우, 
    ## 무단 접근을 방지하기 위해 추가 방화벽 규칙을 추가해야 합니다:
    bind 10.0.0.2
    
    ## 다른 머신이 연결할 수 있도록 Redis가 TCP에서 수신하도록 강제하기 위한 `port`를 정의합니다
    ## (기본 포트는 `6379`입니다).
    port 6379
    
    ## 비밀번호 인증 설정 (모든 노드에서 동일한 비밀번호 사용).
    ## Redis를 Sentinel과 함께 사용하도록 설정할 때, 
    ## 비밀번호는 `requirepass`와 `masterauth`에 대해 동일하게 정의해야 합니다.
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    
    ## Redis 기본 인스턴스를 가리키는 `replicaof`를 정의합니다.
    replicaof 10.0.0.1 6379
    
  3. 변경 사항을 적용하기 위해 Redis 서비스를 재시작합니다.
  4. 모든 다른 복제 노드에 대해 이 단계를 반복합니다.

3단계. Redis Sentinel 인스턴스 구성

Sentinel은 특수한 유형의 Redis 서버입니다. 이는 redis.conf에서 정의할 수 있는 대부분의 기본 구성 옵션을 상속하며, sentinel 접두어로 시작하는 특정 옵션이 있습니다.

Redis 기본 인스턴스와 동일한 인스턴스에 IP 10.0.0.1로 Redis Sentinel이 설치되어 있다고 가정합니다 (일부 설정은 기본과 겹칠 수 있습니다):

  1. Redis Sentinel 설치하기.
  2. /etc/redis/sentinel.conf를 수정합니다:

    ## 다른 머신이 접근할 수 있는 로컬 IP로 지정된 `bind` 주소를 정의합니다.
    ## 외부에서 접근 가능한 IP에 바인딩해야 하는 경우, 
    ## 무단 접근을 방지하기 위해 추가 방화벽 규칙을 추가해야 합니다:
    bind 10.0.0.1
    
    ## 다른 머신이 연결할 수 있도록 Sentinel이 TCP에서 수신하도록 강제하기 위한 `port`를 정의합니다
    ## (기본 포트는 `6379`입니다).
    port 26379
    
    ## 비밀번호 인증 설정 (모든 노드에서 동일한 비밀번호 사용).
    ## Redis를 Sentinel과 함께 사용하도록 설정할 때, 
    ## 비밀번호는 `requirepass`와 `masterauth`에 대해 동일하게 정의해야 합니다.
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    
    ## Redis 기본 및 복제 인스턴스에 대해 동일한 공유 비밀번호를 정의하는 `sentinel auth-pass`를 정의합니다.
    sentinel auth-pass gitlab-redis redis-password-goes-here
    
    ## Redis 기본 노드의 IP 및 포트와 failover를 시작하는 데 필요한 쿼럼을 정의하는 `sentinel monitor`를 정의합니다.
    sentinel monitor gitlab-redis 10.0.0.1 6379 2
    
    ## 응답하지 않는 서버가 다운으로 간주되는 `ms` 단위의 시간으로 `sentinel down-after-milliseconds`를 정의합니다.
    sentinel down-after-milliseconds gitlab-redis 10000
    
    ## `ms` 단위의 `sentinel failover_timeout` 값을 정의합니다. 이는 여러 의미를 갖습니다:
    ##
    ## * 특정 Sentinel이 동일한 기본 노드에 대해 이전 failover를 이미 시도한 후 
    ##   failover를 재시작하는 데 필요한 시간은 두 배의 failover timeout입니다.
    ##
    ## * Sentinel의 현재 구성에 따라 잘못된 기본 노드에 복제 중인 복제기가 
    ##   올바른 기본 노드와 복제하도록 강제되는 데 필요한 시간은 
    ##   정확히 failover timeout입니다 (Sentinel이 잘못된 구성을 감지한 시점부터 계산).
    ##
    ## * 이미 진행 중인 failover를 취소하는 데 필요한 최대 시간으로, 
    ##   해당 실패가 실제로 구성 변경을 초래하지 않은 경우 (REPLICAOF NO ONE가 
    ##   승격된 복제기에 의해 아직 승인되지 않음).
    ##
    ## * 진행 중인 failover가 새로운 기본의 복제로 모든 복제기가 재구성되기를 기다리는 최대 시간입니다. 
    ##   그러나 이 시간 이후에도 복제기는 어쨌든 Sentinels에 의해 재구성되지만, 
    ##   지정된 정확한 병렬 동기화 진행이 아닙니다.
    sentinel failover_timeout 30000
    
  3. 변경 사항을 적용하기 위해 Redis 서비스를 재시작합니다.
  4. 모든 다른 Sentinel 노드에 대해 이 단계를 반복합니다.

4단계. GitLab 애플리케이션 구성

새로운 설치 또는 기존 설치에서 Sentinel 지원을 언제든지 활성화하거나 비활성화할 수 있습니다. GitLab 애플리케이션의 관점에서, 필요한 것은 Sentinel 노드에 대한 올바른 자격 증명입니다.

모든 Sentinel 노드의 목록이 필요하지는 않지만, 장애가 발생할 경우, 나열된 노드 중 적어도 하나에 접근해야 합니다.

다음 단계는 GitLab 애플리케이션 서버에서 수행해야 하며, 이상적으로는 Redis 또는 Sentinel이 동일한 머신에 없어야 합니다:

  1. /home/git/gitlab/config/resque.yml를 수정하여 resque.yml.example 예제를 따르고, 올바른 서버 자격 증명을 가리키도록 Sentinel 라인의 주석을 제거합니다:

    # resque.yaml
    production:
      url: redis://:redi-password-goes-here@gitlab-redis/
      sentinels:
        -
          host: 10.0.0.1
          port: 26379  # Redis 포트가 아닌 Sentinel을 가리킴
        -
          host: 10.0.0.2
          port: 26379  # Redis 포트가 아닌 Sentinel을 가리킴
        -
          host: 10.0.0.3
          port: 26379  # Redis 포트가 아닌 Sentinel을 가리킴
    
  2. GitLab을 재시작하여 변경 사항을 적용합니다.

1개의 주 서버, 2개의 복제본 및 3개의 Sentinel이 있는 최소 구성 예시

이 예에서는 모든 서버가 10.0.0.x 범위의 IP를 가진 내부 네트워크 인터페이스를 가지고 있으며, 이 IP를 사용하여 서로 연결할 수 있다고 가정합니다.

실제 사용에서는 다른 머신으로부터의 무단 접근을 방지하기 위해 방화벽 규칙을 설정하고, 외부(인터넷)로부터의 트래픽을 차단합니다.

이 예시에서는 Sentinel 1Redis Primary와 동일한 머신에 구성되어 있고, Sentinel 2Replica 1과 동일한 머신에, Sentinel 3Replica 2와 동일한 머신에 구성되어 있습니다.

머신과 할당된 IP 목록 및 설명은 다음과 같습니다:

  • 10.0.0.1: Redis Primary + Sentinel 1
  • 10.0.0.2: Redis Replica 1 + Sentinel 2
  • 10.0.0.3: Redis Replica 2 + Sentinel 3
  • 10.0.0.4: GitLab 애플리케이션

초기 구성이 완료된 후, Sentinel 노드에 의해 장애 조치가 시작되면 Redis 노드는 재구성되고 Primary는 한 노드에서 다른 노드로 영구적으로 변경됩니다( redis.conf에 포함됨).

동일한 상황이 초기 실행 후 sentinel.conf에서도 발생하며, 새로운 Sentinel 노드가 Primary를 감시하거나 장애 조치가 다른 Primary 노드를 승격시킵니다.

Redis Primary 및 Sentinel 1에 대한 구성 예시

  1. /etc/redis/redis.conf에서:

    bind 10.0.0.1
    port 6379
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    
  2. /etc/redis/sentinel.conf에서:

    bind 10.0.0.1
    port 26379
    sentinel auth-pass gitlab-redis redis-password-goes-here
    sentinel monitor gitlab-redis 10.0.0.1 6379 2
    sentinel down-after-milliseconds gitlab-redis 10000
    sentinel failover_timeout 30000
    
  3. 변경 사항을 적용하기 위해 Redis 서비스를 재시작합니다.

Redis 복제본 1 및 Sentinel 2에 대한 예시 구성

  1. /etc/redis/redis.conf에서:

    bind 10.0.0.2
    port 6379
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    replicaof 10.0.0.1 6379
    
  2. /etc/redis/sentinel.conf에서:

    bind 10.0.0.2
    port 26379
    sentinel auth-pass gitlab-redis redis-password-goes-here
    sentinel monitor gitlab-redis 10.0.0.1 6379 2
    sentinel down-after-milliseconds gitlab-redis 10000
    sentinel failover_timeout 30000
    
  3. 변경 사항이 적용되도록 Redis 서비스를 재시작합니다.

Redis 복제본 2 및 Sentinel 3에 대한 예시 구성

  1. /etc/redis/redis.conf에서:

    bind 10.0.0.3
    port 6379
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
    replicaof 10.0.0.1 6379
    
  2. /etc/redis/sentinel.conf에서:

    bind 10.0.0.3
    port 26379
    sentinel auth-pass gitlab-redis redis-password-goes-here
    sentinel monitor gitlab-redis 10.0.0.1 6379 2
    sentinel down-after-milliseconds gitlab-redis 10000
    sentinel failover_timeout 30000
    
  3. 변경 사항이 적용되도록 Redis 서비스를 재시작합니다.

GitLab 애플리케이션의 예시 구성

  1. /home/git/gitlab/config/resque.yml를 편집합니다:

    production:
      url: redis://:redis-password-goes-here@gitlab-redis/
      sentinels:
        -
          host: 10.0.0.1
          port: 26379  # sentinel에 포인트, redis 포트가 아님
        -
          host: 10.0.0.2
          port: 26379  # sentinel에 포인트, redis 포트가 아님
        -
          host: 10.0.0.3
          port: 26379  # sentinel에 포인트, redis 포트가 아님
    
  2. 변경 사항이 적용되도록 GitLab 재시작합니다.

문제 해결

Redis 문제 해결 가이드를 참조하세요.