【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 ...
随机推荐
- 从键盘读入学生成绩,找出最高分, 并输出学生成绩等级(Java)
从键盘读入学生成绩,找出最高分, 并输出学生成绩等级 一.题目 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10 等级为'A' 成绩>=最高分-20 等级为'B' ...
- python学习9 函数的基础知识
1.函数的定义 def func(): 2.函数的调用 func() 3.函数的返回值 #1.没有返回值 # (1)不写return # (2)只写return后面的代码不在继续执行,返回空,代表结 ...
- 攻防世界 reverse elrond32
tinyctf-2014 elrond32 1 int __cdecl main(int a1, char **arg_input) 2 { 3 if ( a1 > 1 && c ...
- asp.net core 2.0 web api + Identity Server 4 + angular 5 可运行前后台源码
前台使用angular 5, 后台是asp.net core 2.0 web api + identity server 4. 从头编写asp.net core 2.0 web api 基础框架: 第 ...
- Android Studio 之 RadioButton
•任务 如何通过 RadioButton 实现如图所示的界面? •基本用法 RadioButton 单选按钮,就是只能够选中一个,所以我们需要把 RadioButton 放到 RadioGroup 按 ...
- SqlServer视图的创建与使用
SqlServer系列之视图的创建与使用: 什么是视图? 视图的概述 在数据查询中,可以看到数据表设计过程中,考虑到数据的冗余度低.数据一致性等问题,通常对数据表的设计要满足范式的要求,因此也会造成一 ...
- windows平台rust安装
1.安装目录环境变量 RUSTUP_HOME D:\WorkSoftware\Rust\cargo CARGO_HOME D:\WorkSoftware\Rust\rustup 2.安装下载加速环境变 ...
- 20182217_刘洪宇 后门原理与实践 EXP2
1.后门概念 后门就是不经过正常认证流程而访问系统的通道. 哪里有后门呢? 编译器留后门 操作系统留后门 最常见的当然还是应用程序中留后门 还有就是潜伏于操作系统中或伪装为特定应用的专用后门程序. - ...
- Swagger3注解使用
这里只简单的说一下swagger的传值,返回值时注解的使用演示.相关注解及说明见其他文章 接收参数方式1 我们常规接收参数,可以使用一个类,类里面把属性作为接收的参数,使用注解对属性进行说明.但是这种 ...
- [C++]一篇文章搞懂C++中五花八门的各种初始化
总结 初始化的概念:创建变量时赋予它一个值(不同于赋值的概念) 类的构造函数控制其对象的初始化过程,无论何时只要类的对象被创建就会执行构造函数 如果对象未被用户指定初始值,那么这些变量会被执行默认初始 ...