[转帖]Redis客户端Jedis、Lettuce、Redisson

redis,客户端,jedis,lettuce,redisson · 浏览次数 : 0

小编点评

**Redis 连接池的线程安全问题** Redis 连接池在多个线程使用同一个连接时存在线程安全问题,因为每个线程可能会访问相同的连接。为了解决这个问题,可以使用连接池来创建多个线程安全的连接。 **使用 JedisPool 创建连接池** ```java JedisPool pool = new JedisPool("localhost:6379", 10); ``` 其中: * `localhost` 是 Redis 主机地址 * `6379` 是 Redis 端口 * `10` 是连接池的大小 **使用 JedisPool 的方法获取连接** ```java Jedis jedis = pool.getResource(); ``` **使用 JedisPool 的方法释放连接** ```java jedis.close(); ``` **使用 Lettuce 创建线程安全连接池** Lettuce 是一个基于 Netty 的 Java 客户端,它提供了线程安全和异步模式支持。 ```java Lettuce.in.bound("localhost:6379").get(); ``` **与 Redisson 相比** Redisson 是一个 Java 客户端,它基于 Netty 与 Redis 建立连接。它提供了以下优点: * 更加简单 * 性能更高 * 支持异步请求 **结论** 使用 JedisPool 创建连接池可以解决 Redis 连接池在多个线程使用同一个连接时的线程安全问题。使用 Lettuce 创建线程安全连接池是一个更好的选择,因为它提供了线程安全、异步和响应式模式支持。

正文

https://www.jianshu.com/p/90a9e2eccd73

 

在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce

Jedis:采用的直连,BIO网络模型

Jedis有一个问题:多个线程使用一个连接的时候线程不安全。

解决思路是:

使用连接池,为每个请求创建不同的连接,基于Apache common pool实现。Jedis的连接池有三个实现:JedisPool,ShardedJedisPool,JedisSentinelPool,都是用getResource从连接池获取一个连接。

public class JedisPoolTest {

    public static void main(String[] args) {

        ordinaryPool();

        shardedPool();

        sentinelPool();

    }

    /**

    * 普通连接池

    */

    public static void ordinaryPool(){

        JedisPool pool = new JedisPool("这个参数是ip地址",6379);

        Jedis jedis = pool.getResource();

        jedis.set("shihui","石灰");

        System.out.println(jedis.get("shihui"));

    }

    /**

    * 分片连接池

    */

    public static void shardedPool() {

        JedisPoolConfig poolConfig = new JedisPoolConfig();

        // Redis服务器

        JedisShardInfo shardInfo1 = new JedisShardInfo("这个参数是ip地址", 6379);

        // 连接池

        List<JedisShardInfo> infoList = Arrays.asList(shardInfo1);

        ShardedJedisPool jedisPool = new ShardedJedisPool(poolConfig, infoList);

        ShardedJedis jedis = jedisPool.getResource();

        jedis.set("shihui","分片测试");

        System.out.println(jedis.get("shihui"));

    }

    /**

    * 哨兵连接池

    */

    public static void sentinelPool() {

        String masterName = "redis-master";

        Set<String> sentinels = new HashSet<String>();

        sentinels.add("这个参数是ip地址1:26379");

        sentinels.add("这个参数是ip地址2:26379");

        sentinels.add("这个参数是ip地址3:26379");

        JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels);

        pool.getResource().set("shihui", "哨兵" + System.currentTimeMillis() + "石灰");

        System.out.println(pool.getResource().get("shihui"));

    }

}

 

Lettuce:采用netty,NIO模式

支持同步、异步和响应式模式(Reactive)

实例可以在多个线程中进行共享,不存在线程不安全的情况。

 
比较

 

Redisson:

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid),提供了分布式和可扩展的Java数据结构,比如分布式的Map,List.,Queue,Set,不需要自己去运行一个服务实现。

基于Netty实现,采用非阻塞10,性能高;支持异步请求。

支持连接池、pipeline、LUA Scripting.Redis Sentinel,Redis Cluster不支持事务,官方建议以LUA Scripting代替事务

主从、哨兵、集群都支持。Spring也可以配置和注入RedissonClient。

在Redisson里面提供了更加简单的分布式锁的实现。

 

public static void main(String[]args)throws InterruptedException{

RLock rLock-redissonClient.getLock("updateAccount");

//最多等待100秒、上锁10s以后自动解锁

if(rLock.tryLock(100,10,TimeUnit.SECONDS)){

System.out.println("获取锁成功");

}

// do something

rLock.unlock();

}

 

参考:

https://blog.csdn.net/shihui_0516/article/details/110409135?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-110409135-blog-117781602.t5_refersearch_landing&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-110409135-blog-117781602.t5_refersearch_landing&utm_relevant_index=4

与[转帖]Redis客户端Jedis、Lettuce、Redisson相似的内容:

[转帖]Redis客户端Jedis、Lettuce、Redisson

https://www.jianshu.com/p/90a9e2eccd73 在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce Jedis:采用的直连,BIO网络模型 Jedis有一个问题:多个线程使用一个连接的时候线程不安全。 解决思路是: 使用连接池,为每个请求创建

[转帖]Redis进阶实践之十七 Redis协议的规范

https://www.cnblogs.com/PatrickLiu/p/8567453.html 一、介绍 Redis客户端使用RESP(Redis的序列化协议)协议与Redis的服务器端进行通信。 虽然该协议是专门为Redis设计的,但是该协议也可以用于其他 客户端-服务器 (Client-Se

[转帖]Redis Pipeline使用

https://www.cnblogs.com/-wenli/p/12922089.html 为什么使用 Pipeline? Redis客户端执行一条命令分为如下四个过程: 发送命令 命令排队 命令执行 返回结果 其中,1到4称为Round Trip Time(RTT,往返时间)。 Redis提供了

[转帖]Redis:我是如何与客户端进行通信的

江湖上说,天下武功,无坚不摧,唯快不破,这句话简直是为我量身定制。 我是一个Redis服务,最引以为傲的就是我的速度,我的 QPS 能达到10万级别。 在我的手下有数不清的小弟,他们会时不时到我这来存放或者取走一些数据,我管他们叫做客户端,还给他们起了英文名叫 Redis-client。 有时候一个

[转帖]Redis 最大客户端连接数,你了解吗?

文章系转载,方便整理和归纳,源文地址:https://cloud.tencent.com/developer/article/1803944 1. 前言 上一篇文章《你的Redis集群撑得住吗?》讲了应用增加pod时,有一个应用最大连接数计算公式为:maxTotal * pod数 < Redis c

[转帖]一文带你玩转 Redis 的 RESP 协议 !

https://zhuanlan.zhihu.com/p/384251739 RESP 是 Redis 客户端与 Redis 服务器相互通信时使用的一个协议, 全称 REdis Serialization Protocol ,即 redis 串行协议,通俗易懂,也表明了 redis 的特点,串行化(

[转帖]Redis 性能优化的 13 条军规!史上最全

https://zhuanlan.zhihu.com/p/118532234 Redis性能优化实战方案 Redis 是基于单线程模型实现的,也就是 Redis 是使用一个线程来处理所有的客户端请求的,尽管 Redis 使用了非阻塞式 IO,并且对各种命令都做了优化(大部分命令操作时间复杂度都是 O

[转帖]Redis性能之内部阻塞式操作及应对方法

文章目录 Redis实例都有哪些阻塞点和客户端交互的阻塞点集合的全量查询和聚合操作bigkey删除操作清空数据库 磁盘交互的阻塞点主从节点交互时的阻塞点切片集群实例交互时的阻塞点可以异步执行的阻塞点异步的子线程总结 Redis的网络IO和键值对读写都是由主线程完成的。 Redis实例都有哪些阻塞点

[转帖]Redis进阶(发布订阅,PipeLine,持久化,内存淘汰)

目录 1、发布订阅 1.1 什么是发布订阅 1.2 客户端实例演示 1.3 Java API演示 1.4 Redis发布订阅和rabbitmq的区别 2、批量操作 2.1 普通模式与 PipeLine 模式 2.2 适用场景 2.3 源码解析 2.4 Pipelining的局限性 2.5 事务与 L

[转帖]redis惰性删除 lazy free 源码剖析,干货满满

目录 前言 数据删除场景 lazy free 概念 配置 源码剖析(版本 6.2.6) 场景一:客户端执行的显示删除/清除命令 场景二:某些指令带有的隐式删除命令 场景三:删除过期数据 场景四:内存淘汰数据删除 场景五:主从同步清空从库 小结 前言 都说 redis 是单线程的,其实并不是说 red