您当前的位置:首页 > 电脑百科 > 数据库 > Redis

从通用的协议栈层面来优化Redis性能的实践

时间:2022-06-01 14:23:24  来源:  作者:linux技术栈

redis 作为最受欢迎的 NoSQL 数据库之一,具备高性能、高可用性、高扩展性等特点,在各互联网业务中使用广泛。目前业界针对 Redis 的性能优化主要针是配置项优化以及使用方式的优化。本文介绍尝试撇开 Redis 本身,而从通用的协议栈层面来做优化,这种优化方式理论上可推广到其他 Socket 类互联网应用,如 Memcached、Ngnix、Envoy 等。

分 析

Redis-server 作为一个标准的 Socket 类应用,会通过监听地址端口接收来自客户端的连接,连接建立后会读取连接上的客户端请求,处理后再返回响应给客户端,这其中的连接建立、请求读取、响应返回都是通过内核的 TCP/IP 协议栈来处理的。可以通过火焰图先看一下 Redis-server 在性能压测下的 CPU 消耗情况。

从通用的协议栈层面来优化Redis性能的实践

 

图中,是在客户端读请求压测的时候抓取的火焰图信息。可见,内核态协议栈所占用的 CPU 消耗较大,其中以 sys_write 为主,占比 40% 左右。所以,如果能对这部分 CPU 占用进行优化,收益还是非常可观的。

那么这部分 CPU 占比如何进行优化呢?最好还能做到 Redis 应用本身完全无感知。

协议栈的处理完全省掉是不现实的,这样底层 TCP 通信就玩不转了。但是我们可以考虑将这部分处理剥离出去,不占用 Redis 的 CPU。

那剥离出去的协议栈实现放在哪儿呢?

可以放到一个单独的进程中实现。那这样是不是和剥离前没有区别?

No!因为一台机器上一般会启动多个 Redis 实例,多个 Redis 实例在这种情况下就可以共享这个协议栈实现的进程。相当于将 Redis 和协议栈的 1:1 绑定部署关系,变为 N:1 的独立部署关系。

那这个协议栈实现进程的性能就非常重要了,绝对不能成为瓶颈,否则会导致最终的性能没有提升,甚至更糟。具体如何实现呢?

下面该轮到用户态协议栈出场了!

优 化

用户态协议栈介绍

顾名思义,用户态协议栈是将原本在内核态实现的 TCP/IP 协议栈移到用户态实现的技术。放到用户态实现可以带来几大好处:

1. 高性能

Redis 本身是一个用户态的应用程序,调用内核态的 TCP/IP 协议栈实现,不可避免地会带来用户态和内核态的上下文切换开销。另外,最重要的一点,内核协议栈和应用绑定在一起,无法做到和应用在资源占用上剥离,也就是前面所述的独立部署。

2. 易调测

做过内核态开发的同学应该都知道,内核下程序的调测还是比较痛苦的,动不动给你来个 Oops 就会导致内核挂死。放到用户态实现调测起来就会方便很多。

3. 易定制

内核协议栈随着版本的迭代,历史包袱越来越重,导致越来越臃肿。而且新特性的合入时依赖会越来越多,也会越来越谨慎,甚至 bug 的修复周期也越来越长。用户态协议栈则不会有此类问题,可以在内核协议栈的基础上做裁剪和定制,易调测也会让试错成本大大降低。

相关视频推荐

徒手实现网络协议栈,请准备好环境,一起来写代码

linux下的epoll实战揭秘——支撑亿级IO的底层基石

学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

需要C/C++ linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

从通用的协议栈层面来优化Redis性能的实践

 

用户态协议栈具体实现

用户态协议栈我们采用开源 VPP+VCL 的方案:VPP 作为独立进程在用户态实现 TCP/IP 协议栈,VCL 作为动态库实现 Socket 类接口劫持并和后端 VPP 完成交互。整个系统的架构如下图所示:

从通用的协议栈层面来优化Redis性能的实践

 

其中:

  • VCL - 实现 Socket 类接口劫持并和后端 VPP 完成交互
  • FIFO - 是基于共享内存封装的消息队列,用于 VCL 和 VPP 之间通信
  • Session - 维持传输层和上层应用会话之间的对应
  • TCP/IP - 对应内核的 TCP/IP 协议栈实现
  • DPDK - 实现将网卡的报文收发卸载到用户态

可见,VPP+VCL 分离式的部署模式将协议栈从应用端剥离,并通过 LD_PRELOAD 方式加载 VCL 动态库实现对于 Redis 的无侵入加速。

最后,VPP 如何做到本身处理的高效而不会成为瓶颈呢?

VPP 主要基于 DPDK 实现报文的高效收发,再结合自身的向量化处理(减少 CPU Cache missing)来实现报文的高效处理。另外,graph node+ 插件化也让其非常易于扩展和定制。

从通用的协议栈层面来优化Redis性能的实践

 

rdbsave 动态进程问题

使用开源 VPP 加速 Redis 过程中,也遇到和解决了不少社区版本中的问题,比较典型的就是 rdbsave 动态进程引发的问题。

Redis 可以配置周期性的保存快照,实现上会启用一个动态的 rdbsave 进程来完成,rdbsave 进程非常驻进程,在完成工作后就会退出。配置文件中可以指定保存的周期以及触发保存的变化量,如果周期配置的比较短且触发保存的变化量比较小,则可能会导致 rdbsave 进程频繁的创建和退出,实测过程中这也会导致目前社区中对于动态进程支持的一些问题很快速的就能暴露出来。

Session 同步问题

rdbsave 进程创建时会从主线程同步 socket 相关的 session 资源。目前社区中 epoll fd 相关的 session 资源没有同步完全,主要是因为 session handle 中包含了各个进程的 worker_index 信息,而 worker_index 是因进程 / 线程而异的,直接从主线程同步过来的 session handle 需要根据 worker_index 做转换才能使用。相关的 patch 目前已经合入社区。

死锁问题

rdbsave 进程退出时需要释放和进程关联的 session 资源,目前是通过主线程捕获 SIGCHLD 信号,在信号处理函数中来释放相关 session 资源。如果主线程在先获取锁 A 的情况下跳转到信号处理函数释放资源,而释放资源的时候也获取了锁 A,则会导致死锁。当然我们可以针对锁 A 的情况想办法解决此问题,但是这种解决方式不彻底,因为主线程可能获取了锁 B 后再去执行信号处理函数释放资源,然后释放资源的时候也获取了锁 B。根源是在于执行信号处理函数之前的主线程状态未知。

所以,我们可以考虑在信号处理函数中不释放资源,而仅仅将待释放的资源索引进行保存,等到后面合适的时机,如执行 epoll_wAIt 的时候再进行释放。相关的 patch 目前也已经合入社区。

效 果

通过优化后的火焰图看效果:

从通用的协议栈层面来优化Redis性能的实践

 

可见,内核的 socket 读写已经大大降低,还遗留的是用户态协议栈实现中用来在 VCL 和 VPP 之间通知事件的 eventfd 通知。

基于 redis 4.0.9 以及 memtier_benchmark 1.2.17 测试的结果。

从通用的协议栈层面来优化Redis性能的实践

 

QPS 提升 31%,此时内核态 Redis CPU 占用 99%,用户态 Redis CPU 占用 80% 左右。

从通用的协议栈层面来优化Redis性能的实践

 

延迟降低 23.2%,同样此时内核态 Redis CPU 占用 99%,用户态 Redis CPU 占用 80% 左右。

总 结

用户态协议栈可以轻松做到针对 Redis 的无侵入加速,在占用 CPU 资源更少的情况下,相较内核态协议栈可以取得 31% 的 QPS 加速效果,同时延迟降低 23%。

用户态协议栈作为通用的加速组件,理论上可以支持所有 Socket 类应用的加速。目前基于用户态协议栈对网易数帆轻舟微服务 API 网关中 Envoy 的加速已经产品化并在网易严选环境中落地,针对 Sidecar 的加速也相继在内外部客户完成测试,针对 Redis 的加速也完成了 PoC 测试。整个加速组件的数据面基于 Kube.NETes 的 DaemonSet 部署,而管控面基于 Kubernetes 的 Operator 部署,部署简单、运维方便。我们也会在后续工作中,持续探索基于用户态协议栈的更多应用场景。



Tags:Redis性能   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何进行Redis性能优化?这一篇就够了
Redis 是一款高性能的内存数据存储系统,它被广泛应用于各种实时数据处理场景,如缓存、消息队列、实时统计等。为了最大化 Redis 的性能,我们应该针对具体应用场景,对其配置参数...【详细内容】
2023-11-10  Search: Redis性能  点击:(122)  评论:(0)  加入收藏
Redis性能优化:理解与使用Redis Pipeline
当我们谈论Redis数据处理和存储的优化方法时,「Redis Pipeline」无疑是一个不能忽视的重要技术。在使用Redis的过程中,频繁的网络往返操作可能会引发严重的性能问题,尤其是当大...【详细内容】
2023-10-03  Search: Redis性能  点击:(214)  评论:(0)  加入收藏
Redis性能瓶颈揭秘:如何优化大key问题?
1. 什么是Redis大key问题Redis大key问题指的是某个key对应的value值所占的内存空间比较大,导致Redis的性能下降、内存不足、数据不均衡以及主从同步延迟等问题。到底多大的数...【详细内容】
2023-04-17  Search: Redis性能  点击:(229)  评论:(0)  加入收藏
从通用的协议栈层面来优化Redis性能的实践
Redis 作为最受欢迎的 NoSQL 数据库之一,具备高性能、高可用性、高扩展性等特点,在各互联网业务中使用广泛。目前业界针对 Redis 的性能优化主要针是配置项优化以及使用方式的...【详细内容】
2022-06-01  Search: Redis性能  点击:(508)  评论:(0)  加入收藏
Redis性能命令
Redis 性能测试是通过同时执行多个命令实现的。1,Redis-benchmarkRedis性能命令:redis性能命令格式: redis-benchmark [option] [option value] redis 性能测试工具可选参数如...【详细内容】
2021-11-02  Search: Redis性能  点击:(356)  评论:(0)  加入收藏
▌简易百科推荐
兄弟,王者荣耀的段位排行榜是通过Redis实现的?
在王者荣耀中,我们会打排位赛,而且大家最关注的往往都是你的段位,还有在好友中的排名。作为程序员的你,是否思考过这个段位排行榜是怎么实现的?了解它的实现原理,会不会对上分有所...【详细内容】
2024-04-15    dbaplus社群  Tags:Redis   点击:(4)  评论:(0)  加入收藏
16个Redis常见使用场景总结
来源:blog.csdn.net/qq_39938758/article/details/105577370目录 缓存 数据共享分布式 分布式锁 全局ID 计数器 限流 位统计 购物车 用户消息时间线timeline 消息...【详细内容】
2024-04-11    书圈  Tags:Redis   点击:(10)  评论:(0)  加入收藏
Linux获取Redis 性能指标方法
一、监控指标Ø 性能指标:PerformanceØ 内存指标: MemoryØ 基本活动指标:Basic activityØ 持久性指标: PersistenceØ 错误指标:Error二、监...【详细内容】
2024-04-11  上海天正信息科技有限    Tags:Redis   点击:(10)  评论:(0)  加入收藏
Redis与缓存一致性问题
缓存一致性问题是在使用缓存系统,如Redis时经常遇到的问题。当数据在原始数据源(如数据库)中发生变化时,如何确保缓存中的数据与数据源保持一致,是开发者需要关注的关键问题。一...【详细内容】
2024-04-11  后端Q    Tags:Redis   点击:(8)  评论:(0)  加入收藏
Redis 不再 “开源”,未来采用 SSPLv1 和 RSALv2 许可证
Redis 官方于21日宣布修改开源协议 —— 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause...【详细内容】
2024-03-27  dbaplus社群    Tags:Redis   点击:(25)  评论:(0)  加入收藏
Redis“叛逃”开源,得罪了几乎所有人
内存数据库供应商Redis近日在开源界砸下了一块“巨石”。Redis即将转向双许可模式,并实施更为严格的许可条款。官方对此次变更的公告直截了当:从Redis 7.4版本开始,Redis将在Re...【详细内容】
2024-03-25    51CTO  Tags:Redis   点击:(13)  评论:(0)  加入收藏
如何使用 Redis 实现消息队列
Redis不仅是一个强大的内存数据存储系统,它还可以用作一个高效的消息队列。消息队列是应用程序间或应用程序内部进行异步通信的一种方式,它允许数据生产者将消息放入队列中,然...【详细内容】
2024-03-22  后端Q  微信公众号  Tags:Redis   点击:(23)  评论:(0)  加入收藏
Redis不再 “开源”
Redis 官方今日宣布修改开源协议 —— 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause 开...【详细内容】
2024-03-21  OSC开源社区    Tags:Redis   点击:(15)  评论:(0)  加入收藏
在Redis中如何实现分布式锁的防死锁机制?
在Redis中实现分布式锁是一个常见的需求,可以通过使用Redlock算法来防止死锁。Redlock算法是一种基于多个独立Redis实例的分布式锁实现方案,它通过协调多个Redis实例之间的锁...【详细内容】
2024-02-20  编程技术汇    Tags:Redis   点击:(52)  评论:(0)  加入收藏
手动撸一个 Redis 分布式锁
大家好呀,我是楼仔。今天第一天开工,收拾心情,又要开始好好学习,好好工作了。对于使用 Java 的小伙伴,其实我们完全不用手动撸一个分布式锁,直接使用 Redisson 就行。但是因为这些...【详细内容】
2024-02-19  楼仔  微信公众号  Tags:Redis   点击:(50)  评论:(0)  加入收藏
相关文章
站内最新
站内热门
站内头条