Compartir tecnología

SpringBoot implementa el modo de lectura completa

2024-07-12

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

Introducción

El modo de lectura directa generalmente se refiere a una estrategia de almacenamiento en caché en la que cuando una aplicación intenta leer datos, primero se verifica el sistema de caché para ver si los datos ya están en el caché. Si los datos existen en el caché (es decir, acierto en el caché), los datos se leen directamente desde el caché y se devuelven a la aplicación. Si los datos no existen en el caché (es decir, una falta de caché), los datos se leen del almacén de datos subyacente (como una base de datos), luego se cargan en el caché y finalmente se devuelven a la aplicación.

Las principales ventajas de este modelo incluyen:

  1. Mejorar el rendimiento: El rendimiento de la recuperación de datos se puede mejorar significativamente reduciendo la cantidad de accesos directos al almacenamiento subyacente.
  2. Reducir la latencia: El caché normalmente se encuentra en la memoria y se puede acceder a él mucho más rápido que el almacenamiento en disco, lo que reduce la latencia de la recuperación de datos.
  3. Reducir la carga de la base de datos: Al almacenar los datos a los que se accede con frecuencia en la caché, se puede reducir la presión de las consultas sobre la base de datos, mejorando así el rendimiento de todo el sistema.

El modo de lectura completa generalmente se contrasta con estrategias como Lazy Loading y Eager Loading:

  • Carga lenta: Los datos se cargan solo cuando son necesarios, lo que reduce la carga de datos innecesaria pero puede aumentar la latencia en el primer acceso.
  • Cargando ansiosamente: datos de carga previa, que pueden reducir la latencia del primer acceso, pero pueden aumentar el uso de memoria y el tiempo de inicio de la aplicación.

Al implementar el modo de lectura completa, es posible que desee considerar lo siguiente:

  • Estrategia de invalidación de caché: determine cuándo eliminar datos del caché, como los basados ​​en tiempo (TTL) o en espacio (cuando el caché alcanza un cierto tamaño).
  • Control de concurrencia: Maneja la situación en la que varias instancias de aplicaciones acceden y modifican el caché al mismo tiempo.
  • consistencia de los datos: Asegúrese de que los datos en el caché sean consistentes con los datos en el almacenamiento subyacente, especialmente cuando los datos se actualizan.

lograr

La implementación del patrón Read Through en Spring Boot generalmente se puede lograr mediante la abstracción Spring Cache. Spring Cache proporciona una API unificada para diferentes implementaciones de caché y admite múltiples soluciones de caché, como EhCache, Hazelcast, Infinispan, Redis, etc.

  1. Agregar dependencias: primero, debe agregar las dependencias de caché de Spring Boot y la biblioteca de implementación de caché seleccionada (como 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. Habilitar anotaciones de caché:Agregue la clase de configuración Spring Boot@EnableCachinganotación para habilitar la compatibilidad con anotaciones en caché.

  3. Configurar el administrador de caché: Configurar uno o másCacheManager, Spring Boot configurará automáticamente un simpleCacheManager, pero puede configurar estrategias de almacenamiento en caché más complejas si es necesario.

    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. Usar anotaciones de caché: Se utiliza en métodos que requieren almacenamiento en caché@Cacheable Anotaciones para implementar el modo de lectura completa. Si no hay datos en el caché, se llamará al método y el resultado se almacenará en caché.
    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. clave de caché:existir@CacheableLa clave de caché se especifica en la anotación, que generalmente se basa en el valor del parámetro del método.

  6. nombre de caché: especifique el nombre de la caché, que se utilizará para distinguir diferentes dominios de caché.

  7. Configurar parámetros de caché: Puede configurar el tiempo de espera de la caché, las condiciones, a menos que las condiciones, etc., según sea necesario

    1. valor o nombres de caché :Especifique el nombre de la caché. Puede especificar uno o más nombres de caché que se utilizarán para almacenar el caché.

      @Cacheable(value = "myCacheName", key = "#id")
    2. llave : Defina la estrategia de generación de valores de clave de caché. Las expresiones SpEL (Spring Expression Language) se utilizan generalmente para especificar parámetros de métodos como claves de caché.

      @Cacheable(cacheNames = "myCache", key = "#id")
    3. condición: Defina las condiciones para el almacenamiento en caché y almacene en caché solo cuando se cumplan las condiciones.

      @Cacheable(cacheNames = "myCache", key = "#id", condition = "#id.length() > 3")
    4. a menos que: Defina las condiciones para no almacenar en caché yconditionEn cambio, se utiliza para descartar determinadas situaciones.

      @Cacheable(cacheNames = "myCache", key = "#id", unless = "#result == null")
    5. generador de llaves: especifique una estrategia de generación de claves de caché personalizada. Si necesita una lógica de generación de claves más compleja, puede especificar una.KeyGeneratorNombre del frijol.

      @Cacheable(cacheNames = "myCache", keyGenerator = "myKeyGenerator")
    6. Administrador de caché:Especifique cuál usarCacheManager, si hay variosCacheManagercuando se usa.

      @Cacheable(cacheNames = "myCache", cacheManager = "myCacheManager")
    7. expirar después de escribir : establece el tiempo de caducidad (en milisegundos) después de que se escribe el elemento de la caché. Esta es una configuración comúnmente utilizada para definir la vida útil de los datos almacenados en caché.

      @Cacheable(cacheNames = "myCache", key = "#id", expireAfterWrite = 3600000) // 1小时后过期
    8. expirar después del acceso: establece el tiempo de vencimiento después del último acceso al elemento de la caché, que se aplica al tiempo transcurrido desde que se accedió por última vez a los datos de la caché.

    9. ActualizarDespuésDeEscribir: establezca cuánto tiempo se actualizará el caché después de escribir, adecuado para escenarios donde el caché se actualiza dinámicamente.

    10. sincronizar: establezca si se crearán elementos de caché de forma sincrónica para evitar condiciones de carrera en entornos concurrentes.

  8. Manejo de excepciones: asegúrese de manejar las excepciones que puedan generarse en los métodos de caché para evitar afectar la estabilidad de la aplicación.