Redisのレプリケーションと独自のインスタンスによるフェイルオーバー

GitLab をクラウドプロバイダーでホストしている場合は、オプションで Redis のマネージドサービスを使うことができます。例えば、AWSはRedisを実行するElastiCacheを提供しています。

あるいは、Linuxパッケージとは別に自分のRedisインスタンスを管理することもできます。

要件

独自のRedisインスタンスを提供するための要件は以下のとおりです:

  • 要件ページで必要な Redis の最小バージョンを確認してください。
  • スタンドアロンRedisまたはSentinel付きRedis高可用性がサポートされています。Redisクラスタはサポートされていません。
  • AWS ElastiCacheなどのクラウドプロバイダのマネージドRedisは問題なく動作します。これらのサービスが高可用性をサポートしている場合は、Redisクラスタタイプでないことを確認してください。

RedisノードのIPアドレスまたはホスト名、ポート、パスワード(必要な場合)をメモします。

クラウドプロバイダーのマネージドサービスとしてのRedis

  1. 要件に従ってRedisをセットアップします。
  2. GitLabアプリケーションサーバーを設定し、/etc/gitlab/gitlab.rb ファイルで外部Redisサービスの適切な接続詳細を設定します:

    redis['enable'] = false
       
    gitlab_rails['redis_host'] = 'redis.example.com'
    gitlab_rails['redis_port'] = 6379
       
    # Required if Redis authentication is configured on the Redis node
    gitlab_rails['redis_password'] = 'Redis Password'
    
  3. 変更を有効にするために再設定します:

    sudo gitlab-ctl reconfigure
    

独自のRedisサーバによるRedisのレプリケーションとフェイルオーバー

LinuxパッケージはGitLab専用に最適化されており、Redisを最新のサポートバージョンにアップグレードしてくれるので、Linuxパッケージを使うことを強くお勧めします。

また、設定ファイルのドキュメントで説明されている高度なRedis設定に従って、/home/git/gitlab/config/resque.yml

Linux パッケージ Redis HA のレプリケーションとフェイルオーバーのドキュメントを読むことの重要性はいくら強調しても足りません。このガイドを進める前にお読みください。

新しいRedisインスタンスのセットアップを進める前に、いくつかの要件を示します:

  • このガイドのすべてのRedisサーバーは、ソケットではなくTCP接続を使用するように設定する必要があります。TCP接続を使用するようにRedisを設定するには、Redis設定ファイルでbindport の両方を定義する必要があります。すべてのインターフェース(0.0.0.0)にバインドするか、必要なインターフェース(内部ネットワークからのインターフェースなど)のIPを指定します。
  • Redis 3.2以降では、外部接続を受信するためのパスワードを定義する必要があります (requirepass)。
  • SentinelでRedisを使用している場合は、同じインスタンスでレプリカのパスワード定義(masterauth)にも同じパスワードを定義する必要があります。

さらに、LinuxパッケージでのRedisレプリケーションとフェイルオーバーで説明されている前提条件をお読みください。

ステップ 1.プライマリRedisインスタンスの設定

Redisのプライマリ・インスタンスIPが10.0.0.1 であると仮定します:

  1. Redisをインストールします。
  2. /etc/redis/redis.conf を編集します:

    ## Define a `bind` address pointing to a local IP that your other machines
    ## can reach you. If you really need to bind to an external accessible IP, make
    ## sure you add extra firewall rules to prevent unauthorized access:
    bind 10.0.0.1
       
    ## Define a `port` to force redis to listen on TCP so other machines can
    ## connect to it (default port is `6379`).
    port 6379
       
    ## Set up password authentication (use the same password in all nodes).
    ## The password should be defined equal for both `requirepass` and `masterauth`
    ## when setting up Redis to use with Sentinel.
    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 を編集します:

    ## Define a `bind` address pointing to a local IP that your other machines
    ## can reach you. If you really need to bind to an external accessible IP, make
    ## sure you add extra firewall rules to prevent unauthorized access:
    bind 10.0.0.2
       
    ## Define a `port` to force redis to listen on TCP so other machines can
    ## connect to it (default port is `6379`).
    port 6379
       
    ## Set up password authentication (use the same password in all nodes).
    ## The password should be defined equal for both `requirepass` and `masterauth`
    ## when setting up Redis to use with Sentinel.
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
       
    ## Define `replicaof` pointing to the Redis primary instance with IP and port.
    replicaof 10.0.0.1 6379
    
  3. Redisサービスを再起動して変更を有効にします。
  4. 他のすべてのレプリカノードについて、もう一度手順を実行します。

ステップ3.Redis Sentinelインスタンスの設定

SentinelはRedisサーバーの特別なタイプです。redis.conf で定義できる基本的な設定オプションのほとんどを継承し、sentinel 接頭辞で始まる特定のオプションを使用します。

Redis SentinelがIP10.0.0.1 を持つRedisプライマリと同じインスタンスにインストールされていると仮定します(一部の設定はプライマリと重複する可能性があります):

  1. Redis Sentinelをインストールします。
  2. /etc/redis/sentinel.conf を編集します:

    ## Define a `bind` address pointing to a local IP that your other machines
    ## can reach you. If you really need to bind to an external accessible IP, make
    ## sure you add extra firewall rules to prevent unauthorized access:
    bind 10.0.0.1
       
    ## Define a `port` to force Sentinel to listen on TCP so other machines can
    ## connect to it (default port is `6379`).
    port 26379
       
    ## Set up password authentication (use the same password in all nodes).
    ## The password should be defined equal for both `requirepass` and `masterauth`
    ## when setting up Redis to use with Sentinel.
    requirepass redis-password-goes-here
    masterauth redis-password-goes-here
       
    ## Define with `sentinel auth-pass` the same shared password you have
    ## defined for both Redis primary and replicas instances.
    sentinel auth-pass gitlab-redis redis-password-goes-here
       
    ## Define with `sentinel monitor` the IP and port of the Redis
    ## primary node, and the quorum required to start a failover.
    sentinel monitor gitlab-redis 10.0.0.1 6379 2
       
    ## Define with `sentinel down-after-milliseconds` the time in `ms`
    ## that an unresponsive server is considered down.
    sentinel down-after-milliseconds gitlab-redis 10000
       
    ## Define a value for `sentinel failover_timeout` in `ms`. This has multiple
    ## meanings:
    ##
    ## * The time needed to re-start a failover after a previous failover was
    ##   already tried against the same primary by a given Sentinel, is two
    ##   times the failover timeout.
    ##
    ## * The time needed for a replica replicating to a wrong primary according
    ##   to a Sentinel current configuration, to be forced to replicate
    ##   with the right primary, is exactly the failover timeout (counting since
    ##   the moment a Sentinel detected the misconfiguration).
    ##
    ## * The time needed to cancel a failover that is already in progress but
    ##   did not produced any configuration change (REPLICAOF NO ONE yet not
    ##   acknowledged by the promoted replica).
    ##
    ## * The maximum time a failover in progress waits for all the replicas to be
    ##   reconfigured as replicas of the new primary. However even after this time
    ##   the replicas are reconfigured by the Sentinels anyway, but not with
    ##   the exact parallel-syncs progression as specified.
    sentinel failover_timeout 30000
    
  3. Redisサービスを再起動して変更を有効にします。
  4. 他のすべてのSentinelノードについて、もう一度手順を実行します。

ステップ 4.GitLab アプリケーションの設定

Sentinelのサポートは、新規または既存のインストールでいつでも有効または無効にすることができます。GitLabアプリケーションの観点からは、必要なのはSentinelノードの正しい認証情報だけです。

すべてのセンチネルノードのリストは必要ありませんが、障害が発生した場合、リストアップされたノードの少なくとも1つにアクセスする必要があります。

以下のステップはGitLabアプリケーションサーバーで実行する必要があり、理想的には同じマシンにRedisやSentinelがないことが望ましいです:

  1. resque.yml.exampleの例に従って/home/git/gitlab/config/resque.yml を編集し、Sentinel の行のコメントを解除して、正しいサーバー認証情報を指定します:

    # resque.yaml
    production:
      url: redis://:redi-password-goes-here@gitlab-redis/
      sentinels:
        -
          host: 10.0.0.1
          port: 26379  # point to sentinel, not to redis port
        -
          host: 10.0.0.2
          port: 26379  # point to sentinel, not to redis port
        -
          host: 10.0.0.3
          port: 26379  # point to sentinel, not to redis port
    
  2. 変更を有効にするためにGitLabを再起動してください。

プライマリ1、レプリカ2、センチネル3の最小設定例

この例では、すべてのサーバーが10.0.0.x の範囲のIPを持つ内部ネットワークインターフェースを持ち、これらのIPを使って相互に接続できると考えます。

実際の使用では、他のマシンからの不正アクセスを防ぐためにファイアウォールルールを設定し、外部(インターネット)からのトラフィックをブロックします。

この例では、Sentinel 1は Redis Primaryと同じマシンに、Sentinel 2は Replica 1と同じマシンに、Sentinel 3は Replica 2と同じマシンに設定されています。

各マシンと割り当てられたIPのリストと説明は次のとおりです:

  • 10.0.0.1:Redis プライマリ + センチネル 1
  • 10.0.0.2:Redisレプリカ1 + センチネル2
  • 10.0.0.3:Redisレプリカ2 + センチネル3
  • 10.0.0.4:GitLabアプリケーション

初期設定の後、Sentinelノードによってフェイルオーバーが開始されると、Redisノードは再設定され、プライマリノードは、新しいフェイルオーバーが再び開始されるまで、一方のノードから他方のノードへと永続的に変更されます(redis.confを含む)。

新しいセンチネルノードがプライマリの監視を開始した後、またはフェイルオーバーが別のプライマリノードを昇格させた後、最初の実行後にオーバーライドされたsentinel.conf でも同じことが起こります。

Redisプライマリとセンチネル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  # point to sentinel, not to redis port
        -
          host: 10.0.0.2
          port: 26379  # point to sentinel, not to redis port
        -
          host: 10.0.0.3
          port: 26379  # point to sentinel, not to redis port
    
  2. 変更を有効にするためにGitLabを再起動してください。

トラブルシューティング

Redisのトラブルシューティングガイドをご覧ください。