Tanzu Gemfire アプリケーションのモダナイゼーション

VMware Tanzu GemFire を知ろうシリーズ Part 4: Petclinicを使ったGemfire対応アプリケーション

本シリーズでは、VMware Tanzu Data Serviceの1製品である「VMware Tanzu GemFire」について4回の連載となります。
第一回:GemFireのご紹介と機能性
第二回:Gemfireを仮想マシンへのインストールとREST APIによる操作
第三回:GemFire for Kubernetes のご紹介
第四回:Petclinicを使ったGemfire対応アプリケーション

数回に渡りGemfireを紹介する記事を紹介してまいりました。
この第4回ではより深く理解ということで、実際のアプリケーションを使いながらGemfireを解説したいと思います。

サンプルのアプリケーションとして、Springで有名なPetclinicを使い、かつそれをGemfireに切り替える方法を紹介します。

前提

今回の検証を試すには、最低限以下がインストールされた環境で実施が必要になります。

  • Java 8 (or Java 11)
  • Gemfireをローカルにインストール(厳密にはこの中のgfshツールを使います)

なお、IntellijやEclipseなどより高度なエディタはオプショナルです。Gemfireのローカルのインストールは以下を参照ください。

Windows/Unix/Linux—Install Pivotal GemFire from a Compressed TAR File
Install Pivotal GemFire from a Homebrew Package

PetClinicとは?

まず、Petclinicを簡単に解説します。Spring PetclinicとはコミュニティによってメンテナンスされているSpringのサンプルアプリケーションです。Spring Petclinicは以下の様々なフォーマットで提供されています。

今回は、この中のSpring Bootフォーマットのものを使います。さて、このSpring Bootバージョンでは、Veterinarians(獣医)の一覧を参照する際に、ehcacheによってキャッシングをしています。つまり、初回のクエリはデータベースから問い合わせるものの、二回目以降はキャッシュ領域から参照するような仕組みにしています。以下Petclinicを解説した資料ですが、その中のp7.で触れられています。

 

今回の投稿は、これをehcacheのキャッシュではなく、Gemfireのキャッシュに切り替えたいと思います。図で表すと以下のようです。

コードは筆者が編集したものを使います。

https://github.com/mhoshi-vm/spring-petclinic/tree/gemfire-cache

アプリケーションを起動

まずはアプリケーションを起動してみたいと思います。以下のコマンドでコードをローカルにコピーしてください。

git clone -b gemfire-cache https://github.com/mhoshi-vm/spring-petclinic

その後、ディレクトリーに移動して、アプリケーションの起動を以下で実施してください。

cd spring-petclinic
./mvnw spring-boot:run

しばらくすれば、正常にアプリケーションが起動すると思いますので、以下のURLをアクセスしてみてください。

http://localhost:8080/

以下のようにUIにアクセスできれば、成功です。

Gemfireにアクセス

アプリケーションを起動したら、gfshクライアントツールを使い、Gemfireにアクセスします。以下のコマンドを実行してください。専用のプロンプトが起動されます。

gfsh

プロンプトが起動したら以下のコマンドで、Gemfireにアクセスします。

connect
list members

この中で表示されている「SpringBasedCacheServerApplication」は先ほど起動したPetclinicとともに起動したGemfireのインスタンスです。なおここでは、GemfireのClientCacheという機能を使ってローカルで起動するシンプルなGemfireを使っています。本番環境などでは、外部に構成した専用のGemfireクラスターを構成するべきですが、今回は検証目的なので、あくまでこのままで使用します。

さて、この状態で以下のコマンドを実行します。

query –query=”select * from /vets”

これはOQLという言語で、Gemfire内のデータを参照していますが、スクリーンショットにあるよう、「Rows : 0」とあるように特に、なにもデータがない状態であることが確認できます。

データをキャッシング

ここから実際のデータのキャッシュを発生させたいと思います。Petclinicのアプルに戻りVeterinariansをクリックして、獣医一覧の情報だしてください。

獣医の一覧が表示されたあとにgfshに戻り、以下のコマンドを入力します。

query –query=”select * from /vets”
query –query=”select * from /vets.entrySet”

すると、さきほど「Row : 0」だったものが、「Row : 1」となり、かつ2つ目のコマンドでは実際のデータが格納されていることがわかるかと思います。これによって Gemfireのキャッシングが有効になったことがわかります。

データが本当にキャッシュされているかの検証

本当にキャッシュ領域が参照されているのか確認してみたいと思います。なお、ここからの操作は本来は推奨されない、あくまで検証目的の手順ですのでご注意ください。ここでは、アプリケーションの外部から直接SQLでデータベースを編集した場合になにが起きるか見てみます。

Petclinic起動時はデータはh2と呼ばれるインメモリーデータベースに保管されています。以下のURLでデータベースの管理コンソールに以下にアクセスします。

http://localhost:8080/h2-console

なお、「JDBC URL」にいれる値は編集する必要があります。ここに入れる値は、Petclinic起動のたびに変更されます。Petclinicの起動時のログに以下のようなメッセージが出力されているはずですので、起動ログを参照ください。この中の「jdbc:h2:mem:<起動のたびにかわるID>」を指定してください。それ以外はデフォルトのまま(ユーザー名:sa、パスワードは空)でログインできます。

H2 console available at ‘/h2-console’. Database available at ‘jdbc:h2:mem:9209ec6f-3ca5-44cc-8f2d-a9b32e8a40af’

管理コンソールログイン後、H2データベースにログインして、以下のコマンドを実行します。これは、ID=1の名前を”Hoshino”にを上書きしています。

update vets set LAST_NAME=’Hoshino’ where ID=1

その後、以下のSQLを実行すると、ID=1のユーザーのラストネームが”Hoshino”になっていることがわかります。

select * from vets where ID=1

この状態で、Petclinicの獣医一覧を見てます。するとデータベースの内容とは異なり、データが変更前の状態であることが確認できます。

これは、データベースのデータではなく、キャッシュのデータを参照してしまっているため、更新がされていないために発生する事象です。では、ここで、gfshを使いキャッシュデータを削除したいと思います。gfsh管理コンソールにアクセスをして、以下のコマンドを実行します。

remove –region=/vets –all

その後もう一度、Petclinicの獣医一覧を見てます。すると先ほど異なり、新しく設定した名前であるHoshinoが見えるようになります。これは、Gemfire側でのキャッシュがクリアされたことにより、再度データベースからのキャッシュ取得を実施しているためです。

以上のことからGemfireのキャッシュが有効になっていることと、Gemfireの外からデータを変更した時の影響を確認することができました。

なお、本来では、アプリケーション側にキャッシュへの書き込みロジックを定義する必要がありますが、この獣医一覧はReadOnlyを想定しているものとご理解ください。Gemfireの書き込みについては、以下も参照ください。

Caching 101, Illustrated with Tanzu GemFire

コードの変更箇所

実際のコードの変更箇所は以下に記載されています。(その他、多くのコード変更がふくまれているように見えますが、このデモに関連するのは以下のみです。)

src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.javaの差分

中身の詳細は省きますが、ポイントして、ehcacheで使用していたキャッシングコードをGemfire向けに数コード直したものです。その他ロジックは基本的にはそのまま流用することができます。例えば以下、データのレポジトリーを定義するコードは変更なく、そのままで使用できます。

src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java

これがGemfireを利用する上での大きなポイントとなります。既存のコードから最小限の変更で、利用できるようになっています。

まとめ

今回は、Petclinicを使ってGemfireのキャッシュに切り替える方法を紹介しました。気軽に試せる点も含め、Gemfireの運用を体感できたかと思います。