Redis结合Caffeine实现二级缓存:提高应用程序性能

本文将详细介绍如何使用CacheFrontend和Caffeine来实现二级缓存。

1. 简介

CacheFrontend: 是一种用于缓存的前端组件或服务。通俗的讲:该接口可以实现本地缓存与redis自动同步,如果本地缓存(JVM级)有数据,则直接从本地缓存中返回数据。否则从redis获取。

CacheFrontend的工作方式通常涉及以下两个方面:

  • 数据存储:CacheFrontend会将从后端(Redis)获取的数据存储在本地缓存中。这样,在后续请求中,如果相同的数据被请求,CacheFrontend可以直接从本地缓存中返回,而无需再次访问后端存储(Redis)。这减少了对后端存储的访问次数,提高了响应速度。

  • 数据更新和失效:当后端存储中的数据发生变化时,CacheFrontend需要相应地更新本地缓存中的数据。它可以通过主动监测后端存储的变化。

通过使用CacheFrontend,应用程序可以减轻后端存储的负载,提高系统的性能和可扩展性,从而改善用户体验。

CacheFrontend是由 Lettuce 提供,Lettuce 提供了 ClientSideCaching 实现,在该实现类中接受一个CacheAccessor缓存访问器。我们可以根据具体需要实现自己的缓存访问器。本文将自定义CacheAccessor结合Caffeine实现缓存策略。

2. 实战案例

2.1 依赖管理

xml 复制代码
<!--高性能本地缓存实现-->
<dependency>
  <groupId>com.github.ben-manes.caffeine</groupId>
  <artifactId>caffeine</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.2 配置文件

复制代码
spring:
  redis:
    host: localhost
    password: xxxooo
    database: 10
    port: 6379

2.2 配置

本地缓存配置
java 复制代码
@Bean
public Cache<String, String> localCache() {
  return  Caffeine.newBuilder()
    // 初始容量
    .initialCapacity(100)
    .maximumSize(1000)
    .build() ;
}
RedisClient配置
java 复制代码
@Bean
public RedisClient redisClient(RedisProperties props) {
  RedisURI clientResources = RedisURI.Builder
      .redis(props.getHost(), props.getPort())
      .withPassword(props.getPassword().toCharArray())
      .withDatabase(props.getDatabase())
      .build() ;
  RedisClient client = RedisClient.create(clientResources) ;
  return client ;
}

RedisProperties是系统内部自动注册的Bean。

缓存前端配置CacheFrontend
java 复制代码
@Bean
  public CacheFrontend<String, String> cacheFrontend(RedisClient redisClient, Cache<String, String> localCache) {
    StatefulRedisConnection<String, String> connection = redisClient.connect() ;
    // 添加监听器,当缓存失效后会被监听到。
    connection.addListener(new PushListener() {
      @Override
      public void onPushMessage(PushMessage message) {
        String type = message.getType() ;
        if ("invalidate".equals(type)) {
          System.out.println("...") ;
        }
        List<Object> contents = message.getContent() ;
        Object content = contents.get(0);
        if (content instanceof ByteBuffer) {
          ByteBuffer buf = (ByteBuffer) content ;
          System.out.printf("response content: %s%n", StringCodec.UTF8.decodeValue(buf)) ;
        }
      }
    }) ;
    // 缓存访问器
    CacheAccessor<String, String> cacheAccessor = new CacheAccessor<String, String>() {
      @Override
      public String get(String key) {
        @Nullable
        String present = localCache.getIfPresent(key) ;
        System.out.printf("get operator: %s%n", present) ;
        return present ;
      }
      @Override
      public void put(String key, String value) {
        localCache.put(key, value) ;
        System.out.printf("put operator: key = %s, value = %s%n", key, value) ;
      }
      @Override
      public void evict(String key) {
        localCache.invalidate(key) ;
        System.out.printf("evict operator: %s%n", key) ;
      }
    };
    CacheFrontend<String, String> frontend = ClientSideCaching.enable(
        cacheAccessor, 
        connection,
        TrackingArgs.Builder.enabled()) ;
    return frontend ;
  }

总结:通过本地缓存和Redis缓存可以带来诸多好处,如提高系统性能、减轻数据库压力、支持高并发等。通过合理配置和管理本地缓存与Redis缓存,可以优化应用程序的性能,提高系统的稳定性和可用性。在实际应用中,根据业务需求选择合适的缓存策略和数据结构,并进行持续的性能监控和调优,是确保系统高效运行的关键。

相关推荐
一只自律的鸡7 小时前
【MySQL】第二章 基本的SELECT语句
数据库·mysql
liliangcsdn8 小时前
如何使用python创建和维护sqlite3数据库
数据库·sqlite
TDengine (老段)14 小时前
TDengine 数学函数 DEGRESS 用户手册
大数据·数据库·sql·物联网·时序数据库·iot·tdengine
TDengine (老段)15 小时前
TDengine 数学函数 GREATEST 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
RoboWizard15 小时前
扩容刚需 金士顿新款Canvas Plus存储卡
java·spring·缓存·电脑·金士顿
安当加密15 小时前
云原生时代的数据库字段加密:在微服务与 Kubernetes 中实现合规与敏捷的统一
数据库·微服务·云原生
爱喝白开水a15 小时前
LangChain 基础系列之 Prompt 工程详解:从设计原理到实战模板_langchain prompt
开发语言·数据库·人工智能·python·langchain·prompt·知识图谱
想ai抽15 小时前
深入starrocks-多列联合统计一致性探查与策略(YY一下)
java·数据库·数据仓库
武子康15 小时前
Java-152 深入浅出 MongoDB 索引详解 从 MongoDB B-树 到 MySQL B+树 索引机制、数据结构与应用场景的全面对比分析
java·开发语言·数据库·sql·mongodb·性能优化·nosql
longgyy16 小时前
5 分钟用火山引擎 DeepSeek 调用大模型生成小红书文案
java·数据库·火山引擎