|
導入 Netflixのオープンソース製品であるEurekaは、サービス登録と検出機能に加え、対応するJavaラッパーを提供します。Eurekaの実装では、ノードは平等に扱われるため、一部のレジストリノードに障害が発生してもクラスター全体に影響を与えることはありません。たとえ1つのノードだけが稼働している場合でも、検出サービスは正常に提供されます。すべてのサービス登録ノードに障害が発生した場合でも、Eurekaクライアントはサービス呼び出し情報をキャッシュします。これにより、堅牢なサービス間通信が確保されます。
ZooKeeperは、大規模分散コンピューティング向けに、オープンソースの分散構成、同期、および命名登録サービスを提供しています。以前はHadoopプロジェクトのサブプロジェクトとしてクラスタ内のデータ管理に使用されていましたが、現在は独立したトップレベルプロジェクトにアップグレードされています。また、サービス検出ソリューションとしても多くのシナリオで利用されています。 対比 分散システムには、よく知られた CAP 定理があります (C - データの一貫性、A - サービスの可用性、P - ネットワーク分割障害に対するサービスの許容度。これらの 3 つの特性は、どの分散システムでも同時に満たすことはできず、最大で 2 つを同時に満たすことができます)。 動物園の飼育員 ZooKeeperはCP(一貫性、互換性、信頼性)に基づいて設計されており、ZooKeeperへのアクセス要求はいつでも一貫したデータ結果を返します。また、システムはネットワーク分断に対するフォールトトレランスを備えています。ただし、すべてのサービス要求の可用性を保証することはできません。具体的には、ZooKeeperを使用してサービスリストを取得する際、ZooKeeperがリーダーを選出中の場合、またはZooKeeperクラスタ内のマシンの半数以上が利用できない場合、データは取得されません。したがって、ZooKeeperはサービスの可用性を保証できません。 確かに、ほとんどの分散環境、特にデータストレージが関係する環境では、データの一貫性が第一の保証となるはずです。そのため、ZooKeeper は一貫性 (CP) を考慮して設計されています。しかし、サービス検出のシナリオでは状況が異なります。同じサービスであっても、レジストリ内の異なるノードが異なるサービスプロバイダー情報を保存していても、壊滅的な結果にはなりません。これは、サービスコンシューマーにとって、消費能力が最も重要であるためです。サービスインスタンス情報が誤っている可能性がある場合でも、インスタンス情報を取得できないためにまったく消費しないよりも、消費を試みる方が賢明です。(試行することで、すぐに失敗し、その後、構成の更新と再試行が可能になります。) したがって、サービス検出では、データの一貫性よりも可用性が重要であり、可用性 (AP) は一貫性 (CP) よりも優先されます。 ユーレカ Spring Cloud Netflixは、Eurekaの設計においてAP(Availability, Pay-Per-Click)原則を遵守しました。Eureka Serverは、複数のインスタンスを実行してクラスタを構築し、単一障害点に対処することもできます。ただし、ZooKeeperのリーダー選出プロセスとは異なり、Eureka Serverはピアツーピア通信を使用します。これは、マスター/スレーブの区別がなく、各ピアが対等である分散アーキテクチャです。このアーキテクチャでは、ノードは相互に登録することで可用性を向上させます。各ノードは、他のノードを指す有効なサービスURLを1つ以上追加する必要があります。各ノードは、他のノードのレプリカと考えることができます。 Eurekaサーバーがダウンした場合、Eurekaクライアントからのリクエストは自動的に新しいEurekaサーバーノードに切り替えられます。ダウンしたサーバーが回復すると、Eurekaはそれをサーバークラスターに再統合します。ノードがクライアントリクエストの受け入れを開始すると、すべての操作はreplicateToPeer操作を実行し、Eurekaサーバーが認識している他のすべてのノードにリクエストを複製します。 新しいEureka Serverノードが起動すると、まず隣接するノードからすべてのインスタンスレジストリ情報を取得して初期化を完了しようとします。Eureka Serverは`getEurekaServiceUrls()`メソッドを使用してすべてのノードを取得し、ハートビート更新によって定期的に更新します。デフォルトでは、Eureka Serverが一定時間内(デフォルトは90秒、`eureka.instance.lease-expiration-duration-in-seconds`で設定可能)にサービスインスタンスからハートビートを受信しない場合、Eureka Serverはそのインスタンスを登録解除します。Eureka Serverノードが短期間にハートビートを過度に失った場合(例:ネットワークパーティション障害)、ノードは自己保護モードに入ります。 自己保存モードとは何ですか?デフォルトでは、Eureka Serverが1分間に受信するハートビート更新数が、15分間にわたってしきい値(インスタンス数 * (60 / インスタンスあたりのハートビート間隔(秒) * 自己保存係数)を下回ると、自己保存がトリガーされます。自己保存モードでは、Eureka Serverはサービスレジストリ内の情報を保護し、サービスインスタンスを登録解除しません。受信するハートビート数がしきい値を超えると、Eureka Serverノードは自動的に自己保存モードを終了します。前述のように、その設計理念は、潜在的に正常なサービスインスタンスを盲目的に登録解除するのではなく、誤ったサービス登録情報を保持することです。このモードは `eureka.server.enable-self-preservation = false` を使用して無効にできます。また、`eureka.instance.lease-renewal-interval-in-seconds` を使用してハートビート間隔を変更し、`eureka.server.renewal-percent-threshold` を使用して自己保存係数 (デフォルト 0.85) を変更できます。 要約 ZooKeeperは一貫性(CP)に基づいており、高可用性を保証しません。ZooKeeperがリーダーを選出している場合、またはZooKeeperクラスタ内のマシンの過半数が利用できない場合、データは利用できなくなります。一方、Eurekaはアクセシビリティ(AP)に基づいており、高可用性を保証します。すべてのマシンに障害が発生した場合でも、ローカルにキャッシュされたデータは引き続き取得できます。レジストリセンターとして、その構成は頻繁に変更されず、リリース時やマシン障害時のみ変更されます。頻繁に変更されない構成の場合、CPは適していません。一方、APは問題発生時に可用性を確保するために一貫性を犠牲にすることがあります。つまり、古いデータを返したり、データをキャッシュしたりします。 したがって、理論的にはEurekaの方がレジストリセンターとして適していると言えるでしょう。しかし、実際の環境では、クラスタサイズが不足し、レジストリセンターとして使用しているマシンの半数以上が故障するような状況に遭遇することは稀であるため、多くのプロジェクトではZooKeeperが使用されるでしょう。そのため、実際には大きな問題は発生しません。 |