序言
本文意在介绍 redis 的非阻塞客户端 lettuce 的用法,比起jedis 客户端来说, lettuce 的异步特性和 底层的 nio 异步加持,显得 更加好用且高性能。
正文
关于远程 客户端 代码连接的通用设计的思考
常见 客户端连接的通用逻辑,redis 客户端 lettuce 也遵循了通常的连接流程
- 构建 连接 connect uri , 根据不同的客户端,schema 有所不同,类似 mysql 的连接schema 以 mysql::// 开始,而redis 连接schema 以 redis:// 开始
- 通过 connect uri 构造 连接 client
- 根据连接 client,构建 connection,每个connection 对不同的操作应该是不同的,而client 资源确是共享同步的
- 一般来说拿到connection 以后,就可以就行命令传递了,一般来说较为方便的连接客户端,会提供较为方便的连接操作,类 lettuce ,每个connect 需要进行的命令传递操作,在此基础上
抽象出 COMMAND 对象,每个COMMAND 就是 redis client 的COMMAND 抽象
5. 还有一点时,由于connection 的获取是需要付出一定代价的,所以现代客户端,都很喜欢配合 池化技术,节省一部分这样的开销,利用共享连接池, 例如 apache 的common pool 来进行配置池,可以猜想只要是用的是 cs 模型的基础组件,
我们在配置的时候就可以考虑,是否在客户端进行远端链接的时候进行池化技术的优化。
在此抽象概括下,连接客户端的一些通用设计理念,在此基本基础上的连接逻辑
- 首先我们要进行客户端远程命令的代码执行,connection 这个概念是各个 连接客户端都绕不过去的,为了生成这个connection, 像spring-redis 为例,spring-redis 里面的 redisTemplate 里面需要配置好 connectFactory,然后进行获取每次命令执行
的连接操作,而此时 的redisTemplate 可以认为是 lettuce里面的 client角色,是为了拿到connection的存在,拿到connection之后,可能在此基础上进行 命令传递的操作,然后在此基础上 spring-redis 抽象出了 Operation 的概念,各种对redis不同数据结构的操纵
都可以通过Operation 的api 来操纵,然后传递给远端 redis server
2. 以 java mysql connector 客户端举例的话,同样可以看到 这么几个角色, 首先是DriverManager ,类比上图,这其实就是 Client的角色,用来获取Connection的。拿到Connection以后, 要执行sql 命令了,怎么操作你,它在Connection传递命令的前提下
抽象出来 Statement这个概念,可以认为这个Statement就是一次事务或者读操作,类似于lettuce的 COMMAND角色,然后结果用ResultSet进行存储,以此可知。
3. 像 kafka 的客户端, spring kafka 的客户端设计, 其中 消费监听者这样的角色比较不同,因为生产消费者,涉及到的命令比较少,所以在消费端直接就通过 注解 @KafkaListener 加在方法上的方式来直接监听messager了,而生产者 对mq生产消息的方式是通过KafkaTemplate
的方式来执行的,此 KafkaTemplate 的构成 也是需要知道远端mq的连接方式的,其内部构成为需要 ProducerFactory来组成,这个ProduceFactory 类似于 lettuce Client的存在了,相当于每次发送 message 给mq ,都要新产生一个网络连接,产生连接,名字也和Factory相互照应。
像常见的 解码器和编码器也需要在 Template 这一层进行配置,在此不表,像RedisTemplate也是同样的设计理念。 KafkaTrancationManager 和 mysql 的TrancationManager 的角色类似,当配置也是同样的 需要 produceFactory 进行配置, TrancationMnager → ProduceFactory,
像KafkaTrancationManger的使用意义在于,和数据库一样,在@Transaction 修饰的方法上,如果抛异常,则消息不会发送
4. 以 es 举例的话,官网提供的 es 的客户端,特定维护了两个版本,一个 是low level 为了兼容所有版本的es, 一个是high level 的 rest client , 以high level 的 client 来看,它同样是是以client 角色,来执行 命令的Request 封装,得到一个Response,在此就忽略了 Connection 这样的概念,封装在Client 的请求里面
lettuce 支持的 基本操作语法支持,和接口设计抽象
lettuce 支持三种范式调用
- 同步 2.异步 3. react 式
2. 单机和集群的 connection, pub 和sub connection 分别获取