技術共有

SpringBoot はリードスルーモードを実装します

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

導入

リードスルー モードは一般に、アプリケーションがデータを読み取ろうとするときに、最初にキャッシュ システムをチェックしてデータがすでにキャッシュ内にあるかどうかを確認するキャッシュ戦略を指します。データがキャッシュに存在する場合 (つまり、キャッシュ ヒット)、データはキャッシュから直接読み取られ、アプリケーションに返されます。データがキャッシュに存在しない場合 (つまり、キャッシュ ミス)、データは基礎となるデータ ストア (データベースなど) から読み取られ、キャッシュにロードされ、最後にアプリケーションに返されます。

このモデルの主な利点は次のとおりです。

  1. 性能を上げる: データ取得のパフォーマンスは、基盤となるストレージへの直接アクセスの数を減らすことで大幅に改善できます。
  2. レイテンシの短縮: キャッシュは通常メモリ内に配置され、ディスク ストレージよりもはるかに高速にアクセスできるため、データ取得の待ち時間が短縮されます。
  3. データベースの負荷を軽減する: 頻繁にアクセスされるデータをキャッシュに保存することで、データベースへのクエリ負荷が軽減され、システム全体のスループットが向上します。

リードスルー モードは、通常、遅延読み込みや熱心な読み込みなどの戦略と対比されます。

  • 遅延読み込み: データは必要な場合にのみロードされるため、不必要なデータのロードは削減されますが、最初のアクセス時の待ち時間が長くなる可能性があります。
  • 積載量: データをプリロードします。これにより、初回アクセスの待ち時間は短縮されますが、アプリケーションのメモリ使用量と起動時間が増加する可能性があります。

リード スルー モードを実装する場合は、次の点を考慮する必要があります。

  • キャッシュ無効化戦略: 時間ベース (TTL) またはスペースベース (キャッシュが特定のサイズに達したとき) など、キャッシュからデータを削除するタイミングを決定します。
  • 同時実行制御: 複数のアプリケーション インスタンスが同時にキャッシュにアクセスして変更する状況に対処します。
  • データの一貫性: 特にデータが更新された場合は、キャッシュ内のデータが基礎となるストレージ内のデータと一貫性があることを確認してください。

成し遂げる

Spring Boot での Read Through パターンの実装は、通常、Spring Cache 抽象化を通じて実現できます。 Spring Cache は、さまざまなキャッシュ実装にわたって統合された API を提供し、EhCache、Hazelcast、Infinispan、Redis などの複数のキャッシュ ソリューションをサポートします。

  1. 依存関係の追加: まず、Spring Boot のキャッシュ依存関係と選択したキャッシュ実装ライブラリ (Redis など) を追加する必要があります。

    1. <!-- Spring Boot Starter Cache -->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-cache</artifactId>
    5. </dependency>
    6. <!-- 以Redis为例,添加Redis的Spring Boot Starter -->
    7. <dependency>
    8. <groupId>org.springframework.boot</groupId>
    9. <artifactId>spring-boot-starter-data-redis</artifactId>
    10. </dependency>
  2. キャッシュアノテーションを有効にする:Spring Boot 構成クラスを追加します。@EnableCaching注釈を使用してキャッシュ注釈サポートを有効にします。

  3. キャッシュマネージャーを構成する: 1 つ以上を設定しますCacheManager, Spring Boot は簡単な設定を自動的に行います。CacheManagerただし、必要に応じて、より複雑なキャッシュ戦略を構成できます。

    1. import org.springframework.context.annotation.Bean;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.data.redis.cache.RedisCacheConfiguration;
    4. import org.springframework.data.redis.cache.RedisCacheManager;
    5. import org.springframework.data.redis.connection.RedisConnectionFactory;
    6. @Configuration
    7. public class RedisCacheConfig {
    8. @Bean
    9. public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    10. RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
    11. .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
    12. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(GenericJackson2JsonRedisSerializer.json())))
    13. Map<String, RedisCacheConfiguration> customCacheConfigs = new HashMap<>();
    14. customCacheConfigs.put("mySpecialCache",
    15. config.entryTtl(Duration.ofMinutes(15))); // 为特定缓存设置不同的过期时间
    16. .disableCachingNullValues();
    17. return RedisCacheManager.builder(connectionFactory)
    18. .cacheDefaults(config)
    19. // 在这里可以自定义添加缓存配置
    20. .withInitialCacheConfigurations(customCacheConfigs)
    21. .build();
    22. }
    23. }
  4. キャッシュアノテーションを使用する: キャッシュが必要なメソッドで使用されます。@Cacheableリードスルーモードを実装するためのアノテーション。キャッシュにデータがない場合は、メソッドが呼び出され、結果がキャッシュされます。
    1. import org.springframework.cache.annotation.Cacheable;
    2. import org.springframework.stereotype.Service;
    3. @Service
    4. public class MyService {
    5. @Cacheable(value = "myCache", key = "#id")
    6. public MyData getDataById(String id) {
    7. // 从数据库加载数据
    8. return myDataRepository.findById(id);
    9. }
    10. }
  5. キャッシュキー:存在する@Cacheableキャッシュ キーはアノテーションで指定され、通常はメソッド パラメーターの値に基づきます。

  6. キャッシュ名: 異なるキャッシュ ドメインを区別するために使用されるキャッシュ名を指定します。

  7. キャッシュパラメータを構成する: 必要に応じて、キャッシュのタイムアウト、条件、例外条件などを設定できます。

    1. 値またはキャッシュ名 : キャッシュ名を指定します。キャッシュの保存に使用される 1 つ以上のキャッシュ名を指定できます。

      @Cacheable(value = "myCacheName", key = "#id")
    2. : キャッシュ キー値の生成戦略を定義します。通常、SpEL 式 (Spring Expression Language) は、メソッド パラメータをキャッシュ キーとして指定するために使用されます。

      @Cacheable(cacheNames = "myCache", key = "#id")
    3. 状態: キャッシュの条件を定義し、条件が満たされた場合にのみキャッシュします。

      @Cacheable(cacheNames = "myCache", key = "#id", condition = "#id.length() > 3")
    4. ない限り: キャッシュしない条件を定義し、condition代わりに、特定の状況を除外するために使用されます。

      @Cacheable(cacheNames = "myCache", key = "#id", unless = "#result == null")
    5. キージェネレータ: より複雑なキー生成ロジックが必要な場合は、カスタム キャッシュ キー生成戦略を指定できます。KeyGenerator豆の名前。

      @Cacheable(cacheNames = "myCache", keyGenerator = "myKeyGenerator")
    6. キャッシュマネージャー:どちらを使用するかを指定しますCacheManager、複数ある場合CacheManager使用した場合。

      @Cacheable(cacheNames = "myCache", cacheManager = "myCacheManager")
    7. 書き込み後に期限切れ : キャッシュ項目が書き込まれた後の有効期限をミリ秒単位で設定します。これは、キャッシュされたデータの有効期間を定義するために一般的に使用される構成です。

      @Cacheable(cacheNames = "myCache", key = "#id", expireAfterWrite = 3600000) // 1小时后过期
    8. 有効期限後アクセス: キャッシュ アイテムの最終アクセス後の有効期限を設定します。これは、最後のアクセスからキャッシュされたデータの有効期限が切れるまでの時間に適用されます。

    9. リフレッシュ後書き込み: キャッシュが動的に更新されるシナリオに適した、書き込み後にキャッシュを更新する時間を設定します。

    10. 同期: 同時環境での競合状態を防ぐためにキャッシュ項目を同期的に作成するかどうかを設定します。

  8. 例外処理注: アプリケーションの安定性に影響を与えないように、キャッシュ メソッドでスローされる可能性のある例外を必ず処理してください。