1. 概要

GemFire は、アプリケーションクラスターとバックエンドデータソースの間に位置する高性能の分散データ管理インフラストラクチャです。

GemFireを使用すると、データをメモリ内で管理できるため、アクセスが高速になります。 Spring Dataは、SpringアプリケーションからGemFireへの簡単な構成とアクセスを提供します。

この記事では、GemFireを使用してアプリケーションのキャッシュ要件を満たす方法を見ていきます。

2. Mavenの依存関係

Spring Data GemFireのサポートを利用するには、最初に pom.xmlに次の依存関係を追加する必要があります:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-gemfire</artifactId>
    <version>1.9.1.RELEASE</version>
</dependency>

この依存関係の最新バージョンは、ここにあります。

3. GemFireの基本機能

3.1. キャッシュ

GemFireのキャッシュは、重要なデータ管理サービスを提供するだけでなく、他のピアへの接続を管理します。

キャッシュ構成( cache.xml )は、データがさまざまなノード間でどのように分散されるかを記述します。

<cache>
    <region name="region">
        <region-attributes>
            <cache-listener>
                <class-name>
                ...
                </class-name>
            </cache-listener>
        </region-attributes>
    </region>
    ...
</cache>

3.2. 地域

データ領域は、単一のデータセットのキャッシュ内の論理グループです。

簡単に言うと、リージョンを使用すると、クラスター内のどのノードにデータが保存されているかを考慮せずに、システムの複数のVMにデータを保存できます。

地域は大きく3つのカテゴリに分類されます。

  • 複製領域は、各ノードのデータの完全なセットを保持します。 高い読み取りパフォーマンスが得られます。 データの更新を各ノードに伝播する必要があるため、書き込み操作は遅くなります。
    <region name="myRegion" refid="REPLICATE"/>
  • パーティション化された領域は、各ノードが領域の内容の一部のみを格納するようにデータを分散します。 データのコピーは、他のノードの1つに保存されます。 優れた書き込みパフォーマンスを提供します。
    <region name="myRegion" refid="PARTITION"/>
  • ローカル領域は定義メンバーノードに存在します。 クラスタ内の他のノードとの接続はありません。
    <region name="myRegion" refid="LOCAL"/>

3.3. キャッシュを照会する

GemFireは、GemFireデータ領域に格納されているオブジェクトを参照できるOQL(オブジェクトクエリ言語)と呼ばれるクエリ言語を提供します。 これは、構文のSQLと非常によく似ています。 非常に基本的なクエリがどのように見えるかを見てみましょう。

SELECT DISTINCT * FROM exampleRegion

GemFireのQueryServiceは、クエリオブジェクトを作成するためのメソッドを提供します。

3.4. データのシリアル化

データのシリアル化と逆シリアル化を管理するために、GemFireは、Javaシリアル化以外のオプションを提供します。これにより、パフォーマンスが向上し、データストレージとデータ転送の柔軟性が高まり、さまざまな言語もサポートされます。

そのことを念頭に置いて、GemFireはPortable Data eXchange(PDX)データ形式を定義しました。 PDXは、オブジェクトを完全に逆シリアル化する必要なしに直接アクセスできる名前付きフィールドにデータを格納することにより、より高速なシリアル化と逆シリアル化を提供する言語間データ形式です。

3.5. 関数の実行

GemFireでは、関数をサーバーに常駐させ、関数コード自体を送信しなくても、クライアントアプリケーションまたは別のサーバーから呼び出すことができます。

呼び出し元は、データ依存関数に特定のデータセットを操作するように指示したり、独立したデータ関数を特定のサーバー、メンバー、またはメンバーグループで操作したりすることができます。

3.6. 継続的なクエリ

継続的なクエリでは、クライアントはSQLタイプのクエリフィルタリングを使用してサーバー側のイベントをサブスクライブします。 サーバーは、クエリ結果を変更するすべてのイベントを送信します。 継続的なクエリイベント配信は、クライアント/サーバーサブスクリプションフレームワークを使用します。

連続クエリの構文は、OQLで記述された基本的なクエリに似ています。 たとえば、Stockリージョンの最新の株式データを提供するクエリは次のように記述できます。

SELECT * from StockRegion s where s.stockStatus='active';

このクエリからステータスの更新を取得するには、 CQListenerの実装をStockRegion:にアタッチする必要があります。

<cache>
    <region name="StockRegion>
        <region-attributes refid="REPLICATE">
            ...
            <cache-listener>
                <class-name>...</class-name>
            </cache-listener>
        ...
        </region-attributes>
    </region>
</cache>

4. SpringDataGemFireのサポート

4.1. Java構成

構成を簡素化するために、SpringDataGemFireはコアGemFireコンポーネントを構成するためのさまざまなアノテーションを提供します。

@Configuration
public class GemfireConfiguration {

    @Bean
    Properties gemfireProperties() {
        Properties gemfireProperties = new Properties();
        gemfireProperties.setProperty("name","SpringDataGemFireApplication");
        gemfireProperties.setProperty("mcast-port", "0");
        gemfireProperties.setProperty("log-level", "config");
        return gemfireProperties;
    }

    @Bean
    CacheFactoryBean gemfireCache() {
        CacheFactoryBean gemfireCache = new CacheFactoryBean();
        gemfireCache.setClose(true);
        gemfireCache.setProperties(gemfireProperties());
        return gemfireCache;
    }

    @Bean(name="employee")
    LocalRegionFactoryBean<String, Employee> getEmployee(final GemFireCache cache) {
        LocalRegionFactoryBean<String, Employee> employeeRegion = new LocalRegionFactoryBean();
        employeeRegion.setCache(cache);
        employeeRegion.setName("employee");
        // ...
        return employeeRegion;
    }
}

GemFireのキャッシュとリージョンを設定するには、最初にいくつかの特定のプロパティを設定する必要があります。 ここでは、 mcast-port がゼロに設定されています。これは、このGemFireノードがマルチキャストの検出と配信に対して無効になっていることを示します。 次に、これらのプロパティが CacheFactoryBean に渡され、GemFireCacheインスタンスが作成されます。

GemFireCache beanを使用して、Employeeインスタンスのキャッシュ内の領域を表すLocalRegionFatcoryBeanのインスタンスが作成されます。

4.2. エンティティマッピング

ライブラリは、GemFireグリッドに保存されるオブジェクトをマップするためのサポートを提供します。 マッピングメタデータは、ドメインクラスでアノテーションを使用して定義されます。

@Region("employee")
public class Employee {

    @Id
    public String name;
    public double salary;

    @PersistenceConstructor
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    // standard getters/setters
}

上記の例では、次のアノテーションを使用しました。

  • @ Region、は、Employeeクラスのリージョンインスタンスを指定します
  • @Id、キャッシュキーとして使用されるプロパティに注釈を付ける
  • @PersistenceConstructor これは、複数のコンストラクターが使用可能な場合に、エンティティの作成に使用される1つのコンストラクターをマークするのに役立ちます

4.3. GemFireリポジトリ

次に、Springデータの中心的なコンポーネントであるリポジトリを見てみましょう。

@Configuration
@EnableGemfireRepositories(basePackages
  = "com.baeldung.spring.data.gemfire.repository")
public class GemfireConfiguration {

    @Autowired
    EmployeeRepository employeeRepository;
    
    // ...
}

4.4. Oqlクエリのサポート

リポジトリを使用すると、クエリメソッドを定義して、管理対象エンティティがマップされているリージョンに対してOQLクエリを効率的に実行できます。

@Repository
public interface EmployeeRepository extends   
  CrudRepository<Employee, String> {

    Employee findByName(String name);

    Iterable<Employee> findBySalaryGreaterThan(double salary);

    Iterable<Employee> findBySalaryLessThan(double salary);

    Iterable<Employee> 
      findBySalaryGreaterThanAndSalaryLessThan(double salary1, double salary2);
}

4.5. 関数実行のサポート

GemFire関数の実行を簡素化するために、アノテーションのサポートも利用できます。

関数を使用する場合、実装と実行の2つの懸念事項に対処する必要があります。

Springデータアノテーションを使用して、POJOをGemFire関数として公開する方法を見てみましょう。

@Component
public class FunctionImpl {

    @GemfireFunction
    public void greeting(String message){
        // some logic
    }
 
    // ...
}

@GemfireFunction が機能するには、注釈処理を明示的にアクティブ化する必要があります。

@Configuration
@EnableGemfireFunctions
public class GemfireConfiguration {
    // ...
}

関数を実行する場合、リモート関数を呼び出すプロセスは、呼び出し引数、関数 id 、実行ターゲット( onServer onRegion onMember)を提供する必要があります。 など):

@OnRegion(region="employee")
public interface FunctionExecution {
 
    @FunctionId("greeting")
    public void execute(String message);
    
    // ...
}

関数実行アノテーション処理を有効にするには、Springのコンポーネントスキャン機能を使用してアクティブ化するために追加する必要があります。

@Configuration
@EnableGemfireFunctionExecutions(
  basePackages = "com.baeldung.spring.data.gemfire.function")
public class GemfireConfiguration {
    // ...
}

5. 結論

この記事では、GemFireの重要な機能を調査し、SpringDataが提供するAPIを使用してGemFireを簡単に操作できるようにする方法を検討しました。

この記事の完全なコードは、GitHubから入手できます。