Redis キャッシュ
Spring Data Redis は、org.springframework.data.redis.cache
パッケージで Spring Framework のキャッシュの抽象化の実装を提供します。Redis をバッキング実装として使用するには、次のように構成に RedisCacheManager
(Javadoc) を追加します。
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.create(connectionFactory);
}
RedisCacheManager
の動作は RedisCacheManager.RedisCacheManagerBuilder
(Javadoc) を使用して構成でき、デフォルトの RedisCacheManager
(Javadoc) 、トランザクション動作、定義済みキャッシュを設定できます。
RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
.transactionAware()
.withInitialCacheConfigurations(Collections.singletonMap("predefined",
RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()))
.build();
前の例で示したように、RedisCacheManager
ではキャッシュごとにカスタム構成が可能です。
RedisCacheManager
(Javadoc) によって作成された RedisCache
(Javadoc) の動作は、RedisCacheConfiguration
で定義されます。次の例に示すように、構成により、キーの有効期限、プレフィックス、バイナリストレージ形式との間の変換に使用する RedisSerializer
実装を設定できます。
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(1))
.disableCachingNullValues();
RedisCacheManager
(Javadoc) は、バイナリ値の読み取りと書き込みにデフォルトでロックフリーの RedisCacheWriter
(Javadoc) を使用します。ロックフリーのキャッシュにより、スループットが向上します。エントリロックがないと、Cache
putIfAbsent
、clean
操作で複数のコマンドを Redis に送信する必要があるため、コマンドが重複して非アトミックになる可能性があります。ロック対応では、明示的なロックキーを設定し、このキーの存在をチェックすることでコマンドの重複を防止します。これにより、追加のリクエストが発生し、コマンドの待機時間が発生する可能性があります。
ロックは、キャッシュエントリごとではなく、キャッシュレベルに適用されます。
次のようにロック動作にオプトインすることができます。
RedisCacheManager cacheManager = RedisCacheManager
.builder(RedisCacheWriter.lockingRedisCacheWriter(connectionFactory))
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
...
デフォルトでは、キャッシュエントリの key
には、実際のキャッシュ名とそれに続く 2 つのコロン (::
) が接頭辞として付けられます。この動作は、計算されたプレフィックスだけでなく静的なプレフィックスにも変更できます。
次の例は、静的プレフィックスを設定する方法を示しています。
// static key prefix
RedisCacheConfiguration.defaultCacheConfig().prefixCacheNameWith("(͡° ᴥ ͡°)");
The following example shows how to set a computed prefix:
// computed key prefix
RedisCacheConfiguration.defaultCacheConfig()
.computePrefixWith(cacheName -> "¯\_(ツ)_/¯" + cacheName);
キャッシュ実装では、デフォルトで KEYS
および DEL
を使用してキャッシュをクリアします。KEYS
は、大きなキースペースでパフォーマンスの課題を引き起こす可能性があります。BatchStrategy
を使用してデフォルトの RedisCacheWriter
を作成し、SCAN
ベースのバッチ戦略に切り替えることができます。SCAN
戦略では、過剰な Redis コマンドの往復を避けるためにバッチサイズが必要です。
RedisCacheManager cacheManager = RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory, BatchStrategies.scan(1000)))
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
...
|
次の表に、RedisCacheManager
のデフォルト設定を示します。
設定 | 値 |
---|---|
キャッシュライター | ノンロック、 |
キャッシュ構成 |
|
初期キャッシュ | なし |
トランザクション対応 | いいえ |
次の表に、RedisCacheConfiguration
のデフォルト設定を示します。
キーの有効期限 | なし |
---|---|
キャッシュ | はい |
プレフィックスキー | はい |
デフォルト接頭部 | 実際のキャッシュ名 |
キーシリアライザー |
|
バリューシリアライザー |
|
変換サービス | デフォルトのキャッシュキーコンバーターを備えた |
デフォルトでは |
Redis キャッシュの有効期限
アイドル時間 (TTI) および存続時間 (TTL) の実装は、データストアが異なる場合でも定義と動作が異なります。
一般:
有効期限 (TTL) の有効期限 - TTL は、データアクセスの作成または更新操作によってのみ設定およびリセットされます。作成時を含め、エントリが TTL 有効期限タイムアウト前に書き込まれている限り、エントリのタイムアウトは、設定された TTL 有効期限タイムアウト期間にリセットされます。例: TTL 有効期限タイムアウトが 5 分に設定されている場合、タイムアウトはエントリの作成時に 5 分に設定され、その後、5 分の間隔が期限切れになる前にエントリが更新されるたびに 5 分にリセットされます。5 分以内に更新が発生しない場合、エントリが数回読み取られた場合でも、5 分間に 1 回読み取られただけでも、エントリは期限切れになります。TTL 有効期限ポリシーを宣言するときに、エントリが期限切れにならないようにエントリを書き込む必要があります。
アイドル時間 (TTI) の有効期限 - TTI は、エントリの更新だけでなくエントリが読み取られるたびにリセットされ、実質的に TTL 有効期限ポリシーの拡張となります。
一部のデータストアでは、エントリで発生するデータアクセス操作の種類 (読み取り、書き込み、その他) に関係なく、TTL が構成されている場合にエントリが期限切れになります。設定され、構成された TTL 有効期限タイムアウトが経過すると、エントリはデータストアから削除されます。エビクションアクション (例: 破棄、無効化、ディスクへのオーバーフロー (永続ストアの場合) など) はデータストア固有です。 |
生存時間 (TTL) の有効期限
Spring Data Redis の Cache
実装は、キャッシュエントリの有効期限 (TTL) をサポートします。ユーザーは、新しい RedisCacheWriter.TtlFunction
インターフェースの実装を提供することで、固定 Duration
またはキャッシュエントリごとに動的に計算される Duration
を使用して TTL 有効期限タイムアウトを構成できます。
|
すべてのキャッシュエントリが設定された期間後に期限切れになる必要がある場合は、次のように、固定 Duration
を使用して TTL 期限切れタイムアウトを構成するだけです。
RedisCacheConfiguration fiveMinuteTtlExpirationDefaults =
RedisCacheConfiguration.defaultCacheConfig().enableTtl(Duration.ofMinutes(5));
ただし、TTL 有効期限タイムアウトがキャッシュエントリによって異なる場合は、RedisCacheWriter.TtlFunction
インターフェースのカスタム実装を提供する必要があります。
enum MyCustomTtlFunction implements TtlFunction {
INSTANCE;
@Override
public Duration getTimeToLive(Object key, @Nullable Object value) {
// compute a TTL expiration timeout (Duration) based on the cache entry key and/or value
}
}
内部では、固定 |
次に、次を使用して、固定 Duration
または動的、キャッシュエントリごとの Duration
TTL 有効期限をグローバルベースで構成できます。
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(fiveMinuteTtlExpirationDefaults)
.build();
または、次のようにすることもできます。
RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(MyCustomTtlFunction.INSTANCE);
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaults)
.build();
もちろん、以下を使用してグローバル構成とキャッシュごとの構成の両方を組み合わせることができます。
RedisCacheConfiguration predefined = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(MyCustomTtlFunction.INSTANCE);
Map<String, RedisCacheConfiguration> initialCaches = Collections.singletonMap("predefined", predefined);
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(fiveMinuteTtlExpirationDefaults)
.withInitialCacheConfigurations(initialCaches)
.build();
アイドル時間 (TTI) の有効期限
Redis 自体は、真のアイドル時間 (TTI) 有効期限の概念をサポートしていません。それでも、Spring Data Redis のキャッシュ実装を使用すると、アイドル時間 (TTI) の有効期限に似た動作を実現できます。
Spring Data Redis のキャッシュ実装における TTI の構成は、明示的に有効にする必要があります。つまり、オプトインです。さらに、固定 Duration
または Redis キャッシュの有効期限で説明した TtlFunction
インターフェースのカスタム実装を使用して TTL 構成を提供する必要もあります。
例:
@Configuration
@EnableCaching
class RedisConfiguration {
@Bean
RedisConnectionFactory redisConnectionFactory() {
// ...
}
@Bean
RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.enableTimeToIdle();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(defaults)
.build();
}
}
Redis サーバーは TTI の適切な概念を実装していないため、TTI は有効期限オプションを受け入れる Redis コマンドでのみ実現できます。Redis では、「有効期限」は技術的には存続時間 (TTL) ポリシーです。ただし、Spring Data Redis の Cache.get(key)
操作の場合のように、キーの値を読み取るときに TTL 有効期限を過ぎることができ、それによって TTL 有効期限タイムアウトが効果的にリセットされます。
RedisCache.get(key)
は、Redis GETEX
コマンドを呼び出すことによって実装されます。
Redis |
Spring Data Redis アプリケーションで真のアイドル時間 (TTI) 有効期限に似た動作を実現するには、すべての読み取りまたは書き込み操作で (TTL) 有効期限を設定してエントリに一貫してアクセスする必要があります。この規則には例外はありません。Spring Data Redis アプリケーション全体でさまざまなデータアクセスパターンを混合および一致させている場合 (たとえば、キャッシング、 |