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等),免费分享

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

其中:
- 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+ 插件化也让其非常易于扩展和定制。

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