Flickr: Redis Sentinelの導入

http://code.flickr.net/2014/07/31/redis-sentinel-at-flickr/

1 comment | 0 points | by WazanovaNews 約2時間前 edited


Jshiike 約2時間前 edited | ▲upvoteする | link

Flickrがエンジニアブログで、Redisのマスター障害復旧を自動化するためにRedis Sentinelを導入した経験を紹介しています。

Redisのユースケース

  • 本番サービスに影響を与えないように、写真のアップロード / ユーザ通知 / メタデータの編集などの重たいタスクは、Redisのキューに送られて、非同期でオフライン処理されている。
  • クリティカルなタスクなので、99.9999%が処理(100万件のうち1件以下)され、99.995%の時間は稼働(月に停止が2分を超えない)させる必要がある。
  • もし、マスターが落ちると、復旧は手動対応。マスターを本番からはずし、スレーブの一つを昇格(そこそこ時間がかかる)させ、AOF(append-only-files)とエラーログから未処理のデータを再構成(ものすごく時間がかかる)する。数時間の作業、ユーザの利用への影響、データ欠損の可能性があり。実際にマスターが落ちたことはなかったが、リスクは大きい。

Sentinelの設定

  • シンプルで文法はRedisに似ている。
  • Aphyrの記事ブログで指摘されていた、ネットワークパーティションが分かれた際のリスクは理解したが、自分たちのユースケースの場合は、メリットの方が大きいと判断した(検証結果は後述)。
  • level-of-agreementにおける、自動復旧が始まる前にSentinelがホストの障害を同時にレポートできるインスタンス数の設定は重要。この数値が小さ過ぎると本当の障害を見逃すし、大き過ぎると誤ったアラートが増える。調整を重ねて、80%のインスタンスに設定した。
  • down-after-milliseconds設定は、Sentinelが、ホストの障害を宣言する前、pingに反応せずに待機する時間。何故か、1,000ms以下にすると、ホスト障害のnotificationがエンドレスにでてしまう。3,100msでセットしている。
  • 障害復旧後に同時に再設定できるスレーブの数を決める parallel-sync value を1にセット。read-onlyスレーブからのクエリを提供したければ、この数値は小さくする。
  • Sentinelはステートを設定ファイルに書込むようになっている。これだと、一貫した起動設定をしようにも、Sentinel側がランタイムで設定ファイルを修正してしまうと困る。Flickrの運用ポリシーに合わない。そこで、Sentinel設定ファイルを二つ用意。一つは、Git上でメンテして、Sentinentに修正をかけられることがない。これをデプロイのプロセスで利用するが、もしSentinelシステム設定を更新する際(ほぼない)はインストールする。それから起動スクリプトで、設定ファイルをコピーし、コマンドラインのパラメータ経由でSentinelに渡す。Sentinelは必要であれば、コピーされたファイルを修正する。

Sentinelとのインターフェース

  • Sentinelは、RedisとRedisクライアントの間のインバンドではなく、アウトバンドにあり、起動時にサービスからコンタクトする。そして、Redisの障害を関知したら、通知が送られる。サービスは、SentinelからRedisのホストリストを受取り、Redisのホストと通常のコミュニケーションをはじめる。
  • Java-Redisのやりとりは、Jedis、PHP用には、Predislibredisを使っている。(JedisでSentinelを使う方法はドキュメント化されていないので、原文のコードを参照ください。)

Sentinelのテスト

下記の懸念があったので、テスト環境でシミュレーションをしてみた。

  • ホスト障害の際、システムは実際にどんな反応をするのか?

    • ドキュメントに記載されているとおりに振る舞う。今後、自動化した結合テストを実施するために、MavenのテストフェーズにRedisを追加する予定。
  • 復旧のプロセスはどれくらいかかるのか?

    • 3,100msのdown-after-milliseconds値に加えて、復旧イベントの処理と新しいRedisマスターの昇格で、1-3秒かかる。トータルで、4-6秒程度のダウンタイム。
  • ネットワークパーティションが分かれたときのリスクはどれくらいあるのか?

    • “split brainシナリオ” と呼ばれているのは、ネットワーク接続が分割され、それぞれのエリアでノードが独立して動いている状態(概念図)。データセットが分割されて、それぞれのエリアでマスターに書込まれると、整合性をとるのが困難なデータができてしまう可能性がある。
    • 実験してみると、Sentinelはパーティションがなくなると、任意(という風に見える)の側を新しいマスターとして残し、もう一つのマスターに分割後書込まれたデータを失う。
    • デプロイにおけるあらゆる障害の可能性を考慮してみたが、Flickrの本番環境だと、”split brain” になる可能性はあれど、それが発生するリスクはそれほど高くなく、Sentinelを採用するメリットの方が大きいと判断した。
  • 障害復旧プロセスで、どれほどデータを損失する可能性があるのか?

    • 4-6分のダウンタイムはあれど、バックアップとリトライのロジックを絡めると、99.9995%以上の稼働は達成できると判断している。

本番環境への投入

  • 本番投入後、Redisマスターとつながったネットワークスィッチの障害で、マスターの自動復旧が実際に作動した。失敗したタスクは、計270本だが、全てログにとらえることができた。毎日数百万本のタスクを実行している中で、1日だけ270本失敗ということなので、99.999%の実行目標は達成できるペースは続いている。
  • Sentinelが誤った “subjective down” を送ってくることがある。(ステップとしては、”subjective down” の後に ”objective down” がくると障害となる。)Sentinelのインスタンスが他のサービスとホストを共有しているが、負荷が高いと、Sentinelがpingを送受信するのに影響がでていると思われる。level-of-agreementの設定値が高いので、Flickrの場合は、最終的には問題にはならないが、ホストを共有する場合は同じことが起きる可能性があるので、注意されたし。

#flickr #redis

Back