Redis 高级 Java 客户端 Lettuce 的用法及踩坑经验

作者/分享人:应书澜
向 Ta 提问
毕业于C9高校,硕士学历,曾在IEEE ITS、VSD等Top期刊发表论文。多年研发经验,擅长嵌入式&物联网相关技术,预测算法,分布式中间件,精通Java、Python及C语言;曾在华为、阿里巴巴,上海电气,浙能集团等公司重要项目中担任技术负责人或核心研发成员,现专注于中间件技术。

如果你在网上搜索 Redis 的 Java 客户端,你会发现,大多数文献介绍的都是 Jedis,不可否认,Jedis 是一个优秀的基于 Java 语言的 Redis 客户端,但是,其不足也很明显:Jedis 在实现上是直接连接 Redis-Server,在多个线程间共享一个 Jedis 实例时是线程不安全的,如果想要在多线程场景下使用 Jedis,需要使用连接池,每个线程都使用自己的 Jedis 实例,当连接数量增多时,会消耗较多的物理资源。

与 Jedis 相比,Lettuce 则完全克服了其线程不安全的缺点:Lettuce 是一个可伸缩的线程安全的 Redis 客户端,支持同步、异步和响应式模式。多个线程可以共享一个连接实例,而不必担心多线程并发问题。它基于优秀 Netty NIO 框架构建,支持 Redis 的高级功能,如 Sentinel,集群,流水线,自动重新连接和 Redis 数据模型。

本场 Chat 将介绍以下内容:

  1. Lettuce 重要接口介绍;
  2. Redis单机模式下,Lettuce 的使用;
  3. Redis集群模式下,Lettuce 的使用;
  4. 使用 Lettuce 创建 Redis 集群;
  5. 使用 Lettuce 监控 Redis;
  6. Lettuce 使用过程中的“坑”:堆内存溢出和堆外内存溢出。
已有238人预订
预订达标
文章出炉
     
06月25日
07月06日
本场 Chat 文章已出炉,购买后即可阅读文章并获得一张应书澜的读者圈Pass
请务必添加GitChat服务号以查看活动进度及获取活动通知。
查看文章评论/提问
fighting
不值这个钱
应书澜: 欢迎批评指正
清风与我
题主的文章不错,但是我想吐槽一下gitchat的下载pdf功能。建议还是禁止掉吧,在其它浏览器打开要我先下载qq浏览器,好吧我下载,下载了qq浏览器,重复操作,在qq浏览器打开,点击下载,又提示我下载qq浏览器。逆天么要!!!浪费时间和流量!!!
康文
生产上也这么用? 感觉不妥啊 题主还是没有交代清楚 集群模式下主从切换了,客户端是怎么热感知的,如何动态切换的。 其实我是想跟楼主咨询下 netty内存泄漏相关问题的, 当前已经发现这个问题了,处于潜伏期,但是还没爆发。我用的是springboot 集成 spring-boot-starter-data-redis(2.0.3RELEASE) 搭建的单机模式,spring-boot-starter-data-redis(2.0.3RELEASE)依赖的netty是4.1.25Final版,使用这个构造函数new LettuceConnectionFactory(redisStandaloneConfiguration(), lettuceClientConfiguration); 关键代码:【 private RedisStandaloneConfiguration redisStandaloneConfiguration() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName(host); redisStandaloneConfiguration.setPort(port); return redisStandaloneConfiguration; } /** * 单机模式连接工厂 * * @return LettuceConnectionFactory */ @Bean public LettuceConnectionFactory standaloneLettuceConnectionFactory() { LettuceClientConfiguration lettuceClientConfiguration = getLettuceClientConfiguration(); LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration(), lettuceClientConfiguration); lettuceConnectionFactory.afterPropertiesSet(); return lettuceConnectionFactory; } private LettuceClientConfiguration getLettuceClientConfiguration() { GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxTotal(maxActive); poolConfig.setMaxIdle(maxIdle); poolConfig.setMinIdle(minIdle); poolConfig.setMaxWaitMillis(maxWait); return LettucePoolingClientConfiguration.builder() .poolConfig(poolConfig) .shutdownTimeout(Duration.ZERO) .build(); } 】 启动时报(目前不知道如何导致的,虽然不影响启动,但是肯定不妥): 2018-10-07 16:49:36,761 code-app [Finalizer] WARN io.netty.util.internal.logging.Slf4JLogger.warn(131) -io.lettuce.core.resource.DefaultClientResources was not shut down properly, shutdown() was not called before it's garbage-collected. Call shutdown() or shutdown(long,long,TimeUnit) 2018-10-07 16:49:36,893 code-app [main] ERROR io.netty.util.internal.logging.Slf4JLogger.error(171) -LEAK: HashedWheelTimer.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information. Recent access records: Created at: io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:272) io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:216) io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:195)... 最后建议楼主既然是分享开源技术,就不要做强制打赏了, 不利于技术交流。
你可能还喜欢
如何成为一名合格的 C/C++ 开发者?
范蠡
微服务中的短信服务如何设计?
猿天地
亿级 QQ 会员活动运营系统的设计之道
廖声茂
数据科学 Kaggle 比赛项目实战:Titanic
刘明
分布式日志收集系统 Flume 应用:实时采集 Python 爬取豆瓣最新电影
Enzo
Hadoop 分布式数据存储层 HDDS:基于容器化的块服务架构层
爱闲逛的猿仔
微信扫描登录