设为首页 加入收藏

TOP

Redis 异步客户端选型及落地实践(一)
2023-07-26 08:17:11 】 浏览:73
Tags:Redis 步客户

作者:京东科技 王晨

Redis异步客户端选型及落地实践

可视化服务编排系统是能够通过线上可视化拖拽、配置的方式完成对接口的编排,可在线完成服务的调试、测试,实现业务需求的交付,详细内容可参考:https://mp.weixin.qq.com/s/5oN9JqWN7n-4Zv6B9K8kWQ。

为了支持更加广泛的业务场景,可视化编排系统近期需要支持对缓存的操作功能,为保证编排系统的性能,服务的执行过程采用了异步的方式,因此我们考虑使用Redis的异步客户端来完成对缓存的操作。

Redis客户端

Jedis/Lettuce

Redis官方推荐的Redis客户端有Jedis、Lettuce等等,其中Jedis 是老牌的 Redis 的 Java 实现客户端,提供了比较全面的 Redis 命令的支持,在spring-boot 1.x 默认使用Jedis。

但是Jedis使用阻塞的 IO,且其方法调用都是同步的,程序流需要等到 sockets 处理完 IO 才能执行,不支持异步,在并发场景下,使用Jedis客户端会耗费较多的资源。

此外,Jedis 客户端实例不是线程安全的,要想保证线程安全,必须要使用连接池,每个线程需要时从连接池取出连接实例,完成操作后或者遇到异常归还实例。当连接数随着业务不断上升时,对物理连接的消耗也会成为性能和稳定性的潜在风险点。因此在spring-boot 2.x中,redis客户端默认改用了Lettuce。

我们可以看下 Spring Data Redis 帮助文档给出的对比表格,里面详细地记录了两个主流Redis客户端之间的差异。

异步客户端Lettuce

Spring Boot自2.0版本开始默认使用Lettuce作为Redis的客户端。Lettuce客户端基于Netty的NIO框架实现,对于大多数的Redis操作,只需要维持单一的连接即可高效支持业务端的并发请求 —— 这点与Jedis的连接池模式有很大不同。同时,Lettuce支持的特性更加全面,且其性能表现并不逊于,甚至优于Jedis。

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。

上图展示了Netty NIO的核心逻辑。NIO通常被理解为non-blocking I/O的缩写,表示非阻塞I/O操作。图中Channel表示一个连接通道,用于承载连接管理及读写操作;EventLoop则是事件处理的核心抽象。一个EventLoop可以服务于多个Channel,但它只会与单一线程绑定。EventLoop中所有I/O事件和用户任务的处理都在该线程上进行;其中除了选择器Selector的事件监听动作外,对连接通道的读写操作均以非阻塞的方式进行 —— 这是NIO与BIO(blocking I/O,即阻塞式I/O)的重要区别,也是NIO模式性能优异的原因。

Lettuce凭借单一连接就可以支持业务端的大部分并发需求,这依赖于以下几个因素的共同作用:

1.Netty的单个EventLoop仅与单一线程绑定,业务端的并发请求均会被放入EventLoop的任务队列中,最终被该线程顺序处理。同时,Lettuce自身也会维护一个队列,当其通过EventLoop向Redis发送指令时,成功发送的指令会被放入该队列;当收到服务端的响应时,Lettuce又会以FIFO的方式从队列的头部取出对应的指令,进行后续处理。

2.Redis服务端本身也是基于NIO模型,使用单一线程处理客户端请求。虽然Redis能同时维持成百上千个客户端连接,但是在某一时刻,某个客户端连接的请求均是被顺序处理及响应的。

3.Redis客户端与服务端通过TCP协议连接,而TCP协议本身会保证数据传输的顺序性。

如此,Lettuce在保证请求处理顺序的基础上,天然地使用了管道模式(pipelining)与Redis交互 —— 在多个业务线程并发请求的情况下,客户端不必等待服务端对当前请求的响应,即可在同一个连接上发出下一个请求。这在加速了Redis请求处理的同时,也高效地利用了TCP连接的全双工特性(full-duplex)。而与之相对的,在没有显式指定使用管道模式的情况下,Jedis只能在处理完某个Redis连接上当前请求的响应后,才能继续使用该连接发起下一个请求。

在并发场景下,业务系统短时间内可能会发出大量请求,在管道模式中,这些请求被统一发送至Redis服务端,待处理完成后统一返回,能够大大提升业务系统的运行效率,突破性能瓶颈。R2M采用了Redis Cluster模式,在通过Lettuce连接R2M之前,应该先对Redis Cluster模式有一定的了解。

Redis Cluster模式

在redis3.0之前,如果想搭建一个集群架构还是挺复杂的,就算是基于一些第三方的中间件搭建的集群总感觉有那么点差强人意,或者基于sentinel哨兵搭建的主从架构在高可用上表现又不是很好,尤其是当数据量越来越大,单纯主从结构无法满足对性能的需求时,矛盾便产生了。

随着redis cluster的推出,这种海量数据+高并发+高可用的场景真正从根本上得到了有效的支持。

cluster 模式是redis官方提供的集群模式,使用了Sharding 技术,不仅实现了高可用、读写分离、也实现了真正的分布式存储。

集群内部通信

在redis cluster集群内部通过gossip协议进行通信,集群元数据分散的存在于各个节点,通过gossip进行元数据的交换。

不同于zookeeper分布式协调中间件,采用集中式的集群元数据存储。redis cluster采用分布式的元数据管理,优缺点还是比较明显的。在redis中集中式的元数据管理类似sentinel主从架构模式。集中式有点在于元数据更新实效性更高,但容错性不如分布式管理。gossip协议优点在于大大增强集群容错性。

redis cluster集群中单节点一般配置两个端口,一个端口如6379对外提供api,另一个一般是加1w,比如16379进行节点间的元数据交换即用于gossip协议通讯。

gossip协议包含多种消息,如ping pong,meet,fail等。

1.meet:集群中节点通过向新加入节点发送meet消息,将新节点加入集群中。

2.ping:节点间通过ping命令交换元数据。

3.pong:响应ping。

4.fail:某个节点主观认为某个节点宕机,会向其他节点发送fail消息,进行客观宕机判定。

分片和寻址算法

hash slot即hash槽。redis cluster采用的正式这种hash槽算法实现的寻址。在redis cluster中固定的存在16384个hash slot。

如上图所示,如果我们有三个节点,每个节点都是一主一从的主从结构。redis cluster初始化时会自动均分给每个节点

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇大哥,这是并发不是并行,Are You.. 下一篇读Java实战(第二版)笔记05_Coll..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目