Memorystore を使用して Spring Boot アプリのデータをキャッシュに保存する

Memorystore for Redis は、Google Cloud に対応したフルマネージドの Redis サービスです。Google Cloud 上で動作するアプリケーションは、スケーラビリティと可用性が高く、セキュアな Redis サービスを利用することで、複雑な Redis デプロイを管理する負担なく、優れたパフォーマンスを実現できます。データ キャッシュのバックエンドとして使用して、Spring Boot アプリのパフォーマンスを向上させることができます。この Codelab では、設定方法について説明します。

学習内容

  • Spring Boot アプリのキャッシュ バックエンドとして Memorystore を使用する方法。

必要なもの

  • Google Cloud プロジェクト
  • ブラウザ(Google Chrome など)
  • Linux の標準的なテキスト エディタ(Vim、Emacs、GNU Nano など)の使用経験

この Codelab をどのように使用しますか?

通読のみ 通読して演習を行う

Google Cloud サービスの使用経験はどの程度ありますか?

初心者 中級者 上級者

セルフペース型の環境設定

Google アカウント(Gmail または Google Apps)をお持ちでない場合は、1 つ作成する必要があります。Google Cloud Platform のコンソール(console.cloud.google.com)にログインし、新しいプロジェクトを作成します。

Screenshot from 2016-02-10 12:45:26.png

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

この Codelab の操作をすべて行っても、費用は数ドル程度です。ただし、その他のリソースを使いたい場合や、実行したままにしておきたいステップがある場合は、追加コストがかかる可能性があります(このドキュメントの最後にある「クリーンアップ」セクションをご覧ください)。

Google Cloud Platform の新規ユーザーは、300 ドル分の無料トライアルをご利用いただけます。

Google Cloud Shell の有効化

GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。

[Cloud Shell の起動] をクリックします。

プロビジョニングと環境への接続にはそれほど時間はかかりません。

この仮想マシンには、必要な開発ツールがすべて準備されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このラボでの作業のほとんどは、ブラウザまたは Google Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自の PROJECT_ID が設定されています。

Cloud Shell で次のコマンドを実行して、認証されたことを確認します。

gcloud auth list

コマンド出力

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

Cloud Shell を起動します。

Cloud Shell の起動後に、コマンドラインを使用して新しい Memorystore インスタンスを作成できます。

$ gcloud redis instances create myinstance --size=1 --region=us-central1

Memorystore API が有効になっていない場合は、有効にするかどうかを確認するメッセージが表示されます。「y」と回答します。

API [redis.googleapis.com] not enabled on project [204466653457].
Would you like to enable and retry (this will take a few minutes)?
(y/N)?  y
Enabling service redis.googleapis.com on project 204166153457...
Waiting for async operation operations/tmo-acf.c8909997-1b4e-1a62-b6f5-7da75cce1416 to complete...
Operation finished successfully. The following command can describe the Operation details:
 gcloud services operations describe operations/tmo-acf.c8909997-1b4e-1a62-b6f5-7da75cce1416
Create request issued for: [myinstance]
Waiting for operation [operation-1538645026454-57763b937ad39-2564ab37-3fea7701] to complete...done.
Created instance [myinstance].

オペレーションが完了すると、インスタンスを使用できるようになります。

次のコマンドを実行して、インスタンスの redis ホスト IP アドレスを取得します。この値は、後で Spring Boot アプリを構成するときに再度使用します。

$ gcloud redis instances describe myinstance --region=us-central1 \
  | grep host
host: 10.0.0.4

Google Cloud コンソールで [ストレージ] > [Memorystore] に移動すると、インスタンスが「準備完了」状態になっていることを確認できます。

同じリージョンに Compute Engine インスタンスを作成します。

$ gcloud compute instances create instance-1 --zone us-central1-c

オペレーションが完了すると、インスタンスを使用できるようになります。

[Compute] > [Compute Engine] > [VM インスタンス] に移動して、[接続] 列の [SSH] をクリックし、SSH 経由でインスタンスに接続します。

仮想マシン(VM)インスタンスのシェル(Cloud Shell ではない)で、OpenJDK、Maven、telnet をインストールします。

$ sudo apt-get install openjdk-8-jdk-headless maven telnet

インストールが完了するまで待ってから、次のステップに進みます。

webrediscache の依存関係を使用して、新しい Spring Boot プロジェクトを作成します。

$ curl https://start.spring.io/starter.tgz \
  -d dependencies=web,redis,cache -d language=java -d baseDir=cache-app \
  | tar -xzvf - && cd cache-app

application.properties ファイルを編集して、Redis ホストの Memorystore インスタンスの IP アドレスを使用するようにアプリを構成します。

$ nano src/main/resources/application.properties

Memorystore for Redis の IP アドレス(数ステップ前の手順で取得)を使用して、次の行を追加します。

spring.redis.host=<memorystore-host-ip-address> 

その後に新しい行を追加して、REST コントローラ Java クラスを作成します。

$ nano src/main/java/com/example/demo/HelloWorldController.java

次の内容をファイルに追加します。

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
@Autowired
private StringRedisTemplate template;

@RequestMapping("/hello/{name}")
@Cacheable("hello")
public String hello(@PathVariable String name) throws InterruptedException {
  Thread.sleep(5000);
  return "Hello " + name;
 }
}

@RequestMapping アノテーションは、メソッドを HTTP エンドポイントとして公開し、パスの一部をメソッド パラメータにマッピングします(@PathVariable アノテーションで示されているとおり)。

@Cacheable("hello") アノテーションは、メソッドの実行をキャッシュに保存し、キャッシュ名を「hello」にすることを指定します。これは、パラメータ値と組み合わせてキャッシュキーとして使用されます。コードラボの後半で例をご紹介します。

また、Spring Boot アプリクラスでキャッシュ保存を有効にする必要があります。

DemoApplication.java を編集します。

$ nano src/main/java/com/example/demo/DemoApplication.java

org.springframework.cache.annotation.EnableCaching をインポートし、このアノテーションでクラスにアノテーションを付けます。結果は次のようになります。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class DemoApplication {

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

これで、アプリを実行する準備が整いました。

$ mvn spring-boot:run

先ほどと同じ方法で、インスタンスへの別の SSH 接続を開きます。新しい SSH ウィンドウで、名前として「bob」を渡して /hello/ エンドポイントに複数回アクセスします。

$ time curl http://localhost:8080/hello/bob 
Hello bob!

real        0m5.408s
user        0m0.036s
sys        0m0.009s

$ time curl http://localhost:8080/hello/bob 
Hello bob!

real        0m0.092s
user        0m0.021s
sys        0m0.027s

最初のリクエストには 5 秒かかりましたが、メソッドに Thread.sleep(5000) 呼び出しがあるにもかかわらず、次のリクエストは大幅に高速になっています。これは、実際のメソッドが 1 回だけ実行され、結果がキャッシュに保存されたためです。以降の呼び出しでは、結果がキャッシュから直接返されます。

アプリがキャッシュに保存した内容を正確に確認できます。前の手順で使用したのと同じターミナルから、telnet を使用して Memorystore for Redis ホストに接続します。

$ telnet <memorystore-host-ip-address> 6379

キャッシュキーのリストを表示するには、次のコマンドを使用します。

KEYS *
hello::bob

ご覧のとおり、キャッシュ名はキーの接頭辞として使用され、パラメータ値は 2 番目の部分として使用されます。

値を取得するには、GET コマンドを使用します。

$ GET hello::bob
   Hello bob!

QUIT コマンドを使用して終了します。

クリーンアップするには、Cloud Shell から Compute Engine インスタンスと Memorystore インスタンスを削除します。

コンピューティング インスタンスを削除します。

$ gcloud compute instances delete instance-1 --zone us-central1-c

Memorystore for Redis インスタンスを削除します。

$ gcloud redis instances delete myinstance --region=us-central1

Memorystore for Redis と Compute Engine インスタンスを作成しました。また、Spring Boot キャッシュ保存で Memorystore を使用するように Spring Boot アプリを構成しました。

詳細

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。