常用的操作redis的客户端工具
jedis
Jedis 是 Redis 官方推荐的 Java 连接开发工具,jedis非线程安全。
但是可以通过JedisPool连接池去管理实例,在多线程情况下让每个线程有自己独立的jedis实例,可变为线程安全。
Lettuce
Lettuce 是基于 Netty框架(NIO)的事件驱动的通信,支持同步和异步调用的,可扩展的 redis client,多个线程可以共享一个 RedisConnection,线程安全。
SpringBoot2.0之后默认都是使用的Lettuce这个客户端连接Redis服务器。Lettuce 是一种可扩展的、线程安全的 Redis 高级客户端。
Redisson
Redisson 是一个在 Redis 的功能基础上实现的 Java 驻内存数据网格客户端。实现了分布式和可扩展的 Java 数据结构,提供很多分布式相关操作服务,例如分布式锁,分布式集合,可通过 Redis 支持延迟队列。
小结
Jedis 和 Lettuce 两者相比,Jedis 的性能比较差,其他方面并没有太明显的区别,所以如果你不需要使用 Redis 的高级功能的话,优先推荐使用 Lettuce。
相比于 Jedis、Lettuce 等基于 redis 命令封装的客户端,Redisson 提供的功能更加高端和抽象,逼格简单使用
jedis和lettuce简单使用:https://juejin.cn/post/6844903681087930375,文章中的使用用lettuce时,需添加commons-pool2依赖。
jedis线程不安全
以set方法举例
Jedis jedis = new Jedis();
jedis.set("1","1");
1、
一步步点进去Jedis.set->Client.set->BinaryClient.set->Connection.sendCommand
可以看出来 每次执行set方法都要进行connect方法,点进connect方法
可以看出来一个实例共用一个socket、 outputStream、inputStream。问题也就出现了。来看下jedisSocketFactory.createSocket的方法
问题解说:这样就清晰明了了,共用socket,在多线程执行下,如果线程2走到了获取outputStream或者inputStream的方法,而线程1走到了刚刚new完socket,是不是就出现问题了。
2、
眼尖的人可能会看到
如果我提前连接比如以下,是不是不会出问题了,并不是
Jedis jedis = new Jedis();
jedis.connect();
jedis.set("1","1");
别忘了还共享了 outputStream、inputStream。我们直接来到发送命令的最后Protocol的sendCommand方法
问题解说:因为共享了os,使得线程1正在正常发送指令,线程2突然插入一脚,让发送到服务端的指令不能被服务端识别,所以还可能出现连接断开等问题。
总结
不总结了,自己看吧。着急下班。
版权归原作者 明天一定. 所有, 如有侵权,请联系我们删除。