The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

Infinispan Cache

By default, Quarkus Cache uses Caffeine as backend. It’s possible to use Infinispan instead.

この技術は、previewと考えられています。

preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリストGitHub の課題管理 で受け付けています。

とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。

Infinispan as cache backend

When using Infinispan as the backend for Quarkus cache, each cached item will be stored in Infinispan:

  • The backend uses the <default> Infinispan client (unless configured differently), so ensure its configuration is set up accordingly (or use the Infinispan Dev Service)

  • Both the key and the value are marshalled using Protobuf with Protostream.

Use the Infinispan backend

First, add the quarkus-infinispan-cache extension to your project:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-infinispan-cache</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-infinispan-cache")

Then, use the @CacheResult and other cache annotations as detailed in the Quarkus Cache guide:

@GET
@Path("/{keyElement1}/{keyElement2}/{keyElement3}")
@CacheResult(cacheName = "expensiveResourceCache")
public ExpensiveResponse getExpensiveResponse(@PathParam("keyElement1") @CacheKey String keyElement1,
        @PathParam("keyElement2") @CacheKey String keyElement2, @PathParam("keyElement3") @CacheKey String keyElement3,
        @QueryParam("foo") String foo) {
    invocations.incrementAndGet();
    ExpensiveResponse response = new ExpensiveResponse();
    response.setResult(keyElement1 + " " + keyElement2 + " " + keyElement3 + " too!");
    return response;
}

@POST
@CacheInvalidateAll(cacheName = "expensiveResourceCache")
public void invalidateAll() {

}

Configure the Infinispan backend

The Infinispan backend uses the <default> Infinispan client. Refer to the Infinispan reference for configuring the access to Infinispan.

In dev mode, you can use the Infinispan Dev Service.

If you want to use another Infinispan for your cache, configure the client-name as follows:

quarkus.cache.infinispan.client-name=another

Marshalling

When interacting with Infinispan in Quarkus, you can easily serialize and deserialize Java primitive types when storing or retrieving data from the cache. No additional marshalling configuration is required for Infinispan.

@CacheResult(cacheName = "weather-cache") (1)
public String getDailyForecast(String dayOfWeek, int dayOfMonth, String city) { (2)
    return dayOfWeek + " will be " + getDailyResult(dayOfMonth % 4) + " in " + city;
}
1 Ask this method execution to be cached in the 'weather-cache'
2 The key combines String dayOfWeek, int dayOfMonth and String city. The associated value is of type String.

Quarkus uses Protobuf for data serialization in Infinispan by default. Infinispan recommends using Protobuf as the preferred way to structure data. Therefore, when working with Plain Old Java Objects (POJOs), users need to supply the schema for marshalling in Infinispan.

Marshalling Java types

Let’s say we want a composite Key using java.time.LocalDate.

@CacheResult(cacheName = "weather-cache") (1)
public String getDailyForecast(LocalDate date, String city) { (2)
    return date.getDayOfWeek() + " will be " + getDailyResult(date.getDayOfMonth() % 4) + " in " + city;
}
1 Request that the response of this method execution be cached in 'weather-cache'
2 The key combines a java.util.LocalDate date and a String city. The associated value is of type 'String'.

Since Infinispan serializes data by default using Protobuf in Quarkus, executing the code will result in the following error:

java.lang.IllegalArgumentException:
No marshaller registered for object of Java type java.time.LocalDate

Protobuf does not inherently know how to marshal java.time.LocalDate. Fortunately, Protostream provides a straightforward solution to this problem using @ProtoAdapter and @ProtoSchema.

@ProtoAdapter(LocalDate.class)
public class LocalDateAdapter {
    @ProtoFactory
    LocalDate create(String localDate) {
        return LocalDate.parse(localDate);
    }

    @ProtoField(1)
    String getLocalDate(LocalDate localDate) {
        return localDate.toString();
    }
}

@ProtoSchema(includeClasses = LocalDateAdapter.class, schemaPackageName = "quarkus")
public interface Schema extends GeneratedSchema {
}

Marshalling your POJOs

Just like with Java types, when using your POJOs as keys or values, you can follow this approach:

@CacheResult(cacheName = "my-cache") (1)
public ExpensiveResponse requestApi(String id) { (2)
    // very expensive call

    return new ExpensiveResponse(...);
}
1 Request that the response of this method execution be cached in 'my-cache'
2 The key is a String. The associated value is of type org.acme.ExpensiveResponse.

In this case, you’ll need to define the schema for your Java type using @Proto and @ProtoSchema. This schema can encompass all types and adapters used in your Quarkus application.

@Proto
public record ExpensiveResponse(String result) {
}

@ProtoSchema(includeClasses = { ExpensiveResponse.class })
interface Schema extends GeneratedSchema {
}

Read more about it in the Infinispan reference in the Annotation based serialization section.

Expiration

You have the option to configure two properties for data expiration: lifespan and max-idle.

Lifespan

In Infinispan, lifespan refers to a configuration parameter that determines the maximum time an entry (or an object) can remain in the cache since it was created or last accessed before it is considered expired and removed from the cache.

When you configure the lifespan parameter for entries in an Infinispan cache, you specify a time duration. After an entry has been added to the cache or accessed (read or written), it starts its lifespan countdown. If the time since the entry was created or last accessed exceeds the specified "lifespan" duration, the entry is considered expired and becomes eligible for eviction from the cache.

quarkus.cache.infinispan.my-cache.lifespan=10s

Max Idle

When you configure the max-idle parameter for entries in an Infinispan cache, you specify a time duration. After an entry has been accessed (read or written) in the cache, if there are no subsequent accesses to that entry within the specified duration, it is considered idle. Once the idle time exceeds the max-idle duration, the entry is considered expired and eligible for eviction from the cache.

quarkus.cache.infinispan.my-cache.max-idle=100s

ビルド時に固定される構成プロパティ - 他のすべての構成プロパティは実行時にオーバーライド可能

Configuration property

タイプ

デフォルト

The name of the named Infinispan client to be used for communicating with Infinispan. If not set, use the default Infinispan client.

Environment variable: QUARKUS_CACHE_INFINISPAN_CLIENT_NAME

Show more

string

The default lifespan of the item stored in the cache

Environment variable: QUARKUS_CACHE_INFINISPAN_LIFESPAN

Show more

Duration 

The default max-idle of the item stored in the cache

Environment variable: QUARKUS_CACHE_INFINISPAN_MAX_IDLE

Show more

Duration 

Additional configuration applied to a specific Infinispan cache (highest precedence)

タイプ

デフォルト

The default lifespan of the item stored in the cache

Environment variable: QUARKUS_CACHE_INFINISPAN__CACHE_NAME__LIFESPAN

Show more

Duration 

The default max-idle of the item stored in the cache

Environment variable: QUARKUS_CACHE_INFINISPAN__CACHE_NAME__MAX_IDLE

Show more

Duration 

期間フォーマットについて

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

数字で始まる簡略化した書式を使うこともできます:

  • 数値のみの場合は、秒単位の時間を表します。

  • 数値の後に ms が続く場合は、ミリ秒単位の時間を表します。

その他の場合は、簡略化されたフォーマットが解析のために java.time.Duration フォーマットに変換されます:

  • 数値の後に hms が続く場合は、その前に PT が付けられます。

  • 数値の後に d が続く場合は、その前に P が付けられます。

関連コンテンツ