Hadoopサービスレジストリは、さまざまな方法で使用できます。
レジストリのユーザーは、エントリ(サービスレコード)のパブリッシャーと、サービスレコードを介して場所が特定された他のサービスのコンシューマーの両方になる可能性があります。分散アプリケーションの異なる部分も、異なる目的で使用する場合があります。例として、YARNアプリケーションのアプリケーションマスターは、ワーカーコンテナで使用するためにバインディングを公開できます。コンテナで実行されているコードは、クラスター内の異なるノードで再起動された場合でも、そのマネージャーと通信するためのバインディングを検索できます。クライアントアプリケーションは、パブリックAPIを介してAMと対話するための外部サービスエンドポイントを検索できます。
レジストリは次の目的では使用できません。
yarn:persistence = "application_attempt" yarn:id = ${application_attemptId}
これは、新しい試行が作成された場合でも、アプリケーション試行が完了するとレコードが削除されることを意味します。すべてのアプリケーション試行は、エンドポイントを再登録する必要があります(いずれにせよ、サービスの場所を特定する必要がある場合があります)。
yarn:persistence = "application_attempt" yarn:id = application_attemptId
これは、エンドポイント情報が古い場合でも、アプリケーション試行の間でもレコードが永続化されることを意味します。
パスの選択は、アプリケーション固有のものです。一意であることが保証されているYARNアプリケーション名を持つサービスの場合、次の規則をお勧めします。
/users/${username}/applications/${service-class}/${instance-name}
または、アプリケーションIDをパスで使用できます。
/users/${username}/applications/${service-class}/${applicationId}
後者を使用すると、YARNアプリケーションリストのエントリをサービスレコードに簡単にマッピングできます。
クライアントアプリケーションはサービスを検索できます
サービスレコードの場所を特定した後、クライアントは外部
バインディングを列挙し、目的のAPIを持つエントリを見つけることができます。
ここでは、YARNアプリケーションのすべてのコンテナが、一般に公開するためにサービスエンドポイントを公開しています。
id:password
ペアが渡される必要があります。これにより、コンテナは、AMにレジストリパスへの書き込みアクセスを許可するユーザートークンの有効期限が切れた後でも、エントリを更新できます。id:password
ペアを使用してレジストリ操作インスタンスをインスタンス化します。${base-path} + "/" + RegistryPathUtils.encodeYarnID(containerId)
このレコードには、コンテナの永続化ポリシーとコンテナのIDが必要です。
yarn:persistence = "container" yarn:id = containerId
コンテナが終了すると、エントリは自動的に削除されます。
このコンテナデプロイサービスの公開されたサービスエンドポイントは、サービスレコードの外部
エンドポイントリストにリストする必要があります。
${base-path}
の下のエントリをリストすることにより、YARNアプリケーションによってエクスポートされたすべてのコンテナを列挙できます。クラスターで一般的に固定されているが、バインディングと構成情報を公開する必要があるサービスは、レジストリに公開できます。例:Apache Oozieサービス。デプロイされたアプリケーションが公開できるクラスターの外部のサービス。例:Amazon Dynamoインスタンス。
これらのサービスは、/users/oozie
や/users/hbase
など、サービスを実行しているユーザーに属するパスに登録できます。クライアントアプリケーションはこのパスを使用します。これにより、サービスレコードの有効性を認証できますが、クライアントアプリケーションがサービスがデプロイされているユーザー名を知っているか、完全なパスで構成されている必要があります。
別の方法は、サービスが/services
の下の静的サービスパスにデプロイされることです。たとえば、/services/oozie
にはOozieサービスの登録を含めることができます。このパスのアクセス許可は事前構成されたシステムアカウントに制限されているため、セキュアクラスター上のこのパスのサービス登録の存在は、クラスター管理ツールによって登録されたことを確認します。
/services
の下に登録される場合、システムユーザーアカウントのいずれかによってデプロイされている場合は、自身を直接登録できます。ここで、YARNコンテナは、作業を受け取るためにAMに登録します。通常は、定期的にレポートするハートビートメカニズムによって行われます。AMがアプリケーションの試行よりも長くコンテナが存続するように構成されている場合、AMが失敗してもコンテナは実行を続けます。これらのコンテナは、再起動されたAMにバインドする必要があります。また、AMが再起動しない場合は、最終的にタイムアウトして自身を終了する必要があると結論付けたい場合があります。このようなポリシーは、アプリケーションがネットワークパーティションに対応するのに役立ちます。
internal
エンドポイントリストに、コンテナが使用する特定のAPIのURLに設定されたapi
フィールドとともに公開されます。ps
コマンドで表示できます。より安全なのは、共有シークレットをクラスターファイルシステムに保存し、そのパスをコンテナに渡すことです。そのようなパスへのURIは、アプリケーションの登録された内部エンドポイントの1つである可能性があります。管理ポートとバインディングは、公開する他のエンドポイントにすぎません。これらは、一般公開を目的としていないため、internalエンドポイントとして公開する必要があります。
クライアントアプリケーションは、"classpath://org.apache.hbase"
のような特定のAPIを実装するすべてのサービスを特定したいと考えています。
registryOperations.list(path)
を呼び出して、そのパスの直下にあるすべてのノードをリストし、子ノードの相対リストを取得します。stat()
を呼び出して、子レコードのステータスを列挙します。ServiceRecordHeader.getLength()
の値よりも大きい場合、サービスレコードが含まれている可能性があります。resolve()
操作を使用して取得できます。成功した場合、サービスレコードが含まれています。したがって、クライアントはexternal
エンドポイントを列挙し、目的のAPIを持つエンドポイントを見つけることができます。RegistryPathStatus
ステータスエントリのchildren
フィールドを調べます。それが >= 0 の場合、そのエントリのパスで列挙を再帰的に実行する必要があります。このアルゴリズムは、レジストリツリーの深さ優先探索を記述しています。もちろん、幅優先探索や、単一のエントリポイントが見つかるとすぐに検索を停止するなど、バリエーションも可能です。また、異なるサブツリーの並列検索というオプションもあります。これにより検索時間を短縮できますが、レジストリインフラストラクチャに対するクライアントの負荷が高くなります。
ユーティリティクラスRegistryUtils
は、共通のレジストリ操作用の静的ユーティリティメソッドを提供します。特に、RegistryUtils.listServiceRecords(registryOperations, path)
は、指定されたパスのすべての子レコードエントリのリストと収集を実行します。
クライアントアプリケーションは、「エンドポイントが無効な場合」、具体的には、サービスが実行されていない場合はどうするかという問題に直面します。
一部のトランスポートは、停止は一時的なものであり、元のバインディングに対してスピン再試行を行うことが正しい戦略であると想定しています。これは、Hadoop IPCクライアントのデフォルトポリシーです。
他のトランスポートは、例外やその他のメカニズムを介して、失敗をすぐに報告します。これはクライアントに直接表示されますが、クライアントがレジストリを再スキャンしてアプリケーションに再バインドできます。
最後に、一部のアプリケーションは当初から動的なフェイルオーバー用に設計されています。公開されているバインディング情報は、実際にはzookeeperパスです。Apache HBaseとApache Accumuloがその例です。レジストリはバインディングの最初のルックアップに使用され、その後クライアントは本質的に障害に対して回復力があります。