天地维杰网

人如秋鸿来有信,事若春梦了无痕


  • 首页

  • Redis

  • java

  • linux

  • 日常问题

  • Spring和Springboot

  • Mac相关

  • 中间件

  • 架构

  • python

  • 前端

  • jvm

  • c语言

  • web3

  • 归档

  • 关于

  • 搜索
close

时间: 0001-01-01   |   阅读: 307 字 ~2分钟

Lettuce 已支持 Redis6 客户端缓存

简介: 在 redis 6.0 版本中,已经默认支持了客户端缓存功能,Java 中主流的连接客户端 lettuce 在最新的快照版本 (6.0.0.BUILD-SNAPSHOT) 已经提供支持。 下边就通过代码来体验一下客户端缓存的神奇功能。

Redis 客户端缓存

缓存的解决方案一般有两种:

【L1】 内存缓存(如 Caffeine、Ehcache) —— 速度快,进程内可用,但重启缓存丢失,出现缓存雪崩的问题。

【L2】集中式缓存(如 Redis)—— 可同时为多节点提供服务,但高并发下,带宽成为瓶颈。

业内有很多开源框架来解决以上问题,既能有 L1 速度,并且拥有 L2 集群态。如下

J2Cache 两级缓存框架

hotkey 热点数据实时同步

在 redis 6.0 版本中,已经默认支持了客户端缓存功能,Java 中主流的连接客户端 lettuce 在最新的快照版本 (6.0.0.BUILD-SNAPSHOT) 已经提供支持。 下边就通过代码来体验一下客户端缓存的神奇功能。

Redis 6.0 安装

安装 redis 6,这里通过 Docker 安装命令如下

docker run --name redis6 -p 6379:6379 --restart=always -d redis:6.0.6

Jar 依赖

注意: 这里使用 lettuce 客户端,注意当前使用 6.0 的快照版本 ,需要在 pom 增加 lettuce 快照仓库

  • 1.lettuce 6.0 快照依赖

    <dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.0.0.BUILD-SNAPSHOT</version>
    </dependency>
    1. 配置快照仓库

      <repositories>
      <repository>
          <id>sonatype-snapshots</id>
          <name>Sonatype Snapshot Repository</name>
          <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
          <snapshots>
              <enabled>true</enabled>
          </snapshots>
      </repository>
      </repositories>

代码操作

  • 使用 lettuce 连接 redis ,并循环查看 k1 的值

    // <1> 创建单机连接的连接信息
    RedisURI redisUri = RedisURI.builder()                    //
        .withHost("127.0.0.1")
        .withPort(6379)
        .build();
    RedisClient redisClient = RedisClient.create(redisUri);
    StatefulRedisConnection<String, String> otherParty = redisClient.connect();
    RedisCommands<String, String> commands = otherParty.sync();
    StatefulRedisConnection<String, String> connection = redisClient.connect();
    // <2> 创建缓存访问器
    Map<String, String> clientCache = new ConcurrentHashMap<>(); //map 自动保存所有操作key的 key=value
    CacheFrontend<String, String> frontend = ClientSideCaching.enable(CacheAccessor.forMap(clientCache), connection,
        TrackingArgs.Builder.enabled());
    
    // <3> 客户端正常写入测试数据 k1 v1
    String key = "k1";
    commands.set(key, "v1");
    // <4> 循环读取
    while (true) {
    // <4.1> 缓存访问器中的值,查看是否和 Redis 服务端同步
    String cachedValue = frontend.get(key);
    System.out.println("当前 k1 的值为:--->" + cachedValue);
    Thread.sleep(3000);
    }
  • redis-cli 客户端同时操作 k1 修改 k1 的值

    ./redis-cli -h 127.0.0.1 -p 6379
    
    > set k1 v2
  • 注意查看 控制台日志

    ...
    当前 k1 的值为:--->v1
    当前 k1 的值为:--->v1
    当前 k1 的值为:--->v1
    当前 k1 的值为:--->v2
    当前 k1 的值为:--->v2
    当前 k1 的值为:--->v2
    ....

如上: k1 的值在其他客户端(redis-cli)修改,lettuce 客户端确实感知到了数据变化。 但 lettuce 到底 CacheFrontend.get 到底有没有查询 redis 呢?

我们可以通过以下监控看下客户端具体的操作细节

监控

./redis-cli -h 127.0.0.1 -p 6379

> MONITOR
OK
1595922453.165088 [0 172.16.1.96:57482] "SET" "k1" "v1"   # 对应 <3> 写入测试数据
1595922453.168238 [0 172.16.1.96:57483] "GET" "k1"        # <4.1> 缓存访问器中的值,由于第一次查询为空需要穿透去查询 redis-server
1595922466.525942 [0 172.16.1.96:57498] "COMMAND"         # 其他客户端 redis-cli 接入 提醒
1595922472.046488 [0 172.16.1.96:57498] "set" "k1" "v2"   # 其他客户端 操作 k1
1595922474.208214 [0 172.16.1.96:57483] "GET" "k1"        # 由于k1 值发生变化,循环 <4.1> 会重新查询redis-server

如上: 虽然是个死循环,但是关于 redis 操作只有以上注释的几条,说明客户端缓存生效。

总结

  • 当前仅有 lettuce 支持此功能,jedis 还未支持
  • spring-boot-data-redis 暂未支持此功能,估计需要 spring boot 2.5 版本
不与天斗Domino

不与天斗Domino

Programmer & Architect

183 日志
15 分类
224 标签
© 2013 - 2023 天地维杰网 京ICP备13019191号-1
Powered by - Hugo v0.63.2
Theme by - NexT
0%