序章

RedisはオープンソースのKey-Valueデータストアであり、永続性のためにオプションのディスク書き込みを備えたインメモリストレージモデルを使用しています。 トランザクション、Pub / Subメッセージングパターン、自動フェイルオーバーなどの機能を備えています。 Redisには、ほとんどの言語で記述されたクライアントがあり、推奨される言語はそのWebサイトに掲載されています。

実稼働環境では、少なくとも2つのノード間でデータを複製することがベストプラクティスと見なされます。 これにより、環境障害が発生した場合の回復が可能になります。これは、アプリケーションのユーザーベースが拡大した場合に特に重要です。 また、本番データを変更したり、パフォーマンスに影響を与えたりすることなく、本番データを安全に操作できます。

このガイドでは、両方ともUbuntu16.04を実行している2台のサーバー間のレプリケーションを構成します。 このプロセスは、必要に応じて、より多くのサーバーに簡単に適合させることができます。

前提条件

このガイドを完了するには、2台のUbuntu16.04サーバーにアクセスする必要があります。 Redisが使用する用語に沿って、書き込み要求の受け入れを担当するプライマリサーバーをマスターサーバーと呼び、セカンダリ読み取り専用サーバーをスレーブサーバーと呼びます。

これらの各サーバーでsudo権限が構成されたroot以外のユーザーが必要です。 さらに、このガイドでは、基本的なファイアウォールが設定されていることを前提としています。 Ubuntu 16.04初期サーバーセットアップガイドに従って、これらの要件を満たすことができます。

始める準備ができたら、このガイドを続けてください。

ステップ1:Redisをインストールする

まず、マスターサーバーとスレーブサーバーの両方にRedisをインストールします。

ChrisLeaのRedisPPAを使用して最新のRedisサーバーパッケージをインストールします。 サードパーティのリポジトリを有効にする場合は、常に注意してください。 この場合、Chris Leaは、多くの高品質パッケージを維持する定評のあるパッケージャーです。

まず、PPAを両方のサーバーに追加します。

  1. sudo apt-add-repository ppa:chris-lea/redis-server

ENTERを押してリポジトリを受け入れます。

次に、サーバーのローカルパッケージインデックスを更新し、次のように入力してRedisサーバーパッケージをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install redis-server

これにより、Redisサーバーがインストールされ、サービスが開始されます。

次のように入力して、Redisが稼働していることを確認します。

  1. redis-cli ping

次の応答が返されます。

Output
PONG

これは、Redisが実行中であり、ローカルクライアントからアクセスできることを示しています。

ステップ2:2台のサーバー間のトラフィックを保護する

レプリケーションを設定する前に、Redisのセキュリティモデルの意味を理解することが重要です。 Redisはネイティブ暗号化オプションを提供せず、信頼できるピアのプライベートネットワークにデプロイされていることを前提としています。

Redisが分離されたネットワークにデプロイされている場合…

サーバーが分離されたネットワークで動作している場合は、おそらく、分離されたネットワークのIPアドレスにバインドするようにRedisの構成ファイルを調整するだけで済みます。

各コンピューターでRedis構成ファイルを開きます。

  1. sudo nano /etc/redis/redis.conf

bind行を見つけて、サーバー独自の分離されたネットワークIPアドレスを追加します。

/etc/redis/redis.conf
bind 127.0.0.1 isolated_IP_address

ファイルを保存して閉じます。 次のように入力して、サービスを再起動します。

  1. sudo systemctl restart redis-server.service

Redisポートへのアクセスを開きます。

  1. sudo ufw allow 6379

これで、-hフラグを指定してredis-cliコマンドに代替サーバーのIPアドレスを指定することにより、一方のサーバーから他方のサーバーにアクセスできるようになります。

  1. redis-cli -h isolated_IP_address ping
Output
PONG

これで、Redisは分離されたネットワークからの接続を受け入れることができます。

Redisが分離されたネットワークにデプロイされていない場合…

分離されていない、または制御していないネットワークの場合、トラフィックを他の手段で保護することが不可欠です。 Redisサーバー間のトラフィックを保護するには、次のような多くのオプションがあります。

  • stunnelを使用したトンネリング:サーバーごとに着信トンネルと発信トンネルが必要になります。 ガイドの下部に例があります。
  • spipedによるトンネリング:サーバーごとに2つのsystemdユニットファイルを作成する必要があります。1つはリモートサーバーとの通信用で、もう1つは接続を独自のRedisプロセスに転送するためのものです。 詳細はガイドの下部に記載されています。
  • PeerVPNを使用したVPNのセットアップ:VPN上で両方のサーバーにアクセスできる必要があります。

上記のいずれかの方法を使用して、Redisマスターサーバーとスレーブサーバー間の安全な通信方法を確立します。 各マシンがピア上のRedisサービスに安全に接続するために必要なIPアドレスとポートを知っておく必要があります。

手順3:Redisマスターを構成する

Redisが各サーバーで稼働し、安全な通信チャネルが確立されたので、構成ファイルを編集する必要があります。 マスターとして機能するサーバーから始めましょう。

お気に入りのテキストエディタで/etc/redis/redis.confを開きます。

  1. sudo nano /etc/redis/redis.conf

コメントが示すように、tcp-keepalive設定を見つけて、60秒に設定することから始めます。 これは、Redisがネットワークまたはサービスの問題を検出するのに役立ちます。

/etc/redis/redis.conf
. . .
tcp-keepalive 60
. . .

requirepassディレクティブを見つけて、強力なパスフレーズに設定します。 Redisトラフィックは外部から保護されている必要がありますが、これによりRedis自体に認証が提供されます。 Redisは高速で、パスワードの試行をレート制限しないため、ブルートフォース攻撃から保護するために強力で複雑なパスフレーズを選択してください。

/etc/redis/redis.conf
requirepass your_redis_master_password

最後に、使用シナリオに応じて調整できるオプション設定がいくつかあります。

Redisがいっぱいになったときに、古くて使用頻度の低いキーを自動的に削除したくない場合は、自動キー削除をオフにすることができます。

/etc/redis/redis.conf
maxmemory-policy noeviction

耐久性の保証を向上させるために、追加のみのファイルの永続性をオンにすることができます。 これにより、ファイルが大きくなり、パフォーマンスがわずかに低下しますが、システム障害が発生した場合のデータ損失を最小限に抑えることができます。

/etc/redis/redis.conf
appendonly yes
appendfilename "redis-staging-ao.aof"

終了したら、ファイルを保存して閉じます。

Redisサービスを再起動して、構成の変更を再読み込みします。

  1. sudo systemctl restart redis-server.service

マスターサーバーが構成されたので、少し時間を取ってテストします。

ステップ4:Redisマスターをテストする

Redisクライアントを起動して設定したパスワードを使用して認証できることを確認します。

  1. redis-cli

まず、認証せずにコマンドを試してください。

  1. info replication

次の応答が返されます。

Redis master output
NOAUTH Authentication required.

これは予期されたものであり、Redisサーバーが認証されていないリクエストを正しく拒否していることを示しています。

次に、authコマンドを使用して認証します。

  1. auth your_redis_master_password

クレデンシャルが受け入れられたことの確認を受け取る必要があります。

Redis master output
OK

コマンドを再試行すると、今回は成功するはずです。

  1. info replication
Redis master output
# Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0

認証中に、後でレプリケーションを確認できるようにテストキーを設定します。

  1. set test 'this key was defined on the master server'

終了したら、オペレーティングシステムシェルに戻ります。

  1. exit

マスターサーバーの準備ができたので、スレーブマシンに移りましょう。

手順5:Redisスレーブを構成する

次に、スレーブサーバーがマスターインスタンスに接続できるように、いくつかの変更を加える必要があります。

スレーブサーバーで/etc/redis/redis.confを開きます。

  1. sudo nano /etc/redis/redis.conf

まず、slaveof行を見つけてコメントを外します。 このディレクティブは、マスターRedisサーバーに安全に接続するために使用するIPアドレスとポートをスペースで区切って取得します。 デフォルトでは、Redisサーバーはローカルインターフェイスで6379をリッスンしますが、各ネットワークセキュリティメソッドは、外部の関係者に対して何らかの方法でデフォルトを変更します。

使用する値は、ネットワークトラフィックを保護するために使用した方法によって異なります。

  • 分離ネットワーク:マスターサーバーの分離ネットワークIPアドレスとRedisポート(6379)を使用します(たとえば、slaveof isolated_IP_address 6379)。
  • stunnelまたはspiped:ローカルインターフェース(127.0.0.1)と、トラフィックをトンネルするように構成されたポートを使用します(ガイドに従った場合、これはslaveof 127.0.0.1 8000になります)。
  • PeerVPN :マスターサーバーのVPN IPアドレスと通常のRedisポートを使用します(ガイドに従った場合、これはslaveof 10.8.0.1 6379になります)。

一般的な形式は次のとおりです。

/etc/redis/redis.conf
slaveof ip_to_contact_master port_to_contact_master

次に、コメントを外して、masterauth行にRedisマスターサーバーに設定されたパスワードを入力します。

/etc/redis/redis.conf
masterauth your_redis_master_password

不正アクセスを防ぐために、スレーブサーバーのパスワードを設定します。 パスワードの複雑さに関する同じ警告がここに適用されます。

/etc/redis/redis.conf
requirepass your_redis_slave_password

終了したら、ファイルを保存して閉じます。

ステップ6:Redisスレーブをテストし、変更を適用する

変更を実装するためにサービスを再起動する前に、スレーブマシン上のローカルRedisインスタンスに接続し、testキーが設定されていないことを確認しましょう。

  1. redis-cli

次のように入力して、キーをクエリします。

  1. get test

次の応答が返されるはずです。

Redis slave output
(nil)

これは、ローカルRedisインスタンスにtestという名前のキーがないことを示しています。 次のように入力して、シェルに戻ります。

  1. exit

スレーブでRedisサービスを再起動して、次の変更を実装します。

  1. sudo systemctl restart redis-server.service

これにより、Redisスレーブ構成ファイルに加えたすべての変更が適用されます。

ローカルのRedisインスタンスに再度接続します。

  1. redis-cli

Redisマスターサーバーと同様に、許可されていない場合、操作は失敗するはずです。

  1. get test
Redis slave output
(error) NOAUTH Authentication required.

ここで、前のセクションで設定したRedisスレーブのパスワードを使用して認証します。

  1. auth your_redis_slave_password
Redis slave output
OK

今回キーにアクセスしようとすると、次のキーが使用可能であることがわかります。

  1. get test
Redis slave output
"this key was defined on the master server"

スレーブでRedisサービスを再起動すると、すぐにレプリケーションが開始されました。

これは、レプリケーションに関する情報を報告するRedisのinfoコマンドで確認できます。 master_hostおよびmaster_portの値は、slaveofオプションに使用した引数と一致する必要があります。

  1. info replication
Redis slave output
# Replication role:slave master_host:10.8.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:5 master_sync_in_progress:0 slave_repl_offset:1387 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0

Redisマスターサーバーで同じ情報を見ると、次のように表示されます。

  1. info replication
Redis master output
# Replication role:master connected_slaves:1 slave0:ip=10.8.0.2,port=6379,state=online,offset=1737,lag=1 master_repl_offset:1737 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:1736

ご覧のとおり、マスターサーバーとスレーブサーバーは、定義された関係で相互に正しく識別します。

ステップ7:Redisスレーブをマスターにプロモートする

レプリケーションを設定する主な理由は、データの損失とダウンタイムを最小限に抑えて障害を処理することです。 Redisスレーブは、Redisマスターに障害が発生した場合に書き込みトラフィックを処理するために、マスターステータスに昇格させることができます。

Redisスレーブを手動でプロモートする

これは、Redisスレーブサーバーから手動で行うことができます。 Redisクライアントでログインします。

  1. redis-cli

Redisスレーブパスワードを使用して認証します。

  1. auth your_redis_slave_password

Redisスレーブをプロモートする前に、テストキーを上書きしてみてください。

  1. set test 'this key was overwritten on the slave server'

デフォルトでは、Redisスレーブはslave-read-only yesオプションを使用して読み取り専用に構成されているため、これは失敗するはずです。

Redis slave output
(error) READONLY You can't write against a read only slave.

レプリケーションを無効にして現在のサーバーをマスターステータスに昇格させるには、no oneの値を指定してslaveofコマンドを使用します。

  1. slaveof no one
Redis slave output
OK

レプリケーション情報をもう一度確認してください。

  1. info replication
Redis slave output
# Replication role:master connected_slaves:0 master_repl_offset:6749 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0

ご覧のとおり、スレーブはRedisマスターに指定されています。

キーをもう一度上書きしてみてください。今回は成功するはずです。

  1. set test 'this key was overwritten on the slave server'
Redis slave output
OK

構成ファイルは引き続きこのノードをRedisスレーブとして指定しているため、構成を変更せずにサービスを再起動すると、レプリケーションが再開されることに注意してください。 また、Redisマスターに使用した設定は、ここで再適用する必要がある場合があることにも注意してください(たとえば、追加専用ファイルをオンにしたり、エビクションポリシーを変更したりします)。

他にスレーブがある場合は、新しく昇格したマスターをポイントして、変更の複製を続行します。 これは、slaveofコマンドと新しいマスターの接続情報を使用して実行できます。

元のマスターへのレプリケーションを手動で再開するには、構成ファイルで使用されている値を使用してslaveofコマンドを使用し、暫定マスターとスレーブを元のマスターに戻します。

  1. slaveof ip_to_contact_master port_to_contact_master
Redis slave output
OK

スレーブのキーをもう一度確認すると、Redisマスターによって元の値が復元されていることがわかります。

  1. get test
Redis slave output
"this key was defined on the master server"

一貫性の理由から、スレーブがマスターサーバーと再同期されると、スレーブ上のすべてのデータがフラッシュされます。

Redisスレーブを自動的にプロモートする

Redisスレーブを自動的にプロモートするには、アプリケーション層との調整が必要です。 これは、実装がアプリケーション環境に大きく依存していることを意味し、特定のアクションを提案することを困難にします。

ただし、自動フェイルオーバーを実行するために必要な一般的な手順を確認できます。 以下の手順は、すべてのRedisサーバーが相互にアクセスするように構成されていることを前提としています。

  • アプリケーションから、マスターサーバーが使用できなくなったことを検出します。
  • 1つのスレーブで、slaveof no oneコマンドを実行します。 これにより、レプリケーションが停止し、マスターステータスに昇格します。
  • 新しいマスターの設定を調整して、以前のマスター設定に合わせます。 これは、ほとんどのオプションの構成ファイルで事前に行うことができます。
  • アプリケーションから新しくプロモートされたRedisマスターにトラフィックを転送します。
  • 残りのスレーブで、slaveof new_master_ip new_master_portを実行します。 これにより、スレーブは古いマスターからの複製を停止し、(現在は非推奨になっている)データを完全に破棄し、新しいマスターからの複製を開始します。

元のマスターサーバーにサービスを復元した後、新しく昇格したマスターを指すスレーブとして再参加するか、必要に応じてマスターとしての職務を再開することができます。

結論

2つのサーバーで構成される環境をセットアップしました。1つはRedisマスターとして機能し、もう1つはスレーブとしてデータを複製します。 これにより、システムまたはネットワークに障害が発生した場合に冗長性が提供され、パフォーマンス上の理由から、読み取り操作を複数のサーバーに分散させることができます。 これは、本番アプリケーションとインフラストラクチャのニーズに合わせてRedis構成を設計するための良い出発点ですが、このテーマに関する完全なガイドではありません。 アプリケーションのニーズに合わせてRedisを使用する方法の詳細については、その他のRedisチュートリアルをご覧ください。