在Redis官网中提供了各种语言的客户端,地址: https://redis.io/docs/latest/develop/clients/
Jedis
以Redis命令做方法名称,学习成本低,简单实用,但是对于Jedis实例是线程不安全的(即创建一个Jedis实例,多线程并发运行时会有线程安全问题,在多线程使用时,必须为每一个线程创建独立的Jedis连接,就是必须要使用连接池的方式来配合使用。)多线程环境下需要基于连接池来使用。
lettuce
Lettuce是基于Netty实现的,支持同步、异步、和响应式编程方式,并且是线程安全的,支持Redis的哨兵模式、集群模式、和管道模式。与spring结构契合度较高,且数据吞吐量也很不错,因此spring工程也默认兼容lettuce模式
Redisson
Redisson是一个基于Redis实现的分布式、可伸缩的Java数据结构集合。包括了Map,Queue,Lock,Semaphore,AtomicLog等强大功能
Jedis快速入门
Jedis官网地址:redis/jedis: Redis Java client 快速入门:
-
引入依赖
<!-- 引入Jedis依赖-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
<dependencies>
<!-- 引入Jedis依赖-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
</dependencies>
-
建立连接
public class JedisTest {
private Jedis jedis;
@BeforeEach
void setUp(){
//1.建立连接
jedis = new Jedis("127.0.0.1",6379);
//2.选择数据库
jedis.select(0);
}
@Test
void testString(){
//存入数据
String result = jedis.set("name", "lyc");
System.out.println("result = "+result);
//获取数据
String name = jedis.get("name");
System.out.println("name = "+name);
}
-
使用Jedis,方法名与Redis命令一致
@Test
void testList(){
//存入数据
jedis.lpush("mylist","1","2","3");
for (String s : jedis.lrange("mylist", 0, -1)) {
System.out.println("s = "+s);
}
}
@Test
void testHash(){
//存入数据
jedis.hset("user:1","name","jack");
jedis.hset("user:1","age","21");
//获取数据
Map<String, String> map = jedis.hgetAll("user:1");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+" = "+entry.getValue());
}
}
-
测试
-
释放资源
@AfterEach
void tearDown(){
//关闭连接
if (jedis!=null) {
jedis.close();
}
}
}
注意事项:在释放资源时并不是单纯的close()方法,而是底层调用returnResource()方法
public void close() {
if (this.dataSource != null) {
Pool<Jedis> pool = this.dataSource;
this.dataSource = null;
if (this.isBroken()) {
pool.returnBrokenResource(this);
} else {
pool.returnResource(this);
}
} else {
this.connection.close();
}
}
Jedis连接池
Jedis本身是线程不安全的,在多线程的环境下,并发访问Jedis可能会导致线程安全问题.
因此在并发的环境下,Jedis需要给每一个线程创建独立的Jedis对象。
此时最好的方案时使用线程池,并且频繁的创建和销毁Jedis对象(连接)会有性能损耗,因此推荐使用Jedis连接池代替Jedis的直连方式。
Jedis连接池使用说明:
定义JedisConnectionFactory工具类:
首先声明静态变量 Jedispool(Jedis连接池),通过静态代码块将Jedispool配置初始化。
静态代码块中,先新建一个JedisPoolConfig(Jedis连接池配置)实例化对象,配置JedisPoolConfig对象的参数,通过其设置最大连接数,最大空闲连接,最小空闲连接,以及最长等待时间(单位为毫秒)。
最终通过JedisPool的有参构造方法将配置,主机号,端口号,超时时间,以及密码传入JedisPool对象。
最后提供了静态方法getJedis用来拿到Jedis对象(实际是调用JedisPool的getResource()方法)。
只要调用这个工具类的getJedis方法就能拿到Jedis对象,都是从连接池获取,用完之后返回到池中,这样就避免了频繁的创建与销毁Jedis对象。
代码如下:
public class JedisConnectionFactory {
private static JedisPool jedisPool;
static {
//配置连接池
JedisPoolConfig config = new JedisPoolConfig();
// 最大连接数
config.setMaxTotal(10);
// 最大空闲连接数
config.setMaxIdle(5);
// 最小空闲连接
config.setMinIdle(5);
// 获取连接时的最大等待毫秒数
config.setMaxWaitMillis(1000);
// 在获取连接的时候检查有效性
config.setTestOnBorrow(true);
//创建连接池对象
jedisPool = new JedisPool(config,"192.168.1.100", 6379);
}
// 获取Jedis实例
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
将原来的直接新建Jedis对象改为使用连接池
@BeforeEach
void setUp(){
//1.建立连接
jedis = JedisConnectionFactory.getJedis();
//2.选择数据库
jedis.select(0);
}
再次测试
测试成功。
总结:Jedis中的所有方法都是我们在Redis中学到的命令,这样虽然降低了学习难度,但是导致Jedis显得非常臃肿,因此我们接下来学习的就是由spring整合的SpringDataRedis。
希望对大家有所帮助