【Redis破障之路】四:Jedis基本使用
在前面我们已经学习了Redis命令行客户端redis-cli的使用,接下来我们了解一下Redis基于Java编程语言的客户端。
在Java语言体系下,有三个常用的Redis客户端Jedis
、Redisson
、Lettuce
。三者各有特点,各有适用的场景。
Jedis
:Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Jedis中的方法调用是比较底层的暴露的Redis的API,也即Jedis中的Java方法基本和Redis的API保持着一致,了解Redis的API,也就能熟练的使用Jedis。
Redisson
:实现了分布式和可扩展的Java数据结构,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列。和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。Redisson中的方法则是进行比较高的抽象,每个方法调用可能进行了一个或多个Redis方法调用。
Lettuce
:高级Redis客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。是SpringBoot2.x版本默认的客户端。
好了,我们开始学习Jedis的使用吧。
1、Jedis的基本使用
创建Maven工程,在项目中添加Jedis依赖。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.2</version>
</dependency>
Jedis的使用方法非常简单,只要三行代码就可以实现基本的set/get功能:
//1.生成一个Jedis对象,这个对象负责和指定Redis实例进行通信
Jedis jedis = new Jedis("127.0.0.1", 6379);
// 2.jedis执行set操作
jedis.set("hello", "world");
//3.jedis执行get操作,value="world"
String value = jedis.get("hello");
初始化Jedis需要两个参数:Redis实例的IP和端口,除了这两个参数外,还有一个包含了四个参数的构造函数是比较常用的:
Jedis(final String host, final int port, final int connectionTimeout, final int soTimeout)
参数说明:
- host:Redis实例的所在机器的IP
- port:Redis实例的端口
- connectionTimeout:客户端连接超时
- soTimeout:客户端读写超时
可以打印输出一下上面程序的结果:
和JDBC类似,一般涉及到这种网络I/O的操作,最好使用try catch finally的形式,稍微修改一下上面的例子:
Jedis jedis = null;
try {
jedis = new Jedis("127.0.0.1", 6379);
jedis.get("hello");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
}
接下来我们看一下Jedis对各种基本数据类型的操作:
- 字符串
jedis.set("hello", "world");
//结果 world
System.out.println(jedis.get("hello"));
//结果 1
System.out.println(jedis.incr("counter"));
- hash
jedis.hset("myhash", "f1", "v1");
jedis.hset("myhash", "f2", "v2");
//运行结果 {f2=v2, f1=v1}
System.out.println(jedis.hgetAll("myhash"));
- list
jedis.rpush("mylist", "1");
jedis.rpush("mylist", "2");
jedis.rpush("mylist", "3");
//运行结果 [1, 2, 3]
System.out.println(jedis.lrange("mylist",0,-1));
- set
jedis.sadd("myset", "a");
jedis.sadd("myset", "b");
jedis.sadd("myset", "a");
//运行结果 [b, a]
System.out.println(jedis.smembers("myset"));
- zset
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.zadd("thezset", 99, "tom");
jedis.zadd("thezset", 66, "peter");
jedis.zadd("thezset", 33, "james");
//运行结果 james 33.0 peter 66.0 tom 99.0
jedis.zrangeWithScores("thezset",0,-1).stream().forEach(s->{
System.out.print(s.getElement()+" "+s.getScore()+" ");
});
2、序列化
在Java中,存储对象一般会进行序列化和反序列化,Jedis本身并不支持序列化。可以引入游戏额第三方的序列化工具,例如XML、Json、谷歌的Protobuf、Facebook的Thrift等等。
我们以protostuff(Protobuf的Java客户端)为例来进行学习:
- 引入protostuff依赖
<properties>
<protostuff.version>1.0.11</protostuff.version>
</properties>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>${protostuff.version}</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>${protostuff.version}</version>
</dependency>
- 定义实体类
public class Club implements Serializable {
private int id; // id
private String name; // 名称
private String info; // 描述
private Date createDate; // 创建日期
private int rank; // 排名
//省略getter/setter等
}
- 测试序列化和反序列化
// 1.生成序列化工具类
ProtostuffSerializer protostuffSerializer = new ProtostuffSerializer();
// 2.生成Jedis对象
Jedis jedis = new Jedis("127.0.0.1", 6379);
// 3.序列化
String key = "club:1";
// 定义实体对象
Club club = new Club(1, "AC", "米兰", new Date(), 1);
// 序列化
byte[] clubBtyes = protostuffSerializer.serialize(club);
jedis.set(key.getBytes(), clubBtyes);
// 4.反序列化
byte[] resultBtyes = jedis.get(key.getBytes());
Club resultClub = protostuffSerializer.deserialize(resultBtyes);
//结果 Club{id=1, name='AC', info='米兰', createDate=Sat May 15 22:21:42 CST 2021, rank=1}
System.out.println(resultClub.toString());
3、Jedis连接池
在上面我们使用的是Jedis的直连方式,每次都会新建TCP 连接,使用后再断开连接。
这种频繁的连接/断开连接的过程显然是对资源的一种浪费。
和数据库连接池一样,同样可以引入池化技术,将Jedis连接存在池子(JedisPool)里,每次去池子里取,而不用重新创建。
连接池的方式是可以预先初始化好Jedis连接,所以每次只需要从 Jedis连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。
Jedis提供了JedisPool这个类作为对Jedis的连接池,同时使用了Apache的通用对象池工具common-pool作为资源的管理工具。
使用JedisPool操 作Redis示例如下:
1)Jedis连接池(通常JedisPool是单例的):
// common-pool连接池配置,这里使用默认配置
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 初始化Jedis连接池
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
2)获取Jedis对象不再是直接生成一个Jedis对象进行直连,而是从连接池直接获取:
Jedis jedis = null;
try {
// 1. 从连接池获取jedis对象
jedis = jedisPool.getResource();
// 2. 执行操作
jedis.get("hello");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
// 如果使用JedisPool,close操作不是关闭连接,代表归还连接池
jedis.close();
}
}
面GenericObjectPoolConfig使用的是默认配置,实际它提供有很多参数,例如池子中最大连接数、最大空闲连接数、最小空闲连接数、连接活性检测,等等。
参考:
【1】:《Redis开发与运维》
【2】:redis几种java客户端比较
【Redis破障之路】四:Jedis基本使用的更多相关文章
- 【Redis破障之路】二:Redis安装和基本数据结构
1.安装Redis Redis6.0在2020年已经发布,所以我们安装Redis3.0. 1.1.在Linux上安装Redis 我们在CentOS上安装Redis.常见的的有三种安装方式: yum/a ...
- 【Redis破障之路】三:Redis单线程架构
众所周知,Redis是一个单线程架构的NoSQL数据库,但是是单线程模型的Redis为什么性能如此之高?这就是我们接下来要探究学习的内容. 1.Redis的单线程架构 1.1.Redis单线程简介 首 ...
- redis中各种数据类型对应的jedis操作命令
redis中各种数据类型对应的jedis操作命令 一.常用数据类型简介: redis常用五种数据类型:string,hash,list,set,zset(sorted set). 1.String类型 ...
- 我的VSTO之路(四):深入介绍Word开发
原文:我的VSTO之路(四):深入介绍Word开发 在上一篇文章中,我介绍了Word的对象模型和一些基本开发技巧.为了更好的介绍Word插件开发,我为本文制作了一个Word书签的增强版,具体功能是让用 ...
- Redis入门很简单之六【Jedis常见操作】
Redis入门很简单之六[Jedis常见操作] http://www.tuicool.com/articles/vaqABb http://www.cnblogs.com/stephen-liu74/ ...
- Redis源码阅读(四)集群-请求分配
Redis源码阅读(四)集群-请求分配 集群搭建好之后,用户发送的命令请求可以被分配到不同的节点去处理.那Redis对命令请求分配的依据是什么?如果节点数量有变动,命令又是如何重新分配的,重分配的过程 ...
- python 闯关之路四(下)(并发编程与数据库编程) 并发编程重点
python 闯关之路四(下)(并发编程与数据库编程) 并发编程重点: 1 2 3 4 5 6 7 并发编程:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别 ...
- Redis的三个框架:Jedis,Redisson,Lettuce
Jedis api 在线网址:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html redisson 官网地址: ...
- Redis 主从、哨兵Sentinel、Jedis
Redis 主从.哨兵Sentinel.Jedis 2017年02月15日 15:52:48 有且仅有 阅读数 6183 文章标签: redis主从sentineljedis 更多 分类专栏: 7/1 ...
随机推荐
- go语言的初体验
分享最近学习 Go 语言的心得和体会,适合有编程基础的人,因为这里只做经验性的总结概述,不做基础教学的入门知识讲解,如果想要学习编程语言的基础知识,请出门左转进入官方文档,查看基础教学文档. Go 概 ...
- 【Spring Cloud & Alibaba全栈开源项目实战】:SpringBoot整合ELK实现分布式登录日志收集和统计
一. 前言 其实早前就想计划出这篇文章,但是最近主要精力在完善微服务.系统权限设计.微信小程序和管理前端的功能,不过好在有群里小伙伴的一起帮忙反馈问题,基础版的功能已经差不多,也在此谢过,希望今后大家 ...
- Android Studio 之 CheckBox
•任务 •基本用法 CheckBox,复选框,即可以同时选中多个选项. 从网上找了三个图标,分别命名为 apple.jpg , banana.jpg , oranges.jpg 放置在了 drawab ...
- 冒泡排序(BubbleSort)
介绍: 冒泡排序是一种最基础的交换排序(两两比较待排序的关键字,交换不满足次序要求的那对数,直到整个表都满足次序要求为止),工作方式如同碳酸饮料中的二氧化碳气泡最终会上浮到顶端一样,故名"冒 ...
- PReact10.5.13源码理解之hook
hook源码其实不多,但是实现的比较精巧:在diff/index.js中会有一些optison.diff这种钩子函数,hook中就用到了这些钩子函数. 在比如options._diff中将curr ...
- [.net] 关于Exception的几点思考和在项目中的使用(一)
本文链接 https://www.cnblogs.com/hubaijia/p/about-exceptions-1.html 关于exception的基本语法和作用,这里不再赘述,下面记录一下我在项 ...
- ON DUPLICATE KEY UPDATE作用
ON DUPLICATE KEY UPDATE作用 先声明一点,ON DUPLICATE KEY UPDATE为Mysql特有语法,这是个坑 语句的作用,当insert已经存在的记录时,执行Updat ...
- DDD实战让中台和微服务的落地如虎添翼
微服务到底怎么拆分和设计才算合理,拆多小才叫微服务?有没有好的方法来指导微服务和中台的设计呢? 深入DDD的核心知识体系与设计思想,带你掌握一套完整而系统的基于DDD的微服务拆分与设计方法,助力落地边 ...
- JVM调试命令简介
1.JPS(查JAVA进程) 2.jinfo(查看正在运行java应用程序的扩展参数,包括Java System属性和JVM命令行参数:也可以动态的修改正在运行的JVM一些参数) 大部分的运行期参数是 ...
- 全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架
目录 一.前言 二.RPC 基础概念 1. RPC 是什么? 2. 需要解决什么问题? 3. 有哪些开源实现? 三.protobuf 基本使用 1. 基本知识 2. 使用步骤 四.libevent 1 ...