Technologieaustausch

SpringBoot implementiert den Read-Through-Modus

2024-07-12

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

Einführung

Der Read-Through-Modus bezieht sich im Allgemeinen auf eine Caching-Strategie, bei der beim Versuch einer Anwendung, Daten zu lesen, zunächst das Cache-System überprüft wird, um festzustellen, ob sich die Daten bereits im Cache befinden. Wenn die Daten im Cache vorhanden sind (d. h. Cache-Treffer), werden die Daten direkt aus dem Cache gelesen und an die Anwendung zurückgegeben. Wenn die Daten nicht im Cache vorhanden sind (z. B. ein Cache-Fehler), werden die Daten aus dem zugrunde liegenden Datenspeicher (z. B. einer Datenbank) gelesen, dann in den Cache geladen und schließlich an die Anwendung zurückgegeben.

Zu den Hauptvorteilen dieses Modells gehören:

  1. Leistung verbessern: Die Leistung des Datenabrufs kann erheblich verbessert werden, indem die Anzahl der direkten Zugriffe auf den zugrunde liegenden Speicher reduziert wird.
  2. Reduzieren Sie die Latenz: Der Cache befindet sich normalerweise im Speicher und kann viel schneller als auf Festplattenspeicher aufgerufen werden, wodurch die Latenz beim Datenabruf verringert wird.
  3. Reduzieren Sie die Datenbanklast: Durch das Speichern häufig aufgerufener Daten im Cache kann der Abfragedruck auf die Datenbank verringert und dadurch der Durchsatz des gesamten Systems verbessert werden.

Der Read-Through-Modus steht normalerweise im Gegensatz zu Strategien wie Lazy Loading und Eager Loading:

  • Faules Laden: Daten werden nur bei Bedarf geladen, was unnötiges Laden von Daten reduziert, aber möglicherweise die Latenz beim ersten Zugriff erhöht.
  • Eager Loading: Laden Sie Daten vorab, was die Latenz beim ersten Zugriff verringern kann, aber möglicherweise die Speichernutzung und Startzeit Ihrer Anwendung erhöht.

Bei der Implementierung des Read-Through-Modus sollten Sie Folgendes berücksichtigen:

  • Strategie zur Cache-Invalidierung: Bestimmen Sie, wann Daten aus dem Cache entfernt werden sollen, z. B. zeitbasiert (TTL) oder platzbasiert (wenn der Cache eine bestimmte Größe erreicht).
  • Parallelitätskontrolle: Behandeln Sie die Situation, in der mehrere Anwendungsinstanzen gleichzeitig auf den Cache zugreifen und ihn ändern.
  • Datenkonsistenz: Stellen Sie sicher, dass die Daten im Cache mit den Daten im zugrunde liegenden Speicher übereinstimmen, insbesondere wenn die Daten aktualisiert werden.

erreichen

Die Implementierung des Read Through-Musters in Spring Boot kann normalerweise über die Spring Cache-Abstraktion erfolgen. Spring Cache bietet eine einheitliche API für verschiedene Cache-Implementierungen und unterstützt mehrere Cache-Lösungen wie EhCache, Hazelcast, Infinispan, Redis usw.

  1. Abhängigkeiten hinzufügen: Zuerst müssen Sie die Cache-Abhängigkeiten von Spring Boot und die ausgewählte Cache-Implementierungsbibliothek (z. B. Redis) hinzufügen.

    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. Cache-Anmerkungen aktivieren:Fügen Sie die Spring Boot-Konfigurationsklasse hinzu@EnableCachingannotation, um die Unterstützung für Cache-Annotationen zu aktivieren.

  3. Cache-Manager konfigurieren: Konfigurieren Sie eine oder mehrereCacheManager, Spring Boot konfiguriert automatisch eine einfacheCacheManager, aber Sie können bei Bedarf komplexere Caching-Strategien konfigurieren.

    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. Verwenden Sie Cache-Anmerkungen: Wird für Methoden verwendet, die Caching erfordern@Cacheable Anmerkungen zur Implementierung des Read-Through-Modus. Befinden sich keine Daten im Cache, wird die Methode aufgerufen und das Ergebnis zwischengespeichert.
    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. Cache-Schlüssel:existieren@CacheableDer Cache-Schlüssel wird in der Annotation angegeben, die normalerweise auf dem Wert des Methodenparameters basiert.

  6. Cache-Name: Geben Sie den Cache-Namen an, der zur Unterscheidung verschiedener Cache-Domänen verwendet wird.

  7. Konfigurieren Sie Cache-Parameter: Sie können das Cache-Timeout, die Bedingungen, die Ausnahmebedingungen usw. nach Bedarf konfigurieren

    1. Wert oder CacheNames : Cache-Namen angeben. Sie können einen oder mehrere Cache-Namen angeben, die zum Speichern des Caches verwendet werden.

      @Cacheable(value = "myCacheName", key = "#id")
    2. Schlüssel : Definieren Sie die Generierungsstrategie für Cache-Schlüsselwerte. SpEL-Ausdrücke (Spring Expression Language) werden normalerweise verwendet, um Methodenparameter als Cache-Schlüssel anzugeben.

      @Cacheable(cacheNames = "myCache", key = "#id")
    3. Zustand: Definieren Sie die Bedingungen für das Caching und führen Sie den Cache nur dann durch, wenn die Bedingungen erfüllt sind.

      @Cacheable(cacheNames = "myCache", key = "#id", condition = "#id.length() > 3")
    4. es sei denn: Definieren Sie die Bedingungen für das Nicht-Caching undconditionVielmehr dient es dazu, bestimmte Situationen auszuschließen.

      @Cacheable(cacheNames = "myCache", key = "#id", unless = "#result == null")
    5. Schlüsselgenerator: Geben Sie eine benutzerdefinierte Strategie zur Cache-Schlüsselgenerierung an. Wenn Sie eine komplexere Schlüsselgenerierungslogik benötigen, können Sie eine angebenKeyGeneratorBohnenname.

      @Cacheable(cacheNames = "myCache", keyGenerator = "myKeyGenerator")
    6. CacheManager:Geben Sie an, welches verwendet werden sollCacheManager, wenn es mehrere gibtCacheManagerwenn benutzt.

      @Cacheable(cacheNames = "myCache", cacheManager = "myCacheManager")
    7. Ablauf nach Schreiben : Legen Sie die Ablaufzeit (in Millisekunden) fest, nachdem das Cache-Element geschrieben wurde. Dies ist eine häufig verwendete Konfiguration, um die Lebensdauer zwischengespeicherter Daten zu definieren.

      @Cacheable(cacheNames = "myCache", key = "#id", expireAfterWrite = 3600000) // 1小时后过期
    8. Ablauf nach Zugriff: Legen Sie die Ablaufzeit nach dem letzten Zugriff auf das Cache-Element fest. Sie bestimmt, wie lange es dauert, bis die zwischengespeicherten Daten nach dem letzten Zugriff ablaufen.

    9. Aktualisieren nach dem Schreiben: Legen Sie fest, wie lange der Cache nach dem Schreiben aktualisiert werden soll. Dies eignet sich für Szenarien, in denen der Cache dynamisch aktualisiert wird.

    10. synchronisieren: Legen Sie fest, ob Cache-Elemente synchron erstellt werden sollen, um Race Conditions in gleichzeitigen Umgebungen zu verhindern.

  8. Ausnahmebehandlung: Stellen Sie sicher, dass Sie Ausnahmen behandeln, die möglicherweise in Cache-Methoden ausgelöst werden, um eine Beeinträchtigung der Stabilität der Anwendung zu vermeiden.