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

前書き

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

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

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

前提条件

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

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

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

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

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

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

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

sudo systemctl restart redis-server.service

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

sudo ufw allow 6379

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

redis-cli -h  ping
OutputPONG

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

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

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

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

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

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

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

sudo nano /etc/redis/redis.conf

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

/etc/redis/redis.conf

. . .
tcp-keepalive
. . .

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

/etc/redis/redis.conf

requirepass

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

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

/etc/redis/redis.conf

maxmemory-policy

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

/etc/redis/redis.conf

appendonly
appendfilename ""

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

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

sudo systemctl restart redis-server.service

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

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

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

redis-cli

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

info replication

次の応答が返されます。

Redis master outputNOAUTH Authentication required.

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

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

auth

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

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スレーブを構成する

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

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

sudo nano /etc/redis/redis.conf

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

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

  • 隔離されたネットワーク:隔離されたネットワークIPアドレスとマスターサーバーのRedisポート(6379)を使用します(たとえば、 + slaveof 6379 +)。

  • * stunnel または spiped *:ローカルインターフェイス(127.0.0.1)とトラフィックをトンネルするように構成されたポートを使用します(ガイドに従った場合、これは「+ slaveof 127.0.0.1 8000+」になります)。

  • * PeerVPN *:マスターサーバーのVPN IPアドレスと通常のRedisポートを使用します(これは「+ slaveof 10.8.0」になります。 ガイドに従った場合は6379 + `)。

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

/etc/redis/redis.conf

slaveof

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

/etc/redis/redis.conf

masterauth

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

/etc/redis/redis.conf

requirepass

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

ステップ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
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:
master_port:
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=,port=,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

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

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

結論

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