使用JetCache的异步API访问Redis缓存
Jedis一直是Java中使用最广泛的Redis client,现在我们又有了一个新的选择:lettuce。
lettuce由Pivotal(也就是目前维护Spring的公司)的Mark Paluch发起,支持异步API和Reactive API,连接可以复用,近期开发也非常活跃,成为Redis客户端中的一个新锐。
JetCache提供的统一API也支持异步操作方式,当前,只有使用lettuce访问Redis能实现异步。
当下层使用的驱动不支持异步,比如访问Tair或者使用Jedis访问Redis时,会自动退化为同步堵塞的方式。所以从API上说,是完全兼容和一致的。
JetCache提供了简单易用的常规API(正常方法命名)和具有完整返回值的大写方法名API,异步API基于这些大写方法名的方法。
关于JetCache API的介绍请参考这里:https://github.com/alibaba/jetcache/wiki/CacheAPI_CN
为什么要异步访问缓存呢?虽然大部分情况下Redis缓存访问很快,但毕竟是一个网络IO操作,同步访问缓存多少也会增加一点RT,特别是在循环中操作缓存时,就积少成多了。
比如下面的例子从jdbc结果集读取了数据,然后写缓存:
//......获取数据库连接,执行SQL,得到ResultSet,省略 while(resultSet.next()){ User user = new User(); user.setId(resultSet.getLong("user_id")); //.....省略一部分设置用户属性的代码 cache.put(user.getId(), user); }
仔细分析一下就会发现,其实这个put方法完全没有必要同步执行,因为我们并不关心它的返回值(很多类似的场景下即使操作缓存出现了错误,我们也不能干什么,只能忽略错误继续处理)。
使用JetCache和lettuce的时候,我们什么都不用做,上面的代码的put操作就是异步的,它会马上返回,后续自动异步更新缓存,是不是很酷?
如果要显式的使用异步API,以GET方法为例:
CacheGetResult<UserDO> r = cache.GET(userId);
如果使用底层驱动不支持异步,那么GET方法就会堵塞直到缓存操作完成。
如果支持异步,这一行代码执行完以后,缓存操作可能还没有完成,此时调用r.isSuccess()或者r.getValue()或者r.getMessage()将会堵塞直到缓存操作完成。
如果不想被堵塞,并且需要在缓存操作完成以后执行后续操作,可以这样做:
CompletionStage<ResultData> future = r.future(); future.thenRun(() -> { if(r.isSuccess()){ System.out.println(r.getValue()); } });
以上代码将会在缓存操作异步完成后,在完成异步操作的线程中调用thenRun中指定的回调。
CompletionStage是Java8新增的功能,如果对此不太熟悉可以先查阅相关的文档。
需要注意的是,既然已经选择了异步的开发方式,在回调中不能调用堵塞方法,以免堵塞其他的线程(回调方法很可能是在event loop线程中执行的)。
部分常规api(方法名小写字母开头)由于没有返回值,因此不需要任何修改,它们直接就是异步的,比如put和removeAll方法;而get方法由于需要取返回值,所以仍然会堵塞。
使用lettuce作为客户端访问Redis还有另一个好处,就是不用配置连接池。
lettuce的连接是线程安全的可以复用,所以一个服务器维持一个Redis连接就好了。
对于一些云上的Redis,连接数可能是受限的,要支持更多连接就要付更多钱,这个时候lettuce就非常有优势了。这方面可以参考lettuce的文档获得更多信息:
https://github.com/lettuce-io/lettuce-core/wiki/Connection-Pooling
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
体验一键php/java环境安装工具oneinstack
概述 这个东西其实我很早之前就听说了,但是一直没有去尝试使用,我一直使用的是lnmp一键安装包,但是lnmp一键安装包是安装java环境的,oneinstack更强大一点 官网 https://oneinstack.com/ 环境准备 首先使用vagrant创建一个虚拟机,如果不会使用vagrant,那么就在我的博客里面搜索vagrant这个关键词就好了vagrant box add ubuntu/xenial64vagrant init ubuntu/xenial64vagrant upvagrant ssh 其实具体的操作和docker-machine差不多啦,就是它是针对虚拟机而不是容器而已 使用oneinstack 其实oneinstack源码存储在很多地方,国内阿里云和又拍云,国外Linode和sourceforge都有,所以不存在说我使用国外的服务器的时候下载源码很慢,或者使用国内服务器的时候下载源码很慢的问题,真的很良心,我是从又拍云下载的wget http://mirrors.linuxeye.com/oneinstack-full.tar.gz一般下载速度就是满速下载...
- 下一篇
Java基础8:深入理解内部类
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a724888/article/details/80087616 这位大侠,这是我的公众号:程序员江湖。 分享程序员面试与技术的那些事。 干货满满,关注就送。 本文主要介绍了Java内部类的基本原理,使用方法和各种细节。 有关内部类实现回调,事件驱动和委托机制的文章将在后面发布。 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech 文章首发于我的个人博客: https://h2pl.github.io/2018/04/25/javase8 内部类初探 一、什么是内部类? 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类 二、内部类的共性 (1)内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池