警告: この文章はドラフトであり、Sentinelプロジェクトが進化するにつれて、この文章に含まれるガイドラインは将来変更されるかもしれません。

*Redis Sentinel をサポートするRedisクライアントのためのガイドライン

Redis Sentinel は、Redisマスターの自動フェイルオーバーおよびサービス検出(指定されたインスタンスグループについて誰が現在のマスターなのか)を処理するRedisインスタンスのための監視ソリューションです。Sentinel はフェイルオーバー中にインスタンスを再構成することと、Redisマスターあるいはレプリカに接続するクライアントに構成を提供することの両方に責任があるため、クライアントはRedis Sentinelを明示的にサポートする必要があります。

この文章は以下の目的でSentinelをクライアントの実装でサポートしたいRedisクライアントの開発者を対象としています。

  • Sentinelによるクライアントの自動設定
  • Redis Sentinel自動フェイルオーバーの安全性の向上。

この文章はRedisクライアントの開発者にとって必要な情報だけを含んでいて、読者がRedis Sentinelの動作がどのように動作するかの詳細に精通していることを期待しているため、Redis Sentinelがどのように動作するかについての詳細はRedisのドキュメントを参照してください。

*SentinelによるRedisのサービス検出

Redis Sentinel は全てのマスターを "stats" あるいは "cache" のような名前で識別します。全ての名前は実際には、マスターと可変数のレプリカで構成される インスタンスのグループを識別します。

ネットワーク内の特定の目的のために使われるRedisマスターのアドレスは、自動フェイルオーバー、手動でトリガーされたフェイルオーバー(例えばインスタンスをアップグレードするため)のようなイベントの後、およびその他の理由で変更されるかもしれません。

通常、Redisクライアントは、ネットワーク内のRedisマスターインスタンスのアドレスをIPアドレスとポート番号として指定するある種のハードコーディングされた設定を持ちます。ただし、もしマスターアドレスが変更された場合は、全てのクライアントに手動で挿入する必要があります。

SentinelをサポートするRedisクライアントは、Redis Sentinelを使ってマスター名からRedisマスターのアドレスを自動的に検出することができます。つまり、ハードコードされているIPアドレスとポートの代わりに、Sentinelをサポートするクライアントは以下のものを任意に取ることができるべきです:

  • 既知のSentinelインスタンスの ip:port のペアのリスト。
  • "cache" あるいは "timelines" のようなサービス名。

これはSentinelのリストとサービス名から始まるマスターアドレスを取得するためにクライアントが従うべき手順です。

*Step 1: 最初のSentinelに接続

クライアントはSentinelのアドレスのリストを繰り返す必要があります。全てのアドレスに対して、短いタイムアウト(数百ミリ秒のオーダー)を使用して、Sentinelに接続しようとします。エラーあるいはタイムアウト時に次のSentinelのアドレスを試す必要があります。

もし全ての Sentinel のアドレスが成功せずに施行された場合は、クライアントにエラーが返されなければなりません。

クライアントの要求に応答する最初のSentinelは、次の再接続時に前回の接続の試行で到達可能だったSentinelを最初に試し待ち時間を最小に抑えるために、リストの最初に配置する必要があります。

*Step 2: マスターアドレスアドレスを尋ねる

Sentinelとの接続が確立されたら、クライアントはSentinel上で以下のコマンドを再実行する必要があります:

SENTINEL get-master-addr-by-name master-name

master-name はユーザによって指定される実際のサービス名で置き換えられなければなりません。

この呼び出しによる結果は、以下の2つの応答のうちのいずれかになりえます:

  • ip:port のペア。
  • null の応答。これはSentinelが個のマスターを知らないことを意味します。

もし ip:port のペアを受け取った場合は、Redisマスターに接続するためにこのアドレスが使われなければなりません。それ以外の場合、もしnull応答を受け取った場合は、クライアントはリスト内の次のSentinelを試す必要があります。

*Step 3: 宛先のインスタンス内でROLEコマンドを呼び出す

クライアントがマスターインスタンスのアドレスを検出すると、マスターとの接続を試み、インスタンスの役割が実際にマスターであることを確認するためにROLEコマンドを呼び出します。

もし ROLE コマンドが利用できない場合(Redis 2.8.12で導入されました)、クライアントはINFO replicationコマンドを使用して、出力のrole: フィールドを解析します。

もしインスタンスが期待通りのマスターではない場合、クライアントは短時間(数百ミリ秒)待ってから、Step 1からやり直してください。

*再接続の処理

サービス名がマスターアドレスに解決されRedisマスターインスタンスとの接続が確立されると、再接続が必要になるたびにクライアントはStep 1からSentinelの再起動を使ってアドレスを再び解決する必要があります。例えばSentinelは以下の場合に再び接続する必要があります:

  • タイムアウトまたはソケットエラーの後でクライアントが再接続する場合。
  • クライアントが明示的にクローズしたか、あるいはユーザによって再接続されたためにクライアントが再接続する場合。

上記の場合、及びクライアントがRedisサーバとの接続を失った他の場合には、クライアントはマスターアドレスを再び解決する必要があります。

*Sentinelのフェイルオーバーの切断

Redis 2.8.12から、Redis Sentinel がインスタンスの設定を変更した時、例えばレプリカをマスターに昇格させる、フェイルオーバー後に新しいマスターにレプリケートするように降格させる、あるいは単純に古いレプリカインスタンスのマスターアドレスを変更する、Redis Sentinelは全てのクライアントが再設定されたインスタンスから切断されていることを確認するためにインスタンスにCLIENT KILL type normal コマンドを送信します。これによりクライアントはマスターアドレスを再度解決するように強制されます。

クライアントがまだ更新されていない情報でSentinelに接続する場合、ROLE コマンドによるRedisインスタンス ロールの検証が失敗し、クライアントは接続されたSentinelが古い情報を提供したことを検出して再試行します。

注意: クライアントが古いSentinelインスタンスと通信すると同時に古いマスターがオンラインに戻る可能性があるため、クライアントは古いマスターと接続することができますが依然としてROLEの出力は一致するでしょう。ですが、マスターが再び戻った時にSentinelはそれをレプリカに降格させようとし、新しい切断を引き起こします。同じ論法が異なるマスターとレプリケートするように再設定された古いレプリカへの接続へも適用されます。

*レプリカへの接続

例えば読み込みのリクエストのスケールのために、クライアントがレプリカに接続したい場合があります。このプロトコルは Step 2 をわずかに変更する事でレプリカへの接続をサポートします。次のコマンドを呼び出す代わりに:

SENTINEL get-master-addr-by-name master-name

クライアントは以下を代わりに呼び出すべきです:

SENTINEL replicas master-name

レプリカインスタンスのリストを取得するため。

対照的にクライアントはマスターとの読み込みクエリのスケーリングを避けるために、インスタンスが実際にレプリカであること ROLE コマンドを使って検証しなければなりません。

*コネクション プール

コネクションプールを実装しているクライアントについて、単一接続の再接続時にSentinelは再び接続する必要があります。マスターのアドレスが変更された場合はきぉんの全ての接続が閉じられ、新しいアドレスに接続される必要があります。

*エラー報告

エラーが発生した場合、クライアントは情報を正しくユーザに返さなければなりません。具体的には:

  • Sentinelにアクセスできない場合(クライアントが SENTINEL get-master-addr-by-nameへの応答を受け取れなかった場合)、Redis Sentinelにアクセスできないことを明確に示すエラーを返す必要があります。
  • プール内の全てのSentinelがnull応答を返した場合、Sentinelがこのマスタ名を認識していないというエラーがユーザに知らされなければなりません。

*Sentinelのリストの自動更新

任意に get-master-addr-by-name への成功の応答が受信されると、クライアントは以下の手順に従ってSentinelのノードの内部的なリストを更新することができます。

  • コマンド SENTINEL sentinels <master-name>を使ってこのマスターについての他のSentinelのリストを取得します。
  • リストの最後にまだリストに存在していない全ての ip:port ペアを追加します。

クライアントがリストを永続的にして独自の設定を更新できるようにする必要はありません。Sentinelのリストのメモリ内表現をアップグレードする機能は、信頼性を向上するために十分有用です。

*応答性を改善するためにSentinelを購読する

Sentinelのドキュメントには、Redisインスタンス設定の変更を購読するためにクライアントがPub/Subを使ってSentinelインスタンスに接続する方法が示されています。

この仕組みはクライアントの再設定を高速化するために使うことができます。つまり、この文章で記述された新しいRedisマスター(あるいはレプリカ)のアドレスを解決するための3つのステップの手順を実行するためにいつ設定の変更が発生したかを知るために、クライアントはPub/Subをlistenすることができます。

しかし、Pub/Subを使って受信された更新メッセージは、クライアントが全ての更新メッセージを受信することができるという保証がないため、上記の手順の代用にするべきではありません。

*追加の情報

追加の情報あるいはこのガイドラインの具体的な記載についての議論、Redis Google Groupにメッセージを送ってください。

TOP
inserted by FC2 system