2

RegionShortcut.PARTITION と setRedundantCopies(1) を使用して GemFire リージョンを定義しました。3 つの異なる VM で実行されている 3 つのアプリケーションが、これらのリージョンを利用しています。

アイテムをキャッシュに挿入したばかりのアプリケーション (アイテムの「所有者」) の VM をシャットダウンしているときに、デッドロックが発生したようです。

*ブロックされたプロセス: region.put の前にブロックされました。

*ブロッキング プロセス: リージョンから古いエントリを削除しようとした後、ブロックされたようです。この操作は、CacheListenerAdapter によって提供される破棄メカニズムによって呼び出されると思われます。

次のリンクでこの問題に関するいくつかのドキュメントを読みました: CacheListener Interface APIおよびこのブログでは、主にリスナーの使用法が原因であることがわかりました。

それでも、この問題は GemFire 6.x バージョンで対処および修正されたようです [例:ここここ]

だから、私は尋ねたい:

1) この問題は Gemfire 8 で報告されていますか? または7?

2) この問題の推奨される回避策は何ですか? ここでは、3 つの異なる回避策について説明します。他にもありますか?好ましいものはありますか?

参考までに、ブロッキング プロセスのスレッド ダンプは次のとおりです。

Owner stack trace: java.lang.Throwable
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.park(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
    at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lockInterruptibly(Unknown Source)
    at com.gemstone.gemfire.internal.cache.BucketRegion.lockPrimaryStateReadLock(BucketRegion.java:780)
    at com.gemstone.gemfire.internal.cache.BucketRegion.doLockForPrimary(BucketRegion.java:719)
    at com.gemstone.gemfire.internal.cache.BucketRegion.beginLocalWrite(BucketRegion.java:704)
    at com.gemstone.gemfire.internal.cache.BucketRegion.basicDestroy(BucketRegion.java:1105)
    at com.gemstone.gemfire.internal.cache.PartitionedRegionDataStore.destroyLocally(PartitionedRegionDataStore.java:1511)
    at com.gemstone.gemfire.internal.cache.PartitionedRegion.destroyInBucket(PartitionedRegion.java:5440)
    at com.gemstone.gemfire.internal.cache.PartitionedRegionDataView.destroyExistingEntry(PartitionedRegionDataView.java:45)
    at com.gemstone.gemfire.internal.cache.PartitionedRegion.basicDestroy(PartitionedRegion.java:5317)
    at com.gemstone.gemfire.internal.cache.LocalRegion.validatedDestroy(LocalRegion.java:1330)
    at com.gemstone.gemfire.internal.cache.LocalRegion.destroy(LocalRegion.java:1317)
    at com.gemstone.gemfire.internal.cache.AbstractRegion.destroy(AbstractRegion.java:282)
    at com.gemstone.gemfire.internal.cache.LocalRegion.remove(LocalRegion.java:9513)
4

1 に答える 1

1

CacheListeners が関係するデッドロックが発生する可能性があります。この動作は、最新 (GemFire 8.1) の javadoc に記載されています。CacheListener ドキュメントからの関連する抜粋を次に示します。

デッドロックのリスクを回避する

CacheListener のメソッドは、EntryEvent で記述されたエントリのロックを保持しながら呼び出されます。その結果、リスナー メソッドの実行に時間がかかると、呼び出し元の操作に時間がかかります。さらに、Region メソッドを呼び出すリスナー コードは、デッドロックを引き起こす可能性があります。たとえば、エントリ キー k1 の afterUpdate(EntryEvent) で、put(k2, someVal) が呼び出されると同時に、エントリ キー k2 の afterUpdate(EntryEvent) が put(k1, someVal) を呼び出すと、デッドロックが発生する可能性があります。この co-key 依存関係の例は、リージョン "A" のリスナー コードが "B" でリージョン操作を実行し、リージョン "B" のリスナー コードが "A" でリージョン操作を実行する、co-Region 依存関係に拡張できます。デッドロックは、リージョンの構成に応じて、Java レベルまたは分散マルチ VM デッドロックのいずれかになります。デッドロックが発生しないようにするには、リスナー コードで他のスレッドが領域にアクセスするようにし、そのスレッドがタスクを完了するまで待機しないようにする必要があります。

于 2015-06-30T18:44:23.713 に答える