Ubuntu 16.04でRedisレプリケーションを構成する方法

前書き

Redisはオープンソースのキーと値のデータストアであり、永続化のためにオプションのディスク書き込みを伴うメモリ内ストレージモデルを使用します。 トランザクション、pub / subメッセージングパターン、および他の機能の中での自動フェールオーバーを備えています。 Redisには、ほとんどの言語で記述されたクライアントがあり、推奨されるクライアントはtheir websiteで紹介されています。

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

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

前提条件

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

これらの各サーバーで構成されたsudo特権を持つ非rootユーザーが必要です。 さらに、このガイドでは、基本的なファイアウォールが設定されていることを前提としています。 これらの要件を満たすために、Ubuntu 16.04 initial server setup guideをたどることができます。

開始する準備ができたら、このガイドに進みます。

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

開始するには、masterサーバーとslaveサーバーの両方にRedisをインストールします。

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

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

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

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

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

sudo apt-get update
sudo apt-get install redis-server

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

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

redis-cli ping

次の応答が返されます。

OutputPONG

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

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

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

Redisが分離されたネットワークに展開されている場合…

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

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

sudo nano /etc/redis/redis.conf

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

/etc/redis/redis.conf

bind 127.0.0.1 isolated_IP_address

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

sudo systemctl restart redis-server.service

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

sudo ufw allow 6379

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

redis-cli -h isolated_IP_address ping
OutputPONG

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

Redisが分離されたネットワークに展開されていない場合…

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

  • Tunneling with stunnel:サーバーごとに着信トンネルと発信トンネルが必要になります。 例は、ガイドの下部にあります。

  • Tunneling with spiped:サーバーごとに2つのsystemdユニットファイルを作成する必要があります。1つはリモートサーバーとの通信用で、もう1つは接続を独自のRedisプロセスに転送するためのものです。 詳細はガイドの下部に記載されています。

  • Setting up a VPN with PeerVPN:両方のサーバーがVPNでアクセス可能である必要があります。

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

ステップ3:Redisマスターを設定する

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

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

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サービスを再起動して、構成の変更を再読み込みします。

sudo systemctl restart redis-server.service

マスターサーバーが設定されたので、少し時間をかけてテストしてください。

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

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

redis-cli

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

info replication

次の応答が返されます。

Redis master outputNOAUTH Authentication required.

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

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

auth your_redis_master_password

資格情報が受け入れられたことの確認を受信する必要があります。

Redis master outputOK

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

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

認証されている間に、後で複製を確認できるようにテストキーを設定します。

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

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

exit

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

ステップ5:Redisスレーブを構成する

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

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

sudo nano /etc/redis/redis.conf

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

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

  • isolated network:マスターサーバーの分離されたネットワーク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キーが設定されていないことを確認しましょう。

redis-cli

次のように入力して、キーを照会します。

get test

次の応答が返されます。

Redis slave output(nil)

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

exit

これらの変更を実装するには、スレーブでRedisサービスを再起動します。

sudo systemctl restart redis-server.service

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

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

redis-cli

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

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

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

auth your_redis_slave_password
Redis slave outputOK

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

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

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

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

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マスターサーバーで同じ情報を見ると、次のようなものが表示されます。

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クライアントでログインします。

redis-cli

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

auth your_redis_slave_password

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

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コマンドを使用します。

slaveof no one
Redis slave outputOK

複製情報を再度確認します。

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マスターに指定されています。

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

set test 'this key was overwritten on the slave server'
Redis slave outputOK

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

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

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

slaveof ip_to_contact_master port_to_contact_master
Redis slave outputOK

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

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を実行します。 これにより、スレーブは古いマスターからの複製を停止し、それらの(現在では廃止された)データを完全に破棄し、新しいマスターからの複製を開始します。

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

結論

Redisマスターとして機能するサーバーとスレーブとしてデータを複製するサーバーの2つのサーバーで構成される環境をセットアップしました。 これにより、システムまたはネットワークに障害が発生した場合に冗長性が提供され、パフォーマンス上の理由から複数のサーバー間で読み取り操作を分散できます。 これは、実稼働アプリケーションとインフラストラクチャのニーズに合わせてRedis構成を設計するための適切な出発点ですが、決して主題に関する包括的なガイドではありません。 アプリケーションのニーズにRedisを使用する方法の詳細については、other Redis tutorialsを確認してください。