私は現在高負荷の下で私たちのプロジェクトで発生する以下の問題を、研究しています:要するにApache Igniteでのピアクラスローディングはどのように機能しますか?
class org.apache.ignite.IgniteDeploymentException: Failed to deploy user message: java.nio.HeapByteBuffer[pos=0 lim=180 cap=180]
at org.apache.ignite.internal.util.IgniteUtils$8.apply(IgniteUtils.java:825)
at org.apache.ignite.internal.util.IgniteUtils$8.apply(IgniteUtils.java:823)
at org.apache.ignite.internal.util.IgniteUtils.convertException(IgniteUtils.java:944)
at org.apache.ignite.internal.IgniteMessagingImpl.send0(IgniteMessagingImpl.java:106)
at org.apache.ignite.internal.IgniteMessagingImpl.send(IgniteMessagingImpl.java:82)
...
Caused by: class org.apache.ignite.internal.IgniteDeploymentCheckedException: Failed to deploy user message: java.nio.HeapByteBuffer[pos=0 lim=180 cap=180]
at org.apache.ignite.internal.managers.communication.GridIoManager.sendUserMessage(GridIoManager.java:1571)
at org.apache.ignite.internal.IgniteMessagingImpl.send0(IgniteMessagingImpl.java:103)
... 25 more
、次のようにケースがある:
- は3つのノード、すべてのノードでキャッシュを分散単一のワークステーションで実行します(このテストでは)。
- 各ノードのワーカー。
- IgniteMessagingを使用して作業者間のメッセージングを行います(トピックにはString型があり、メッセージクラスとしてbyte []とByteBufferの両方を試しました)。
- クライアントはクラスタに接続し、クロスノードメッセージングとスキャンクエリの原因となるビジネスロジックをトリガします。クエリとメッセージングは同時に実行されます。
ピア展開は連続展開モードで行います(この問題は共有モードと同じです)。 Igniteのドキュメントによれば、バージョンが変更された場合にのみクラスを再デプロイする必要がありますが、動作していないようです。
私がログに同様のメッセージをたくさん気づいた:私はメッセージタイプとしてのByteBufferを使用する場合
2017-05-05 13:31:28 INFO org.apache.ignite.logger.java.JavaLogger info Removed undeployed class: GridDeployment [ts=1493980288578, depMode=CONTINUOUS, [email protected], clsLdrId=36c3828db51-0d65e7d5-77bf-444d-9b8b-d18bde94ad13, userVer=0, loc=true, sampleClsName=java.lang.String, pendingUndeploy=false, undeployed=true, usage=0]
...
2017-05-05 13:31:29 INFO org.apache.ignite.logger.java.JavaLogger info Removed undeployed class: GridDeployment [ts=1493980289125, depMode=CONTINUOUS, [email protected], clsLdrId=1dd3828db51-1b20df7a-a98d-45a3-8ab6-e5d229945830, userVer=0, loc=true, sampleClsName=java.lang.String, pendingUndeploy=false, undeployed=true, usage=0]
...
これがあります。 byte []の場合、クラスBは常に再配置されています。
私はIgniteカーネルを少し解析し、クラスローダー内のすべてのクラスに対して、そのクラスローダーに存在する少なくとも1つのクラスが他のローダーに再配置されたときに、アンデプロイがトリガーされている疑いがあります。
それは最初にorg.apache.ignite.spi.deployment.local.LocalDeploymentSpi番号レジスタ
- 内部で起こる、我々はLocalDeploymentSpi#addResourceを使用して「登録クラス ローダーのために追加された新しいリソースのマップ」を取得します。
- 次に、「ignoreClsLdrを除くすべてのクラスローダーのリソースを削除します」。 LocalDeploymentSpi#removeResourcesを使用します。このメソッドの内部では、新しいリソースの古いバージョンを含むすべてのローダーを「運命の」コレクションに追加するように見えます。
- 最後に、このコレクションを反復し、各要素に対してonClassLoaderReleasedを呼び出します。後者のアクションでは、実際にはすべてのクラスがアンデプロイされます(最後に、「アンデプロイされたクラスの削除」メッセージが表示されます)。
私はこの概念を理解していません。なぜ複数のクラスローダーがありますか?なぜこのような場合にクラスローダー全体をアンデプロイするのですか?
誰かが説明できるのであれば、Igniteの "Under the Hood"でピアクラスローディングがどのように機能するのでしょうかと感謝します。
P.S. Ignite 2.1.0の新しいスナップショットのソースを見ていますが、動作はIgnite 1.9.0の標準と同じです。