1、背景

  • 短TCP连接现在很普遍(长TCP连接消耗带宽,短连接消耗TCP连接数,90%以上TCP流量小于32KB)
  • Linux的TCP事务处理的峰值0.3million/s个,I/O却达到10million/s个(内核处理瓶颈)
  • 扩展短连接处理效率对面向用户在线服务有重要意义

2、问题

  • lack of connection locality(多线程应用,共享一个socket,所以要通过锁的机制来获取socket,因此对性能影响严重 )
  • shared file descriptor space(文件描述符fd是进程内共享的, 多线程之间需要额外的锁的开销)
  • inefficient packet processing(NUMA-unaware memory access和heavy data structures(sk_buff)瓶颈)
  • heavy system call overhead(syscall user/kernel mode switching)
  • 默认linux TCP连接性能不稳定

3、解决方案

  • Google REUSEPORT(Google 2013)
  • Fastsocket(Sina 2014)
  • MegaPipe(University of California, Berkeley 2013)
  • mTCP(Korea Advanced Institute of Science and Technology 2014)
  • 6WIND(http://www.6wind.com/

3.1、Fastsocket

基于Google REUSEPORT patch增加了多核的支持(TCP单连接CPU本地化处理)
改进
  • TCP单个连接完整处理做到了CPU本地化,避免了资源竞争(解决了lack of connection locality的问题)
  • 保持完整BSD socket API(hook系统调用)

实现
  • 动态链接库libfsocket.so拦截socket、bind、listen等系统调用并进入这个链接库进行处理
  • libfsocket.so会通过ioctl为该进程clone listen fd关联的socket、sock、file的系统资源
  • 进程调用listen系统调用时,fastsocket内核会为其关联的sock分配accept队列(多进程多队列)
  • fastsocket提供将每个listen和accept的进程绑定到用户指定的CPU核
不足
  • shared file descriptor space
  • inefficient packet processing
  • heavy system call overhead
  • 需要修改内核代码

3.2、MegaPipe(University of California, Berkeley & Yahoo! Research 2012)

一种适用于多核服务器新的I/O可伸缩的网络编程接口,主要用来解决TCP短连接的性能问题
问题
  • syscall user/kernel mode switching
  • 多线程应用,共享一个socket,所以要通过锁的机制来获取socket,因此对性能影响严重
  • 文件描述符fd是进程内共享的, 多线程之间需要额外的锁的开销
改进
  • lightweight socket(在socket上使用fd,需要额外的检查vfs的负载)

  • Transparent batching

  • Per-core accept queue for each channel

不足
  • 没有重用内核态中的packet I/O
  • 没有优化TCP/IP processing
  • CPU周期的内核态占用率达80%-83%(锁,缓存管理,频繁的用户态和内核态切换是主要原因)

3.3、mTCP

一种适用于多核服务器的高度可扩展的用户空间TCP协议栈
 
改进
  • TCP stack的多核扩展
  • 集成现有的high-performance packet I/O library
  • allows efficient flow-level event aggregation
  • performs batch processing of RX/TX packets for high I/O efficiency
  • batch processing无需系统状态切换
  • 不需要内核代码的改动
效果
  • Linux的CPU周期的内核态占用率达80%-83%,kernel以及TCP协议栈实现是主要瓶颈
  • 无需系统状态切换,性能是Linux的4.3倍以上
实现
  • 用户层TCP栈

  1. Basic TCP Processing
  2. Lock-free, Per-core Data Structures
  3. Batched Event Handling(每10Gbps的端口,使用8个RX/TX队列,每队列平均2170个mTCP线程)
  • separate-TCP-thread-per-application-thread模型

  • 集成现有的high-performance packet I/O library
  1. PacketShader I/O engine(PSIO)来支持event-driven packet I/O interface(目前只改了Intel 82598/82599网卡驱动);
  2. PSIO减小了syscall和上下文切换的开销,减少了包内存分配和DMA的开销;
  3. PSIO中包是批量发送减少了类似于DMA地址映射和IOMMU查找的开销;
  • 用户层API

不足
  • 需要改写应用层程序代码(BSD-like socket.(accept() –> mtcp_accept())
  • mTCP会绕过现有的Linux Kernel的一些服务,如防火墙等
  • 原型目前只支持单个应用程序

3.4、6WIND(商业)

提供TCP协议栈的解决方案
改进
  • Packet buffer copy between Linux kernel and userland memory areas
  • High latency of userland/kernel system calls
  • Complex locking and scheduling mechanisms in the kernel
架构
解决方案
  • 提供有效利用多核性能的TCP socket编程模型
  • socket API使用零拷贝操作分发数据同时也使用简化的I/O模型
  • 应用每秒可支撑上百外的并发session、事务等

 

4、性能评估

5、竞品对比

Types Accept queue Conn. Locality Socket API Event Handling Packet I/O Application Mod- ification Kernel Modification
Linux-2.6 Shared None BSD socket Syscalls Per packet Transparent No
Linux-3.9 Per-core None BSD socket Syscalls Per packet Add option SO REUSEPORT No
MegaPipe Per-core Yes lwsocket Batched syscalls Per packet Event model to completion I/O Yes
FlexSC,VOS Shared None BSD socket Batched syscalls Per packet Change to use new API Yes
mTCP Per-core Yes User-level socket Batched function calls Batched Socket API to mTCP API No
(NIC driver)
Fastsocket Per-core Yes BSD socket Ioctl + kernel calls Per packet Transparent No