3

現在、Spring Boot Starter 1.4.2.RELEASE と Geode Core 1.0.0-incubating を Maven を使用して、Geode Locator と 2 つのキャッシュ ノードで構成されるローカル Docker 構成に対して使用しています。

ここでドキュメントを参照しました:

http://geode.apache.org/docs/guide/developing/distributed_regions/locking_in_global_regions.html

次のように、アプリケーションで使用するために cache.xml ファイルを構成しました。

<?xml version="1.0" encoding="UTF-8"?>
<client-cache
        xmlns="http://geode.apache.org/schema/cache"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://geode.apache.org/schema/cache
                        http://geode.apache.org/schema/cache/cache-1.0.xsd"
        version="1.0">
    <pool name="serverPool">
        <locator host="localhost" port="10334"/>
    </pool>
    <region name="testRegion" refid="CACHING_PROXY">
        <region-attributes pool-name="serverPool"
                scope="global"/>
    </region>
</client-cache>

私の Application.java では、次の方法で領域を Bean として公開しました。

@SpringBootApplication
public class Application {

    @Bean
    ClientCache cache() {
        return new ClientCacheFactory()
                .create();
    }

    @Bean
    Region<String, Integer> testRegion(final ClientCache cache) {
        return cache.<String, Integer>getRegion("testRegion");
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

そして、私の「サービス」DistributedCounter.javaで:

@Service
public class DistributedCounter {

@Autowired
private Region<String, Integer> testRegion;

/**
 * Using fine grain lock on modifier.
 * @param counterKey {@link String} containing the key whose value should be incremented.
 */
public void incrementCounter(String counterKey) {
    if(testRegion.getDistributedLock(counterKey).tryLock()) {
        try {
            Integer old = testRegion.get(counterKey);
            if(old == null) {
                old = 0;
            }
            testRegion.put(counterKey, old + 1);
        } finally {
            testRegion.getDistributedLock(counterKey).unlock();
        }
    }
}

私は gfsh を使用して /testRegion という名前のリージョンを構成しました - ただし、そのタイプが「GLOBAL」であることを示すオプションはありません。他のさまざまなオプションしか利用できません - 理想的には、これは永続的で複製されたキャッシュである必要があります。次のコマンド:

create region --name=/testRegion --type=REPLICATE_PERSISTENT

http://geode.apache.org/docs/guide/getting_started/15_minute_quickstart_gfsh.htmlのハウツーを使用する と、2 つのノード構成での永続化とレプリケーションの機能を簡単に確認できます。

ただし、上記の DistributedCounter でのロックはエラーを引き起こしませんが、2 つのプロセスが同じ「キー」でロックを取得しようとすると機能しません。2 番目のプロセスはロックの取得をブロックされません。DistributedLockService を使用する Gemfire フォーラムの以前のコード サンプルがあります。現在のドキュメントでは、リージョン エントリのロックに使用しないよう警告しています。

アトミックにインクリメンタルな long の「マップ」をサポートするためのきめの細かいロックのユースケースはサポートされているユースケースですか? もしそうなら、それを適切に構成する方法は?

4

3 に答える 3

2

これは、サーバー側のコード (関数など) でのみ機能します。

クライアント コードから、"region.putIfAbsent" を使用してロック セマンティクスを実装できます。

2 つ (またはそれ以上) のクライアントが同じリージョンとキーでこの API を呼び出した場合、1 つだけが正常に配置され、null の戻り値で示されます。このクライアントは、ロックを保持していると見なされます。他のクライアントは、勝者が置いたオブジェクトを取得します。「入力」した値にクライアントの一意の識別子が含まれている場合、敗者は誰がロックを保持しているかさえ知っているため、これは便利です。

領域エントリがロックを表すことには、他にも優れた利点があります。ロックは、障害が発生しても存続します。リージョンの有効期限を使用して、ロックの最大リース時間を設定できます。前述のように、誰がロックを保持しているかを簡単に知ることができます。

お役に立てれば。

于 2016-11-28T22:44:45.883 に答える