别被 PPT 骗了:从系统调用与内核视角看「云与自托管」的四大误区
最近技术群里又在日常撕「All-in-Cloud」还是「自托管(Self-hosting)下云」。有些人张口就是“公有云弹性和 SLA 吊打自建”,另一批人则高呼“买几台物理机性能翻倍、成本腰斩”。
每当看到这种脱离场景的嘴炮,我都想把他们的架构图撕掉,按着头去看 dmesg、perf 和 strace。系统的状态不会陪你演戏,硬件开销和内核瓶颈就在那里。今天喵就从底层性能、资源隔离和排障视角的几个经典误区,把这两者拉出来遛遛。
误区一:「自托管直接插满 NVMe,I/O 性能必然秒杀云盘」
很多人算账:AWS 一个 gp3 卷才几千 IOPS,我买张企业级 NVMe SSD 随便跑几百万 IOPS,自托管赢麻了。
真去跑生产负载时,往往被现实打脸。本地 NVMe 确实具备极低的物理延迟(4KB 随机写可以在数十微秒级),但在高并发数据库写入时,瓶颈往往不在颗粒速度,而在文件系统与内核刷新机制。
拿 PostgreSQL 或 MySQL 的 WAL 写入来说,核心链路是 fdatasync()。我们在自建环境用 strace 跟踪一次典型的事务提交:
# strace -T -e trace=fdatasync -p <postgres_pid>
fdatasync(7) = 0 <0.000412>
fdatasync(7) = 0 <0.000389>
fdatasync(7) = 0 <0.012480> # 突然抖动到了 12ms!
为什么物理机还会抖到 12ms?
你很可能没配置硬件 RAID 卡的 BBU(电池备份写缓存),或者没有处理好文件系统的挂载参数(比如 noatime,data=writeback,barrier=0 敢不敢开?开完断电丢不丢数据?)。另外,单机 Linux 的内存脏页回写参数(dirty_ratio / dirty_background_ratio)一旦设置不当,kworker 刷脏盘时会引发严峻的 I/O 排队阻塞。
而在云端,分布式块存储通过三副本网络同步和专门的硬件加速卡(如 AWS Nitro)接管了写缓存,它的平均延迟确实不如裸物理盘的微秒级,但它的 P99 方差往往经过严格的 QoS 限制。
结论:不要拿物理盘的「标称峰值」去比云盘的「服务等级」。自托管想压榨出真正的硬件性能,你需要精细调校文件系统 barrier、I/O 调度器(none/mq-deadline)以及脏页刷新水位,否则只要一次断电或配置不当,写入毛刺会教做人。
误区二:「上了云原生/K8s,应用层就不需要关心 Linux 调度了」
一些人认为:公有云买托管 EKS/ACK,资源编排全自动化,再也不用碰底层 Linux 内核参数。
这是最典型的掩耳盗铃。只要你的容器跑在 Linux 上,就逃不脱内核 cgroup 的制裁。我们在云上最常踩的一个坑就是——明明 CPU 占用率只有 30%,但服务 P99 延迟却莫名暴涨。
这时候去抓一眼容器对应的 cgroup 状态:
# 进入 cgroup v2 目录
cat /sys/fs/cgroup/system.slice/docker-<container_id>.scope/cpu.stat
usage_usec 1847291823
user_usec 1204918203
system_usec 642373620
nr_periods 100000
nr_throttled 34820 # 注意这个:34.8% 的周期被节流了!
throttled_usec 4819201948
原因在于 CFS(Completely Fair Scheduler)配额机制。如果你在 K8s 里给 Pod 限制了 resources.limits.cpu: 2,实际上内核是在以 100ms(默认 cpu.cfs_period_us)为一个周期切片。当应用并发较多,瞬间把 200ms 的配额在周期前 20ms 用完了,内核就会通过 cfs_quota_throttled 直接冻结该容器的所有线程,硬生生停滞 80ms 等待下个周期!
用 perf sched 能清晰看到这些线程被无情切出并等待:
# perf sched record -- sleep 1
# perf sched latency
---------------------------------------------------------------------------------------------------------------
Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |
---------------------------------------------------------------------------------------------------------------
my-cloud-app:(12) | 198.23 ms | 1420 | avg: 2.412 ms | max: 79.821 ms | 12847.192841 s |
---------------------------------------------------------------------------------------------------------------
结论:不管是自建还是云上托管,只要你开启了 CPU limits,就必须深入理解内核 CFS。要么关掉 CPU 限制仅用 requests 做调度,要么调优 cpu.cfs_period_us,甚至引入内核的 CPU Burst 特性。抽象层从没有消除复杂度,它只是把问题推到了你看不见的地方。
误区三:「公有云网络是黑盒透明的,网络瓶颈只存在于自建机房」
自建机房常常要担心光模块坏掉、交换机丢包、单机网卡多队列没配置好;有些人就天真地以为公有云的网络是无限宽带的“虚拟大管家”。
事实是,云厂商不仅对带宽做了强限制,对 PPS(Packets Per Second) 和 Conntrack 连接数 的限制更是严厉至极,而且很多配额根本不写在售卖页的显著位置。
比如微服务架构下高频短连接场景,在自托管物理机上,我们可以配置网卡多队列 + RPS/RFS,将中断打散到各个 CPU 核心:
# 查看网络软中断是否倾斜
cat /proc/softirqs | grep NET_RX
CPU0 CPU1 CPU2 CPU3
NET_RX: 12891283 123 231 182 # 极其严重的单核倾斜!
自托管你可以靠 ethtool -L eth0 combined 8 以及绑核脚本解决它。
但在云上虚拟机中,很多时候你的物理网络是经过 Hypervisor 虚拟化的(如 vHost/virtio 或 SR-IOV)。当你的 PPS 瞬间冲高,云宿主机会直接在底层丢包,而你的虚拟机内核内部几乎什么报错都看不到(ifconfig 丢包计数为 0)。
你可以用 bpftrace 抓内核丢包点,往往发现是驱动层直接抛弃:
# bpftrace -e 'kprobe:kfree_skb { @[kstack] = count(); }'
@[
kfree_skb+1
ena_clean_rx_irq+789 [ena] # 发现是厂商网卡驱动直接在清理环形缓冲区时 drop
napi_gro_receive+142
]: 48210
结论:在公有云上跑高网络吞吐或高 PPS 业务(如 DNS、网络代理),必须仔细阅读机型的网卡规格限制(ENA/Virtio 驱动支持上限),不要以为买了大规格的实例就不会在驱动层被限流。
误区四:「自托管太折腾,不如云上全家桶省时省力」
这个误区的另一面是:“云上什么都配置好了,自建简直是刀耕火种。”
真去排查过深水区线上故障的人都知道,拥有完整的内核控制权与硬件观测视角,有时候反而是最省时间的。
在自托管物理节点上,你拥有底层的全功能工具链:
- 内存异常抖动?直接
perf c2c抓跨 NUMA 节点的缓存行伪共享(False Sharing)。 - 内核锁竞争?
perf lock contention -a -b瞬间定位到是哪一段内核自旋锁(spinlock)在卡顿。 - 随时能够升级最新的稳定版内核(比如 6.6+ LTS),享用全新的调度器改进与 MGLRU 内存回收策略。
反观部分云托管环境,内核版本长期冻结在厂商打满各种自研补丁的定制版本上。一旦遇到难以解释的系统停顿,既没有权限开启某些硬件性能计数器(PMU 常常被 Hypervisor 禁用,导致某些 perf 指标无法收集),提 Ticket 给客服往往转了几道工单后得到一句“底层宿主机发生热迁移,现已恢复”。这种完全失控的排障过程,耗费的心智成本其实远高于自己维护硬件。
总结:拿数据说话,别信玄学
- 自托管的真正门槛,从来不是“买服务器硬件”的费用,而是你有没有能力驾驭一套完整的运维监控、内核参数调优矩阵(I/O、网络栈、调度器)以及物理容灾体系。
- 公有云的核心价值不是“绝对的高性能”,而是“工业化的基线水平与按需伸缩”。你需要用它的规则写代码,同时警惕多租户超卖、QoS 隐形限制和虚拟化层的开销。
选型之前,别被各路布道师带节奏。拉一台物理机,开一个云实例,压测脚本跑起来,strace、fio 和 perf 一挂,数据会告诉你最真实的答案。
License: CC BY-NC 4.0
Updated 13 hours ago
Was this article helpful? Give it a like.
0 comments


