分散環境でどうなるかはテストしてみないとわからない

https://www.youtube.com/watch?v=QdkS6ZjeR7Q

1 comment | 2 points | by WazanovaNews 約3年前 edited


Jshiike 約3年前 edited | ▲upvoteする | link

Kyle Kingsburyは、「クラウドにおいてもネットワークパーティションは起こりうるゆえに、DBなどのプロダクトはマニュアルやマーケティング資料で説明している仕様 & パフォーマンスを、分散環境では必ずしもだせない。」というテーマでの検証結果を公表しているブログのシリーズと、ストレス下での計測ツールJepsenで知られています。ここ1年半ほどで、

  • PostgreSQL / Redis / MongoDB / Riak / Zookeeper / NuoDB / Kafka / Cassandra / Redis / RabbitMQ / etcd / Consul / Elasticsearch

などが紹介されているので、ご興味あれば確認ください。これはKyleのプライベートの時間でのプロジェクトなのですが、話題になったので今ではComcastがスポンサーになってるようです。

先週のStrange Loop 2014でも講演しています。ちなみにKyleは、ブログも含めて、かなりアグレッシブなスタイルで発言してますが、講演の中で自ら言及しているように、ユースケースによっては指摘のポイントが問題ないケースも当然ありますので、そのあたり割り引いて読む & 見てもらえればと思います。

1) ネットワークパーティションと整合性

  • ネットワークパーティションは、ガベッジコレクタの中断 / セグメンテーション違反 = クラッシュ / ブリッジループ などを引き起こすことがある。EC2だとネットワークパーティションは毎月起こる。
  • 分散環境でのシンクロに起因する遅延は、どの順番で何が実行されるのか不確かにする危険性がある。stale read(readに成功したと返ってくるが、実は変更前の古いデータであるケース)は起こさないで、皆が同じ順のステータスを見れるようにしなくてはいけない。この時間/タイミングの保証はパワフルで、分散環境における整合性のゴールドスタンダードと言える。これがlinearizability。シーケンシャルな整合性(何がどの順番で起きるか合意しているが、いつおきるかまでは定まっていない)でもよい。
  • 例えば、Twitterのユーザ名を変更したときに、キャッシュが正しく動作すれば、新しい名前->古い名前でなく、古い名前->新しい名前の順で処理が進むはず。そうならないケースはserializability(直列化可能性)、つまり、なんらかの順番で実行されることは担保されるが、実行順は期待通りにならない状態。serializabilityの場合も、もしある実行の条件式がかなり複雑であれば、それが制御となり弱い整合性にならないこともありうる。
  • CAP定理: ノード間のデータ複製において、同時に二つの保証を満たすことはできるが、三つを同時に保証することはできない。
    • Consistency(整合性)
    • Availability(可用性)
    • Partition-tolerance(分断耐性)
  • Cはlinearizability。Aは生き残ったノードで全てのリクエストを処理できること。Pは必須。となると、APもしくはCPの選択。完璧なCAを実現すると唱えてる人は自分達が何をやってるのかわかってない。
  • 弱い整合性モデルは障害の際にもっと可用性がだせるが、何が起きてるか直感的にわかりづらい。また、コーディネーションの負担が少ないので、スピードが早い。この場合の「弱い」というのは「安全でない」と同義ではない。CRDTのように順不同でもオペレーションの結果が保持されれば安全というケースもある。
  • Jepsenで、DB自動化 / テスト / 障害シミュレーション / スケジューリング / オペレーション履歴の記録をし、Knossosでlinearizabilityを確認する。

2) RabitMQ

  • 障害耐性を担保するために、キューはlinearizabilityを犠牲にする仕様。当然キューにとってはよい。
  • しかし、ネットワークパーティションのケースで、生き残ったノードにおいて35%のacknowledged messagesがロスト。
  • RabitMQ側で改善対応中だが、その間利用する際の留意点は、
    • パーティションモードは、”ignore”を使うこと。自動復旧ができなくなるのでマニュアル操作が必要となる。
    • mutexとしては使わない。
    • shovelは単一障害ポイントになる。

3) etcd

  • 競合状態になることがある。joinをしたときに、プライマリのノードがハングする。etcdのチームはレスがよいので、もう修正済かも。
  • etcdのベースであるRaftはコミットしたログエントリがlinearizableであることを保証してくれるが、etcdの「整合性」readはRaftのログでなく、現在のプライマリのステートを読込んで、返すので、古い情報を読む可能性があった。
  • Consulにも同様の問題があったが、LeaderLeaseTimeoutの修正で対処した。リアルタイムでないシステムにおけるタイムアウトは、正当性を保証できない。もちろんクラウドでも。
  • しかし、最終的にetcd も Consulも、こちらの指摘事項を受け止め、linearizable readをサポートするようになった。

4) Elasticsearch

  • 2010年の段階で、Parition-torelance(分断耐性)を諦めている。
  • クラスタステイタスのエンドポイントは正しい状況を伝えない。ノードがredでもgreenを返す。クラスタがトランジションする際は、短い間、書込みがロストする。
  • ネットワークパーティションでは両側にブリッジするノードがでるケースがあるが、その場合、Elasticsearchは、両側がマジョリティを占めていると判断し、二つのプライマリが存在するようになる。(チケットがクローズになったのでもう修正されたか?)
  • 完全なパーティションにしても、シングルノードでも、いずれにしてもロストする。複数の本番利用ケースでも起きている。ノードのリブート、シャードのリバランスでもロストする。
  • Elasticsearch側は、シングルノードの改善にまずフォーカスしている。Zookeeperプラグインを修復して、利用するべきではないか。
  • Elasticsearchを使う時はプライマリのデータ保管場所は別途用意して、定期的に同期をとること。

5) まとめ

  • 自分のシステムが安全かどうか自問してみる。
    • ランタイム/GCが中断したらどうなるか?
    • ネットワークが遅くなったらどうなるか?
    • 一方通行/部分的なネットワークパーティションになったらどうなるか?
  • タイムスタンプとタイムアウトで実現できることをよく理解する。
  • クライアントも分散システムの一部である。
  • ステートトランジションはクリティカルなインパクトを与えるので熟考すること
  • どれだけの安全性が必要か?そもそも、データロスや不整合とか問題ないユースケースも当然ある。複雑さと正確性の担保のバランス。
  • iptableで本番環境の障害をシミュレーションし、結果を記録する。
  • 障害時のテストがされてないシステムが多い。素晴らしいデザインのシステムがネットワークパーティション時にどうなるか見てみるとよい。とにかくまずテストしてみること。

#jepsen #rabbitmq #etcd #consul #elasticsearch


ワザノバTop200アクセスランキング


Back