Snap 2019 — Google 把网络栈搬到用户态微内核
待复核Snap 是 Google 内部用来把主机网络功能从 Linux 内核里搬出来、放到一个用户态微内核进程里运行的系统。虚拟交换、流量整形、加密、负载均衡都在用户态完成;内核只负责最底层收发包和硬件驱动。
日常类比:传统 Linux 网络栈像大楼物业,门禁、水电、快递分拣全包。物业太慢时,Google 把最忙的「快递分拣」外包给独立公司(Snap 进程)——可随时改流程,不用等整栋楼停电检修(内核升级)。边界:Snap 仍依赖内核开门收货,独立的是上层网络功能,不是整条网络栈。
它不是学术原型,而是跑在 Google 大规模生产机上的工业系统(论文覆盖三代硬件与约五年演进)。与同年 shenango-2019 追单机微秒延迟不同,Snap 更关心百万台规模下的可运维性:如何在不中断服务时每周给网络栈上新功能。
一句话记:Snap =「可热升级的用户态网络物业公司」,不是「完全离开大楼的独立王国」。
不理解 Snap,下面这些事都说不清:
- 为什么 Google Cloud 能热升级网络功能而不重启虚拟机——Snap 是独立用户态进程
- 为什么 arrakis-2014 / ix-2014 的纯 kernel-bypass 难原样落地多租户云——需要可控中间层
- 为什么 AWS Nitro 走专用硬件卸载、Google 走软件 Snap——两条路线的工程取舍(笔记侧对比,非论文专章)
- 为什么 dpdk 单机很强、几百万台异构机上仍不够——还缺隔离与热升级框架
- 为什么云厂商越来越多把网络栈搬出内核——Snap 用多年生产数据证明软件路径可行
- 为什么通用 linux-kernel 网络栈在云多租户下越来越吃力——每包开销与升级代价叠加
1. 用户态微内核架构
Snap 是普通 Linux 用户态进程,内部却像微内核:自有调度、内存与 IPC;防火墙、虚拟交换、加密等以「引擎」插件插入。类比:操作系统里的操作系统。引擎用输入/输出队列串成管道——每段只做一件事,像 Unix 管道。相对裸 dpdk,Snap 在收发包之上提供完整引擎框架,团队可像写插件一样加功能,不必重写底层轮询。
2. 三种 CPU 调度模型
- 专核:独占 CPU 忙等,延迟最低但空闲也占核(像 dpdk)
- 共享调度:跟应用抢 Linux CFS(公平调度器),省 CPU 但尾延迟尖刺大
- 自适应轮询:空闲时
epoll_wait让出,有包立刻忙等——多数云负载的默认选择
直觉:流量常突发——低包率省 CPU,高包率自动忙等。金融网关等极端低延迟场景才值得专核。
3. 可热升级
升级时新进程经 Unix 域套接字接手连接状态(序列号、密钥等),原子切换数据路径,旧进程退出;对 VM/容器透明,通常几百毫秒。安全补丁可在数小时内全球推送,不必滚动重启整机内核——这是相对内核模块最大的运维优势。
案例 1:引擎链处理一个包
Section titled “案例 1:引擎链处理一个包”NIC → parse → ACL → shape → encrypt → VM逐部分解释:
parse:拆包头,认出属于哪台虚拟机ACL:按安全规则决定放行或丢弃(像门禁名单)shape:按带宽配额限速encrypt:跨机房流量做 IPsec 类加密- 各引擎独立线程池后,论文报告一类场景 P99 延迟约降一半——内核里很难给子模块单独分线程
案例 2:自适应轮询状态机
Section titled “案例 2:自适应轮询状态机”idle --(packet)--> busy_poll --(queue empty)--> idle ^ epoll_wait 唤醒 主动让出 CPU逐部分解释:
- 队列空 → 调用
epoll_wait睡觉,把 CPU 还给邻居进程 - 包到达 → 立刻进入忙等,连续清队列
- 再空 → 回到 idle。相对专核,论文场景下 CPU 约省 30–40%,P99 只多约 10µs
案例 3:热升级状态迁移
Section titled “案例 3:热升级状态迁移”old_snap --(UDS: flows, keys)--> new_snap atomic datapath switch → old exits逐部分解释:
- 新进程启动后经 Unix 域套接字接收流状态
- 原子切换数据路径,旧进程退出
- 上层 VM 看不到中断;这是「每周上线网络功能」的运维基础
- 用户态 ≠ 自动隔离:Snap 常以高权限运行,崩溃可断全机 VM 网络——需心跳、自动重启与状态快照。
- CFS 尾延迟:共享调度被抢走几毫秒,P99 与 P99.9 可差一个数量级——高峰改忙等。
- NUMA 事后补:跨节点内存让延迟翻倍——引擎必须绑本地节点分配缓冲。
- 引擎间 IPC 过热:百万包/秒下消息拷贝成热点——改共享内存/零拷贝(与 l4-1995 经验一致)。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 大规模多租户云网络——要热升级、隔离与灵活部署
- 网络功能每周演进,等不起内核发布窗口
- CPU 相对充裕(自适应调度在资源够时最划算)
- 需要统一遥测/调试——引擎同进程便于 profiling
不适用:
- 单机极致低延迟(不如 dpdk 专核)
- SmartNIC/DPU 已硬件卸载同类功能
- 小于约几万台、运维框架成本不划算
- 固件几乎不改的固定网络设备
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 第一代:改 Linux 内核模块——快,但升级走内核发布,周期以月计
- 第二代:内核可插拔框架——稍好,仍受 API/panic 约束
- 第三代:Snap 彻底用户态——用应用式 CI/CD 发网络栈
- 关键动机常是迭代速度,不只是单包性能;名字无官方缩写,内部强调可「snap in」插拔
- 与 shenango-2019 同年:一个改调度,一个搬整栈;思路可互补
- 搬出内核首先为了迭代与运维,性能可用专核或硬件补;内核发布流程是结构性瓶颈。
- 用户态网络最难的是 CPU 调度——专核 / 共享 / 自适应没有万能解。
- 热升级是云底座刚需——不能热升级的组件会拖住整机发布。
- 控制面与数据面分离反复出现:从 arrakis-2014 到 SDN 到 Snap。
- 论文:Snap: A Microkernel Approach to Host Networking (SOSP 2019)
- Andromeda 虚拟网络(Snap 为其数据面):NSDI 2018 Andromeda
- AWS Nitro 设计对比:Security Design of the AWS Nitro System
- arrakis-2014 —— 把硬件直接给应用的前置思想实验
- ix-2014 —— 受保护数据面,Snap 在工业界的精神前身
- arrakis-2014 —— 应用绕过内核做 I/O;Snap 折中为用户态中间进程
- ix-2014 —— 硬件保护隔离数据面;Snap 用进程隔离更易部署升级
- dpdk —— 纯用户态轮询;Snap 在其上加自适应调度与引擎框架
- io-uring —— 减少 syscall;Snap 更进一步让网络栈常驻用户态
- linux-kernel —— Snap 要解决的内核网络性能与运维瓶颈
- xen-2003 —— 虚拟化隔离思路影响 Snap 的资源分区
- shenango-2019 —— 同年微秒级核重分配,与自适应调度同一问题的另一解
- demikernel-2021 —— Demikernel 2021 — 微秒级数据中心的 LibOS 架构