plantegg

java tcp mysql performance network docker Linux

关于本博

find me on twitter: @plantegg

Github: 欢迎star

关注基础知识,一次把问题搞清楚,从案例出发深挖相关知识。

以前觉得自己一看就懂,实际是一问就打鼓,一用就糊涂。所以现在开始记录并总结再联系案例,一般是先把零散知识记录下来(看到过),慢慢地相关知识积累更多,直到碰到实践案例或是有点领悟到于是发现这块知识可以整理成一篇系统些的文章(基本快懂了)。

“技术变化太快,容易过时”,我的看法是网络知识、操作系统、计算机原理等核心概念知识的寿命会比你的职业生涯还长。这些都是40岁之后还会还会很有用

如何在工作中学习 所有方法我都记录在这篇文章中了,希望对你能有所帮助。

所有新文章从这里可以看到,即使再简单的一篇总结我可以持续总结三五年,有新的发现、感悟都是直接在原文上增减,不会发表新的文章。

image-20220421102225491

为什么写博客而不是公众号,我见过20年前的互联网,深度依赖搜索引擎,所以还是喜欢博客。另外技术类文章更适合电脑阅读(随时摘录、实验)

精华文章推荐(2021年前)

在2010年前后MySQL、PG、Oracle数据库在使用NUMA的时候碰到了性能问题,流传最广的这篇 MySQL – The MySQL “swap insanity” problem and the effects of the NUMA architecture http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/ 文章描述了性能问题的原因(文章中把原因找错了)以及解决方案:关闭NUMA。 实际这个原因是kernel实现的一个低级bug,这个Bug在2014年修复了https://github.com/torvalds/linux/commit/4f9b16a64753d0bb607454347036dc997fd03b82,但是修复这么多年后仍然以讹传讹,这篇文章希望正本清源、扭转错误的认识。

image-20210517082233798

CPU的制造和概念 从最底层的沙子开始用8篇文章来回答关于CPU的各种疑问以及大量的实验对比案例和测试数据来展示了CPU的各种原理,比如多核、超线程、NUMA、睿频、功耗、GPU、大小核再到分支预测、cache_line失效、加锁代价、IPC等各种指标(都有对应的代码和测试数据)。

image-20210802161410524

《Intel PAUSE指令变化是如何影响自旋锁以及MySQL的性能的》 从一个参数引起的rt抖动定位到OS锁等待再到CPU Pause指令,以及不同CPU型号对Pause使用cycles不同的影响,最终反馈到应用层面的rt全过程。在MySQL内核开发的时候考虑了Pause,但是没有考虑不同的CPU型号,所以换了CPU型号后性能差异比较大

image.png

10倍性能提升全过程 在双11的紧张流程下,将系统tps从500优化到5500,从网络到snat、再到Spring和StackTrace,一次全栈性能优化过程的详细记录和分析。

image.png

就是要你懂TCP–半连接队列和全连接队列:偶发性的连接reset异常、重启服务后短时间的连接异常,通过一篇文章阐明TCP连接的半连接队列和全连接队大小是怎么影响连接创建的,以及用什么工具来观察队列有没有溢出、连接为什么会RESET

image.png

就是要你懂TCP–性能和发送接收Buffer的关系:发送窗口大小(Buffer)、接收窗口大小(Buffer)对TCP传输速度的影响,以及怎么观察窗口对传输速度的影响。BDP、RT、带宽对传输速度又是怎么影响的

就是要你懂网络–一个网络包的旅程:教科书式地阐述书本中的路由、网关、子网、Mac地址、IP地址是如何一起协作让网络包最终传输到目标机器上。 同时可以跟讲这块的RFC1180比较一下,RFC1180 写的确实很好,清晰简洁,图文并茂,结构逻辑合理,但是对于90%的程序员没有什么卵用,看完几周后就忘得差不多,因为他不是从实践的角度来阐述问题,中间没有很多为什么,所以一般资质的程序员看完当时感觉很好,实际还是不会灵活运用

国产CPU和Intel、AMD性能PK 从Intel、AMD、海光、鲲鹏920、飞腾2500 等CPU在TPCC、sysbench下的性能对比来分析他们的性能差距,同时分析内存延迟对性能的影响

image-20220319115644219

从网络路由连通性的原理上来看负载均衡lvs的DR、NAT、FullNAT到底搞了些什么鬼,以及为什么要这么搞,和带来的优缺点:《就是要你懂负载均衡–lvs和转发模式》

LVS 20倍的负载不均衡,原来是内核的这个Bug,这个内核bug现在还在,可以稳定重现,有兴趣的话去重现一下,然后对照源代码以及抓包分析一下就清楚了。

就是要你懂TCP–握手和挥手,不是你想象中三次握手、四次挥手就理解了TCP,本文从握手的本质–握手都做了什么事情、连接的本质是什么等来阐述握手、挥手的原理

nslookup OK but ping fail–看看老司机是如何解决问题的,解决问题的方法肯定比知识点重要多了,同时透过一个问题怎么样通篇来理解一大块知识,让这块原理真正在你的只是提示中扎根下来

如何在工作中学习 一篇很土但是很务实可以复制的方法论文章。不要讲举一反三、触类旁通,谁都知道要举一反三、触类旁通,但是为什么我总是不能够举一反三、触类旁通?

举三反一–从理论知识到实际问题的推导 坚决不让思路跑偏,如何从一个理论知识点推断可能的问题

性能相关(2015-2018年)

就是要你懂TCP–半连接队列和全连接队列 偶发性的连接reset异常、重启服务后短时间的连接异常

就是要你懂TCP–性能和发送接收Buffer的关系:发送窗口大小(Buffer)、接收窗口大小(Buffer)对TCP传输速度的影响,以及怎么观察窗口对传输速度的影响。BDP、RT、带宽对传输速度又是怎么影响的 发送窗口大小(Buffer)、接收窗口大小(Buffer)对TCP传输速度的影响,以及怎么观察窗口对传输速度的影响

就是要你懂TCP–性能优化大全

就是要你懂TCP–TCP性能问题 Nagle算法和delay ack

10倍性能提升全过程 在双11的紧张流程下,将系统tps从500优化到5500,从网络到snat、再到Spring和StackTrace,看看一个性能全栈工程师如何在各种工具加持下发现各种问题的。

CPU系列文章(2021年完成)

CPU的制造和概念

十年后数据库还是不敢拥抱NUMA?

[Intel PAUSE指令变化是如何影响自旋锁以及MySQL的性能的](/2019/12/16/Intel PAUSE指令变化是如何影响自旋锁以及MySQL的性能的/)

[Perf IPC以及CPU性能](/2021/05/16/Perf IPC以及CPU利用率/)

CPU性能和CACHE

[CPU 性能和Cache Line](/2021/05/16/CPU Cache Line 和性能/)

AMD Zen CPU 架构 以及 AMD、海光、Intel、鲲鹏的性能对比

Intel、海光、鲲鹏920、飞腾2500 CPU性能对比

网络相关基础知识(2017年完成)

就是要你懂网络–一个网络包的旅程

通过案例来理解MSS、MTU等相关TCP概念

就是要你懂TCP–握手和挥手

wireshark-dup-ack-issue and keepalive

一个没有遵守tcp规则导致的问题

[kubernetes service 和 kube-proxy详解](/2020/09/22/kubernetes service 和 kube-proxy详解/)

DNS相关

就是要你懂DNS–一文搞懂域名解析相关问题

nslookup OK but ping fail

Docker中的DNS解析过程

windows7的wifi总是报DNS域名异常无法上网

LVS 负载均衡

就是要你懂负载均衡–lvs和转发模式

就是要你懂负载均衡–负载均衡调度算法和为什么不均衡

网络工具

就是要你懂Unix Socket 进行抓包解析

就是要你懂网络监控–ss用法大全

就是要你懂抓包–WireShark之命令行版tshark

netstat timer keepalive explain

Git HTTP Proxy and SSH Proxy

开源代码加个壳,年收你 15 万美金——一次 RDS 迁移自建的成本审计

一句话结论

我们把 6 个 RDS MySQL 集群迁到 EC2 自建,年省 $151,425(76%)。这不是什么黑科技,就是把云厂商帮你装好的 MySQL 自己装了一遍。


云数据库的定价逻辑

RDS 的本质是:在 EC2 上跑一个开源数据库,加一层管控面板,然后把价格翻一倍往外卖。

以 ap-east-1 区域 db.m5d.xlarge(4C 16G)为例:

部署方式 小时单价 倍率
EC2 同配置裸机 $0.277/hr
RDS Single-AZ $0.638/hr 2.3×
RDS Multi-AZ(2 节点) $1.276/hr 4.6×
RDS Multi-AZ DB Cluster(3 节点) $1.768/hr 6.4×

存储更离谱。同样的 gp3 磁盘:

EBS 直接挂载 RDS 存储(3 节点集群) 倍率
容量 $0.1056/GB-month $0.45/GB-month 4.3×
IOPS(超基线) $0.0066/IOPS-month $0.078/IOPS-month 11.8×
吞吐(超基线) $0.0528/MiBps-month $0.313/MiBps-month 5.9×

你没看错——同一块硬盘、同一个 IOPS,挂在 RDS 上比挂在 EC2 上贵 12 倍

那管控面板值这个差价吗?


管控做了什么:收钱的自动化

RDS 管控提供的核心能力:

  1. 自动备份 —— 一个 cron + mysqldump/xtrabackup 的事
  2. 自动故障切换 —— 开源社区 orchestrator/MHA 免费且更灵活
  3. 自动小版本升级 —— 这不是优点,这是灾难(下面细说)
  4. 监控 —— Performance Insights 还要额外收费,基础 CloudWatch 指标连 QPS 都看不到
  5. 参数管理 —— 一个 my.cnf 的事,还不让你改一半参数

真正恶心的是强制升级。

MySQL 8.0 社区还在维护,RDS 直接宣布 EOL,逼你升 8.4。理由?”降低我们的运维成本”。从来不考虑:

  • 你的 ORM 框架兼不兼容
  • 你的 CDC 组件(Canal/Debezium)测过没有
  • 你的 SQL 在新优化器下会不会回退

云厂商嘴上说”客户第一”,实际做的每一个决策都是”降低自己的运维成本,把风险转嫁给客户”。一个 Terraform apply 就把你几百个集群的引擎版本全换了,你连说不的机会都没有。


实战:6 个集群的迁移账本

原始配置

# RDS 规格 节点数 存储 IOPS 月费
1 db.m5d.4xlarge (16C 64G) 3 500GB gp3 12,000 $6,208
2 db.m5d.2xlarge (8C 32G) 3 500GB gp3 12,000 $3,626
3 db.m5d.2xlarge (8C 32G) 3 500GB gp3 12,000 $3,626
4 db.m5d.xlarge (4C 16G) 3 400GB gp3 12,000 $2,290
5 db.m5d.large (2C 8G) 3 200GB gp3 3,000 $735
6 db.t3.small (2C 2G) 2 100GB gp2 $114
合计 $16,598/月

迁移后实际 EC2 配置

# EC2 规格 节点数 存储 IOPS 月费
1 m7i.xlarge (4C 16G) 3 350GB gp3 3,000 $734
2 m6i.2xlarge (8C 32G) 3 350GB gp3 3,000 $1,283
3 r6i.xlarge (4C 32G) 3 350GB gp3 3,000 $858
4 m7i.xlarge (4C 16G) 3 350GB gp3 3,000 $734
5 c7i.large (2C 4G) 3 100GB gp3 3,000 $296
6 规划 t3.small 2 100GB gp3 3,000 $74
合计 $3,979/月

成本分析

RDS 年费:$199,174
EC2 年费:$47,749
年省:$151,425(76%)


省钱的三个层次

第一层:平移替换(省 50-60%)

单纯把 RDS 换成同规格 EC2 自建 MySQL,不做任何优化。省钱来源:

  • 去掉 RDS 的”管控溢价”(计算 2-3 倍)
  • 去掉存储的”托管溢价”(IOPS 12 倍)
  • 使用 gp3 基线 3000 IOPS 免费额度(RDS 要额外收钱)

第二层:基于监控降配(再省 15-20%)

拉取 48 小时监控后发现:

集群 CPU Avg 存储 IOPS 实际使用 配置 IOPS 利用率
集群 1(16C 64G) 2.5% 20 12,000 0.17%
集群 5(2C 8G) 17.5% 0.7 3,000 0.02%
集群 6(2C 2G) 4.3% 0.8

集群 1 尤其荒唐:RDS 上跑着 16C 64G 的大实例,实际 CPU 平均 2.5%,存储 IOPS 日常仅 20。我们直接降到 4C 16G,一个集群就省了 $65,687/年

这不是什么高难度操作——拉个 CloudWatch 指标谁都会。但如果你用着 RDS,你永远不会去想”我要不要降配”,因为:

  1. RDS 没有直观的利用率告警(连 QPS 都不给你看,要开 Performance Insights 再付钱)
  2. 修改实例规格需要重启,Multi-AZ 切换有风险
  3. 反正不是自己的钱,KPI 不考核基础设施成本

第三层:总结

层次 动作 节省比例
平移替换 RDS → EC2 同规格 50-60%
监控降配 基于实际负载缩减规格 +15-20%
合计 ~76%

这只是冰山一角

上面 6 个集群的 RDS 年费不到 20 万美金。在我们整个基础设施账单里,这连 5% 都不到。

如果把所有托管服务(RDS、ElastiCache、MSK、OpenSearch……)全部迁移自建,按同样的比例估算,年省百万美金量级不是梦话。

而在国内互联网行业,很多公司一年在云上花几千万甚至几个亿人民币。按我们实测的 76% 节省比例,实际可能只需要 20-30% 的预算就能跑同样的业务。剩下的钱去哪了?去了云厂商的毛利率报表里。


更进一步:EC2 到 IDC 自建

如果 RDS 到 EC2 能省 76%,那 EC2 到自建 IDC 呢?

EC2 本身也有”云溢价”。同样一台 4C 16G 的服务器:

方案 月成本估算 相对 EC2
EC2 On-Demand $202/月
EC2 1年 Savings Plan $140/月 0.7×
IDC 自建(含托管+带宽+折旧) $60-80/月 0.3-0.4×

经验法则:当你的年云支出超过 1000 万人民币(约 $140 万美金),就应该认真评估自建 IDC 或混合架构了。在这个规模下:

  • 你已经有足够的运维团队
  • 服务器采购有议价空间
  • 网络带宽成本可以通过 BGP 直连大幅降低
  • 3 年折旧后硬件几乎是”免费”的

工程师的价值

$151,425/年

这是一个 DBA 花两周时间做迁移评估 + 执行带来的年化收益。这笔钱:

  • 在北京够招一个资深工程师
  • 在二线城市够招两个
  • 比 90% 的”降本增效”项目 ROI 都高

而且这还只是”小试牛刀”——6 个中小规格集群。

别忘了,这原本 20 万刀的开支上面,云厂商还要再收 8% 的企业支持服务费(Enterprise Support)。$199,174 × 8% = $15,934/年,又是一个工程师的工资。

放大到整个公司:如果你一年在云上花 1000 万人民币,8% 就是 80 万——够养一个 3-4 人的专职运维团队了。而云厂商的”支持服务”给你什么?一个工单系统、一个响应 SLA、偶尔帮你提个 limit。你自己的工程师调个参数 5 分钟搞定的事,走工单要等 24 小时。

如果你是多云架构,情况更糟:

  • 每家云都要交一份支持费
  • 每家的 API/控制台/计费模型都不一样,运维工具要写多套
  • 跨云网络打通本身就是成本(专线、VPN、流量费)
  • 出了问题两家互相甩锅,你夹在中间当传话筒

如果你已经有了 IDC 自建能力,云上的托管服务就是在给云厂商交智商税。 同样的 MySQL、同样的 Redis、同样的 Kafka——跑在你自己机房的服务器上,性能更好、延迟更低、成本是云上的 1/5。

云厂商的销售会告诉你”自建运维成本高””要招人要管理”。但他们不会告诉你:

  • 他们的托管服务本身就是你花钱让别人招了个运维
  • 这个运维收费是市场价的 5-10 倍
  • 这个运维还会强制你升级、限制你改配置、监控还要额外付费
  • 你交的 8% 支持费,换来的是一个工单系统和一句”建议您升级到最新版本”

AI 才是真正的降本增效工具

很多人问:自建听起来好,但你哪来的人力做迁移评估、写管控脚本、搞高可用切换?

答案是:AI。

这次 6 个集群的迁移评估,从拉取 RDS 配置、查询 CMDB 元数据、获取 EC2 实际规格、抓取 AWS 官方定价 JSON、计算成本对比、生成汇总报告——全程由 AI Agent 完成。一个 DBA 坐在终端前给指令,AI 负责执行。整个成本审计过程不到 2 小时。

传统做法?开会讨论 → 安排人力 → 写脚本拉数据 → Excel 算半天 → 做 PPT 汇报 → 领导审批。一个月能出结果算快的。

AI 在这次迁移中具体干了什么

环节 AI 完成的工作 替代的传统人力
配置审计 批量调用 AWS CLI 拉取 6 个集群的 RDS/EC2 规格、存储、IOPS 运维工程师手动登录控制台逐个记录
价格计算 从 AWS Bulk Pricing JSON(几百 MB)中精确提取区域定价 打开 N 个定价页面手动比对
CMDB 关联 SSH 跳板机查询内部元数据库,关联 RDS 与 EC2 实例 运维人员人肉翻 CMDB
监控分析 批量拉 CloudWatch 48h 数据,识别降配机会 人工看图、拍脑袋
报告生成 直接输出结构化 Markdown/飞书文档 写 Word、排版、发邮件
迁移工具 生成数据校验脚本、切换 checklist、回滚方案 高级 DBA 手写

为什么很多公司 AI “烧 token 看不到效果”

每月花几万块 token 费,产出是什么?让员工用 ChatGPT 润色周报、用 Copilot 补全几行代码、开会用 AI 做纪要。这些场景有价值吗?有。但 ROI 约等于零——因为省的是”5 分钟”,不是”5 万美金”。

AI 降本增效的正确姿势:让 AI 去做那些”能做但没人力做”的事。

成本审计就是典型。每个公司都知道云上可能有浪费,但:

  • 没人有空去逐个实例拉监控
  • 没人愿意花一周时间算 Excel
  • 算完了还不一定能推动执行

AI 把这个成本降到接近零。一次对话 = 一次完整审计 = 发现 $15 万/年的节省机会。 这次对话消耗的 token 费?不到 $5。

ROI 对比

场景 投入 年化产出 ROI
AI 润色周报/邮件 $100/月 token 省 10 小时人力 ≈ $500
AI 辅助写代码 $200/月 token 省 20% 开发时间 ≈ $2,000 10×
AI 做基础设施成本审计 $5 token $151,425/年 30,000×

差距不是 AI 本身的问题,是你让 AI 做什么的问题。

让 AI 帮你写”尊敬的领导,现将本周工作汇报如下”——这不叫降本增效,这叫浪费电。让 AI 帮你查明白每年有 15 万美金在被云厂商白拿——这才叫降本增效。

给管理者的建议

  1. 别让 AI 去做”锦上添花”的事,让它去做”本来没人力做”的事
  2. 基础设施成本审计是最容易落地的高 ROI 场景——数据结构化、API 可调用、结果可量化
  3. 把 AI 当成一个 7×24 的初级运维,给它明确的指令和工具权限,它能干的活比你想象的多
  4. 衡量 AI 投入的标准不是”省了多少时间”,而是”做了多少原来做不了的事”

结语

云厂商不是做慈善的。RDS 的商业模式就是:

把 MySQL 官网免费下载的二进制文件装到你本来就在付费的 EC2 上,加一个 Web 控制台,然后跟你收 2-12 倍的溢价

这门生意的毛利率,做梦都能笑醒。

而你只需要一个懂 MySQL 的工程师、一套开源高可用方案(orchestrator + ProxySQL)、一个备份脚本——就能省下 75% 的钱,还能获得更大的灵活性。

不是所有上云都是降本。绝大多时候,下云才是。

云计算极致弹性的骗局

一句话总结

云厂商卖的是”随时扩容、秒级弹性”,实际交付的是”库存看运气、升配等半天、换代要验证、出了问题没人兜底”。

今天发生了什么

我们的内部某个系统需要紧急扩容。业务处于重保状态,绝对不能出问题。

结果呢?在阿里云上升配一台 ECS,花了超过 5 个小时,到现在还没搞定。

原因:

  • 7 代机库存不足,扩不上去
  • 9 代机有库存,但不让从 7 代直接升——AMD/Intel 架构差异、机器代数差异等”稳定性考量”不允许跨代升配
  • 资源明明有,但就是用不上

这就是云厂商口中的”极致弹性”。

弹性的真相:一张限制清单

云厂商的宣传:需要资源?点一下,秒级到位。

实际情况:

你以为的 实际的
随时扩容 老代际没库存,扩不动
秒级弹性 升配排队 5 小时起步
按需付费 想用新代际?先全量迁移+验证
免运维 云厂商改默认参数不通知你,出了问题你自己查

升级坑死你的案例:https://plantegg.github.io/2026/04/15/AWS-HikariCP-%E8%BF%9E%E6%8E%A5%E8%B6%85%E6%97%B6%E6%A0%B9%E5%9B%A0%E5%88%86%E6%9E%90/

更讽刺的是——今天有库存不代表明天有。库存是动态的,哪天一个大客户扫一波资源,你原来能扩的机型就扩不动了。

换代验证:花钱替云厂商做测试

云厂商每隔两三年推出新一代实例。旧代际的库存会逐渐减少。为了保证未来能弹性扩容,你就得主动迁移到新代际。

迁移意味着什么?

  1. 新旧代际的默认参数可能不一致
  2. 你要停下业务开发,专门去做兼容性验证
  3. 验证过了,也不能保证不漏——因为有些差异只在特定场景才暴露

这不是假设,是真实踩过的坑:

AWS 第 8 代 EC2 实例(2025 年 9 月上线),把 ENI 安全组的连接跟踪超时从 5 天(432000 秒)悄悄改成了 350 秒。没有独立公告,没有迁移指南,甚至 API 在 6 个月后才开始返回这个参数:https://plantegg.github.io/2026/04/15/AWS-HikariCP-%E8%BF%9E%E6%8E%A5%E8%B6%85%E6%97%B6%E6%A0%B9%E5%9B%A0%E5%88%86%E6%9E%90/

后果:所有跨网络的长连接(数据库、消息队列、RPC),只要空闲超过 350 秒,就会被安全组静默丢弃——不发 RST,不通知任何一方。应用端看到的就是”莫名超时”。我们的 Java 服务迁移到 AWS 8 代实例后,HikariCP 连接池每隔 20 分钟就批量报错。

排查花了多久? 从开 case 到定位根因,19 小时。AWS 自己的支持工程师都要开两轮会议才找到原因。而 AWS 确认,已有 6 家大型企业、10 余个支持案例报告了同一问题——实际受影响的用户远不止这些,因为”静默丢包”根本不会产生明确的错误信号。

这就是你要做的”换代验证”——替云厂商测试他们自己都没文档化的行为变更。

自建机房为什么不需要这种验证

“买新物理机不也要验证吗?”——不需要,或者说简单到可以忽略。

原因很直接:

物理机是干净的。 一台戴尔/联想的服务器,装完 OS 就能用。服务器厂商在出厂前已经做过 OS 兼容性测试。你的业务直接跑在裸金属上,中间没有任何隐藏层。

ECS/EC2 不是干净的。 云厂商在你的 VM 和物理硬件之间塞了一堆自己的服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
你以为的结构:          实际的结构:

┌─────────────┐ ┌─────────────┐
│ 你的应用 │ │ 你的应用 │
├─────────────┤ ├─────────────┤
│ OS │ │ OS │
├─────────────┤ ├─────────────┤
│ 硬件 │ │ 虚拟化层 │ ← 你看不到、控制不了
└─────────────┘ ├─────────────┤
│ ENI 连接跟踪│ ← 默认参数随代际变
├─────────────┤
│ 云盘 IO 调度│ ← 性能特征随代际变
├─────────────┤
│ 管控面代理 │ ← 占 CPU/内存
├─────────────┤
│ Nitro/神龙卡│ ← 固件行为不透明
├─────────────┤
│ 物理硬件 │
└─────────────┘

每换一代实例,这些隐藏层的行为都可能变化。而且云厂商不会事先告诉你变了什么——因为这些是他们的”内部实现细节”。

物理机换代: 装 OS → 简单压测 → 上线。一个运维花半天搞定。不需要惊动业务研发。

ECS 换代: 申请新代际实例 → 部署全套应用 → 回归测试 → 性能对比 → 连接行为验证 → 灰度切流 → 观察一周。一个团队花两周,业务研发全部停下来配合。

你花钱买了”弹性”,结果每两年要停下来做一次全量迁移验证。这不是弹性,这是供着一个祖宗。

库存问题无解

有人说:”跟云厂商提前报备,让他们预留库存。”

想想这意味着什么:

  • 你要提前规划未来的扩容需求(那还要弹性干什么?)
  • 你要信任云厂商的库存承诺(今天有库存明天就没了)
  • 你要绑定特定代际(否则哪天被迫换代又要全量验证)

按需、弹性、免规划——卖点一个都兑现不了。

结论

云计算的”极致弹性”是一个营销概念,不是工程事实。

真实的云计算体验是:

  • 扩容要看库存脸色——紧急时刻扩不动
  • 换代要做全量验证——业务研发替云厂商测试
  • 默认参数会变——不通知、不文档化、出了问题你自己查
  • 中间层行为不透明——静默丢包连错误信号都没有

如果你的业务对可用性有要求,在做架构决策时,请把这些成本算进去。不要被”秒级弹性”的 PPT 忽悠了。

5 个小时了,我只是想给一台 ECS 加点配置而已。

JVM DNS 缓存 TTL 配置避坑指南(实验验证版)

适用范围:所有 Java 业务,尤其在用域名而非 IP 接入下游服务(数据库、Kafka、Redis、HTTP 服务等)的场景。
验证环境:OpenJDK 17(Rocky Linux 8.10);结论同样适用 Java 8/11/21。
验证日期:2026-05-25。

TL;DR(先看这部分)

如果你只想拿走一条结论:

-Dnetworkaddress.cache.ttl=N 是错的,不会生效

想用 JVM 启动参数控制 DNS 缓存 TTL,只有 -Dsun.net.inetaddr.ttl=N 这一种正确写法

如果还能拿走第二条:

代码里 Security.setProperty("networkaddress.cache.ttl", "N") 极易被 log4j2、Spring、Kafka client 等抢跑而失效。生产配置不要依赖这种方式。

如果还能拿走第三条:

推荐配置(任选其一,不用全选)

  1. 启动参数:-Dsun.net.inetaddr.ttl=30 -Dsun.net.inetaddr.negative.ttl=10
  2. 或修改 $JAVA_HOME/conf/security/java.securitynetworkaddress.cache.ttl=30networkaddress.cache.negative.ttl=10

下面是 11 组对照实验的证据。


1. 背景:两个属性、两套存储、一个静态字段

1.1 控制 JVM DNS 缓存 TTL 的两个属性

属性名 类别 设置途径 备注
networkaddress.cache.ttl Security property 代码 Security.setProperty(...)$JAVA_HOME/conf/security/java.security 文件 Java 1.4+ 官方正名
sun.net.inetaddr.ttl System property 代码 System.setProperty(...);JVM 启动参数 -D Sun 私有的旧名,作为 fallback 保留

负向缓存对应 networkaddress.cache.negative.ttl / sun.net.inetaddr.negative.ttl

1.2 JDK 内部的读取逻辑(OpenJDK 17 源码 sun.net.InetAddressCachePolicy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final class InetAddressCachePolicy {
private static volatile int cachePolicy; // ← 真正起作用的值

static { // ← 类首次加载时执行 1 次,之后再不读取
Integer tmp = AccessController.doPrivileged(...) {
// 1) 优先读 Security.getProperty("networkaddress.cache.ttl")
// 2) fallback 读 System.getProperty("sun.net.inetaddr.ttl")
};
cachePolicy = (tmp != null) ? tmp
: (hasSecurityManager ? FOREVER : 30); // 默认 30s
}

public static int get() { return cachePolicy; }
}

三个关键事实:

  1. 静态块只跑一次(class load 时),之后不再读 Security/System property。
  2. 所以业务代码里再调 Security.setProperty(...) 改 TTL,InetAddressCachePolicy 不会回头读——值已经被冻在 cachePolicy 字段里了。
  3. JVM 内部 System Properties 与 Security Properties 是两套独立存储
    • -Dnetworkaddress.cache.ttl=N 写进的是 System Properties
    • 但 InetAddressCachePolicy 第一步走 Security.getProperty(...),根本不读 System Properties
    • 所以这种写法虽然不报错,但完全没有效果

1.3 默认值

  • 无 SecurityManager(绝大多数现代生产场景):正向 30 秒,负向 10 秒
  • 有 SecurityManager(极少见):正向 forever(永久),负向 10 秒

2. 实验设计

2.1 待验证的核心假设

任何在你 Security.setProperty(...) 之前调用 InetAddress.getXxxByName() / getLocalHost() 的代码,都会触发 InetAddressCachePolicy 类首次加载,使 cachePolicy 字段被冻结到 JVM 默认值。其中最常见的抢跑者就是 log4j2 的 LogManager.getLogger(...)——尤其是写在 static final 字段里的那种。

2.2 测量方法(双重证据)

  • 直接证据:反射读取 sun.net.InetAddressCachePolicy.get() 拿到 effective 值
  • 间接证据tcpdumpudp dst port 53 包,统计 20 秒内对目标域名的实际 DNS 查询次数
    • 若 TTL=2 生效:约 20+ 次(每秒一查,缓存基本不命中)
    • 若 TTL 失效(默认 30s):约 4~6 次(启动 overhead + 全程命中缓存)
    • 差异 4~6 倍,结论稳定

2.3 11 个对照场景

# TTL 设置方式 log4j Logger 时机
S1 -Dnetworkaddress.cache.ttl=2 不引入 log4j(基线)
S2 代码 Security.setProperty(main 首行) 不引入 log4j(基线)
S3 代码 setProperty(main 首行) setProperty 之后再 LogManager.getLogger
S4 代码 setProperty static final Logger 字段(类加载即触发,生产里最常见的写法
S5 代码 setProperty main 中先 LogManager.getLoggersetProperty(手写错顺序)
S6 -Dnetworkaddress.cache.ttl=2 static final Logger 字段
S7 -Dsun.net.inetaddr.ttl=2 不引入 log4j
S8 -Dsun.net.inetaddr.ttl=2 static final Logger 字段(验证 -D 能否兜底)
S9 -Dsun.net.inetaddr.ttl=2 main 中先 getLogger 后 setProperty
S10 java.security 文件 networkaddress.cache.ttl=2 不引入 log4j
S11 java.security 文件 networkaddress.cache.ttl=2 static final Logger 字段(验证文件能否兜底)

3. 实验结果

# TTL 设置方式 log4j Logger 时机 DNS 查询数 cachePolicy TTL 生效
S1 -Dnetworkaddress.cache.ttl=2 6 30
S2 代码 Security.setProperty 26 2
S3 代码 setProperty setProperty 后 getLogger 26 2
S4 代码 setProperty static final 字段 4 30
S5 代码 setProperty main 中 getLogger 先于 setProperty 4 30
S6 -Dnetworkaddress.cache.ttl=2 static final 字段 6 30
S7 -Dsun.net.inetaddr.ttl=2 26 2
S8 -Dsun.net.inetaddr.ttl=2 static final 字段 26 2
S9 -Dsun.net.inetaddr.ttl=2 main 中 getLogger 先 24 2
S10 java.security 文件 26 2
S11 java.security 文件 static final 字段 26 2

TTL=2,每秒解析一次共 20 次。生效时 cachePolicy=2、DNS 查询数 ≈ 20+;失效时 cachePolicy=30、查询数 ≈ 46(这 46 次是 JVM 启动期 hostname/reverse-lookup 等开销,业务期完全命中缓存)。

3.1 四种主流设置方式的最终判定

设置方式 验证场景 判定
-Dnetworkaddress.cache.ttl=N S1, S6 完全无效(写错 property store)
代码 Security.setProperty(...) S2, S3 / S4, S5 ⚠️ 理论可行,实际极易被抢跑
-Dsun.net.inetaddr.ttl=N S7, S8, S9 稳定生效,能兜底任意代码顺序
java.security 文件 networkaddress.cache.ttl=N S10, S11 稳定生效,能兜底任意代码顺序

4. 为什么 log4j2 会”覆盖”你的设置(机制澄清)

严格说不是覆盖,是读取时机错过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
时间轴(坏写法 S4):

t0 类加载 MyClass(业务的 main 类)
t0a → static final Logger LOG = LogManager.getLogger(MyClass.class); ← 类加载阶段
t0b → log4j2 LoggerContext init
t0c → 解析配置 / 注册 ServiceLoader / hostname lookup
t0d → 第一次调到 InetAddress.getXxxByName()
t0e → 触发 InetAddressCachePolicy.<clinit>
t0f → Security.getProperty("networkaddress.cache.ttl") = null
t0g → System.getProperty("sun.net.inetaddr.ttl") = null
t0h → 用默认值 30,写入 cachePolicy 字段,**永久冻结**

t1 main() 进入
t1a Security.setProperty("networkaddress.cache.ttl", "5");
↑ 写进了 Security Properties Map,但 cachePolicy 字段不再被读
t1b 之后所有 InetAddress 操作 → InetAddressCachePolicy.get() → 30

4.1 抢跑者远不止 log4j2

任何在 Security.setProperty 之前触发 InetAddress.getXxxByName/getLocalHost 的代码,都会冻结 cachePolicy。常见的有:

抢跑者 触发路径
log4j2 / logback LogManager.getLogger() 初始化 LoggerContext,配置里 ${hostName}/%H 或某些默认 Lookup 触发
java.util.logging (JUL) LogRecord 默认携带 hostname
Spring Boot 启动 banner、Actuator、InetUtils 自动选 IP
Tomcat / Jetty / Netty bind() 时解析监听地址;Netty 还会初始化 DNS resolver
Kafka client KafkaProducer/Consumer 构造时 ClientUtils.parseAndValidateAddresses 解析 bootstrap 域名
HikariCP / Druid 等连接池 初始化时连第一个 DB 实例(解析 JDBC URL host)
JMX / RuntimeMXBean getRuntimeMXBean().getName()pid@hostname,触发 reverse lookup
Micrometer / Prometheus 注册 metrics 时打 hostname tag
Apache HttpClient / OkHttp client 构造时可能预解析
Java agent (-javaagent) APM agent (Skywalking、Pinpoint、NewRelic、DataDog) 在 premain() 阶段就跑,早于 main,常自报 hostname——这条最阴险,业务代码完全没写错,agent 默默把你的 setProperty 干掉了

只要这个清单里任意一项先于业务代码 Security.setProperty,TTL 就被冻在默认值。


5. 业务方避坑清单(必读)

5.1 必须避免

❌ 错误写法 错误原因
-Dnetworkaddress.cache.ttl=30 写进了 System Properties,但 InetAddressCachePolicy 只从 Security Properties 读这个名字。完全无效。
Security.setProperty(...) 写在 static {} 块或字段初始化里 与其他 static 初始化的执行顺序不可控,几乎注定被 log4j 抢跑
把 setProperty 放在某个工具类的 init 方法里、依赖被调用一次 同上,时机不可控
只设正向、不设负向 默认负向 10 秒(部分 Linux 发行版打包甚至改过这个值);DNS 失败的负向缓存仍然影响故障切换

5.2 推荐做法(任选其一)

方案 A:JVM 启动参数(最方便、最不容易出错)

1
2
3
java -Dsun.net.inetaddr.ttl=30 \
-Dsun.net.inetaddr.negative.ttl=10 \
-jar app.jar

适用场景:业务团队普遍写 java.security 文件不方便,或者运维平台/发布系统能统一注入 JVM 参数。

方案 B:修改 java.security 配置文件(系统级、所有 Java 进程统一生效)

编辑 $JAVA_HOME/conf/security/java.security(Java 8 是 $JAVA_HOME/jre/lib/security/java.security):

1
2
networkaddress.cache.ttl=30
networkaddress.cache.negative.ttl=10

注意:

  • 该文件可能本来就有这两行,要么注释掉、要么是默认值。不要新增重复行
  • 修改后所有运行该 JDK 的进程都会生效,改之前确认无副作用
  • RPM 装的 JDK 在升级时会用包里的版本覆盖该文件,升级流程要带回这个修改
  • 实测发现 RHEL/Rocky 默认就有 networkaddress.cache.negative.ttl=10 这行(不是 JDK 默认 0),删它会改变行为。

方案 C:代码内 Security.setProperty(...) —— 不推荐

如果实在因为某些原因要用代码方式设置:

1
2
3
4
5
6
public static void main(String[] args) {
// 必须是 main 第一行(甚至要早于该类的 static field 初始化,但 static field 在 main 之前已执行)
Security.setProperty("networkaddress.cache.ttl", "30");
Security.setProperty("networkaddress.cache.negative.ttl", "10");
// ……
}

且必须确保这个 main 类不持有任何 static final Logger 字段——否则 log4j 在类加载期就跑完了。

但即便这样,仍然防不住 -javaagent 在 premain 阶段抢跑。所以代码方式只在简单场景下能用,在带 APM agent 的环境里基本必败。

5.3 取值建议

场景 正向 TTL 负向 TTL
一般业务 30 秒 10 秒
频繁 DNS 切换/扩缩容 10 ~ 30 秒 5 ~ 10 秒
DNS 极少变更、追求性能 60 ~ 300 秒 30 秒
永远不要 -1(永久缓存)—— 这是带 SecurityManager 时的默认值,DNS 一变就再也感知不到 0 也要慎用——DNS 失败时会变成每次解析打 DNS server,可能造成查询风暴

6. 验证与诊断

6.1 一行命令验证 TTL 是否生效

1
2
3
4
5
# 替换 -Dsun.net.inetaddr.ttl=2 为你实际的写法,看打印是不是 2
java -Dsun.net.inetaddr.ttl=2 \
--add-opens java.base/sun.net=ALL-UNNAMED \
-e 'System.out.println(((Integer)Class.forName("sun.net.InetAddressCachePolicy").getMethod("get").invoke(null)));' \
2>/dev/null

或者写一个最简验证类:

1
2
3
4
5
6
7
8
public class TtlCheck {
public static void main(String[] args) throws Exception {
java.lang.reflect.Method m = Class.forName("sun.net.InetAddressCachePolicy")
.getMethod("get");
m.setAccessible(true);
System.out.println("Effective TTL = " + m.invoke(null) + " seconds");
}
}

运行:java --add-opens java.base/sun.net=ALL-UNNAMED TtlCheck

期望输出:Effective TTL = 30 seconds(或你设置的值);如果是其他奇怪值就有问题。

6.2 定位是谁在抢跑(深度排查)

1
java -Xlog:class+init=info ...your-app... 2>&1 | grep -E 'InetAddressCachePolicy|InetAddress\$'

能看到 InetAddressCachePolicy 在哪个时点、被哪个类引用首次初始化。结合 -XX:+TraceClassLoading 或在该类静态块挂断点能看到完整调用栈。

6.3 用 tcpdump 验证业务运行期的 DNS 查询频次

1
2
3
4
# 在业务实例上抓 30 秒
sudo tcpdump -i any -nn 'udp port 53' -w /tmp/dns.pcap &
sleep 30 ; sudo killall tcpdump
sudo tcpdump -nn -r /tmp/dns.pcap | grep '<your-domain>' | wc -l

把这个数字除以 30 得到每秒查询频次。如果查询频次 << 1/TTL,说明 TTL 比预期大;如果 ≈ 业务每秒解析次数,说明缓存几乎不命中。


7. 附录

7.1 实验脚本与原始日志

  • 实验目录:~/q/tmp/jvm-dns-ttl-log4j-test/(本地)/ /root/jvm-dns-ttl-log4j-test/(测试机 172.30.65.103)
  • 主程序:TtlProbe.java
  • 跑 S1~S9:bash run-experiment.sh
  • 跑 S10/S11:bash run-jsec-experiment.sh(自动备份/还原 java.security)
  • 原始 pcap + log:results/

7.2 历史背景:为什么 JVM 有”两个名字”

  • JDK 1.4 之前:只有 sun.net.inetaddr.ttl,Sun 私有 system property
  • JDK 1.4(2002 年):把 DNS 缓存策略正式化到 Security property 标准里,引入 networkaddress.cache.ttl 作为官方名
  • 此后至今:旧名 sun.net.inetaddr.ttl 没废弃,作为 fallback 保留——保兼容

设计层面的内在矛盾:官方名是 Security property,但 JVM 最方便的设置方式(-D)只能设 System property。绝大多数业务方踩坑,根源就是直觉地把这两者拼成 -Dnetworkaddress.cache.ttl=N,然后悄悄失效。

7.3 相关资源

7.4 验证环境

  • OS:Rocky Linux 8.10
  • JDK:OpenJDK 17.0.19(Red_Hat-17.0.19.0.10-1)
  • log4j2:2.20.0
  • 测试域名:3 条 A 记录的内网域名
  • 验证日期:2026-05-25

MySQL PreparedStatement 性能问题重现报告

1. 问题概述

1.1 问题描述

在 MySQL 使用 useServerPrepStmts=true 时,处理大量参数(5万个)的 PreparedStatement IN 查询时存在严重性能问题。根据原始报告,服务器端预编译比客户端预编译慢 190-207倍

1.2 问题来源

1.3 问题根因(原始报告)

MySQL 服务器在处理大量参数的 PreparedStatement 时:

  1. 大量内存重分配: 50,000 次参数替换操作
  2. 字符串操作复杂度: O(SQL长度) × 参数数量
  3. 内存碎片化: 频繁的大块内存分配和释放

2. 测试环境

2.1 AWS 资源信息

资源 配置
AWS Account 872515255872
Region ap-southeast-1
VPC vpc-084114e405054a5b7

2.2 RDS MySQL 8.0 实例

配置项
实例标识符 mysql-prepared-test
实例类型 db.t3.medium (2vCPU, 4GB)
存储 50GB gp3
引擎版本 MySQL 8.0.43
Endpoint mysql-prepared-test.cfsoq6muu0jv.ap-southeast-1.rds.amazonaws.com

2.3 RDS MySQL 5.7 实例

配置项
实例标识符 mysql57-prepared-test
实例类型 db.t3.medium (2vCPU, 4GB)
存储 50GB gp3
引擎版本 MySQL 5.7.44-rds.20240408
Endpoint mysql57-prepared-test.cfsoq6muu0jv.ap-southeast-1.rds.amazonaws.com

2.4 EC2 测试客户端

配置项
实例 ID i-0b26f3cb781bae059
实例类型 t3.medium
AMI Amazon Linux 2023
Public IP 18.141.185.36
Java Amazon Corretto 17
Maven 3.8.4

3. 测试方法

3.1 测试代码

1
2
3
4
git clone https://github.com/plantegg/MySQLPrepared.git
cd MySQLPrepared
./run_test.sh --host <mysql-host> --port 3306 --database test \
--user admin --password '<password>' --rounds 3

3.2 测试参数

参数
IN 查询参数数量 50,000
参数类型 15位大整数
SQL 长度 (spaces=128) ~6.5MB
测试轮次 3

3.3 AWS CLI 命令

创建 RDS MySQL 8.0 实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
aws rds create-db-instance \
--profile default --region ap-southeast-1 \
--db-instance-identifier mysql-prepared-test \
--db-instance-class db.t3.medium \
--engine mysql \
--engine-version 8.0 \
--master-username admin \
--master-user-password 'Tiger#2612' \
--allocated-storage 50 \
--storage-type gp3 \
--db-subnet-group-name mysql-benchmark-subnet-group \
--vpc-security-group-ids sg-01541b078e0b483d0 \
--no-multi-az \
--publicly-accessible \
--backup-retention-period 0 \
--no-auto-minor-version-upgrade

创建 RDS MySQL 5.7 实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
aws rds create-db-instance \
--profile default --region ap-southeast-1 \
--db-instance-identifier mysql57-prepared-test \
--db-instance-class db.t3.medium \
--engine mysql \
--engine-version 5.7.44-rds.20240408 \
--master-username admin \
--master-user-password 'Tiger#2612' \
--allocated-storage 50 \
--storage-type gp3 \
--db-subnet-group-name mysql-benchmark-subnet-group \
--vpc-security-group-ids sg-01541b078e0b483d0 \
--no-multi-az \
--publicly-accessible \
--backup-retention-period 0 \
--no-auto-minor-version-upgrade

创建 EC2 测试实例

1
2
3
4
5
6
7
8
aws ec2 run-instances \
--profile default --region ap-southeast-1 \
--image-id ami-0d1c0ec9903f7b01f \
--instance-type t3.medium \
--key-name renxijun-ec2-key \
--security-group-ids sg-0706d5fbe75649370 \
--subnet-id subnet-09d864b724dce6434 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mysql-prepared-test-ec2}]'

4. 测试结果

4.1 MySQL 8.0.43 测试结果

紧凑格式 (spaces=0, SQL长度 ~100KB)

配置 平均执行时间 Com_stmt_prepare
useServerPrepStmts=false 129.6ms 0
useServerPrepStmts=true 115.6ms 1
性能差异 true 快 1.1 倍 -

带空格格式 (spaces=128, SQL长度 ~6.5MB)

配置 平均执行时间 Com_stmt_prepare
useServerPrepStmts=false 400.7ms 0
useServerPrepStmts=true 101.0ms 1
性能差异 true 快 4.0 倍 -

4.2 MySQL 5.7.44 测试结果

带空格格式 (spaces=128, SQL长度 ~6.5MB)

配置 平均执行时间 Com_stmt_prepare
useServerPrepStmts=false 600.0ms 0
useServerPrepStmts=true 90.0ms 1
性能差异 true 快 6.7 倍 -

4.3 与原始报告对比

版本 原始报告 (5.7.29) 本次测试 (5.7.44) 本次测试 (8.0.43)
false 平均时间 ~52ms 600ms 400.7ms
true 平均时间 ~27,839ms 90ms 101ms
性能差异 true 慢 535 倍 true 快 6.7 倍 true 快 4.0 倍

5. 结论

5.1 问题重现结果

在 MySQL 5.7.44 和 8.0.43 版本上,原始报告中描述的性能问题未能重现。

测试结果显示:

  • 在两个版本上,useServerPrepStmts=true 反而比 false 更快
  • MySQL 5.7.44: 服务器端预编译快 6.7 倍
  • MySQL 8.0.43: 服务器端预编译快 4.0 倍

5.2 可能原因分析

  1. MySQL 版本差异

    • 原始问题发现于 MySQL 5.7.29
    • 本次测试使用 MySQL 5.7.44 和 8.0.43
    • 问题可能已在 5.7.29 之后的版本中被修复
  2. AWS RDS 优化

    • AWS RDS 可能包含特定的性能优化
    • 与原生 MySQL 行为可能存在差异
  3. JDBC 驱动版本

    • 测试使用 mysql-connector-j-8.0.33
    • 驱动可能已优化参数处理逻辑

5.3 建议

  1. 如需重现原始问题

    • 使用 MySQL 5.7.29 或更早版本
    • 使用原生 MySQL 而非 AWS RDS
  2. 生产环境建议

    • 在较新版本的 MySQL 上,useServerPrepStmts=true 性能更优
    • 建议进行实际业务场景的性能测试
    • 对于大量参数的 IN 查询,考虑使用分批查询或临时表方案

6. 附录

6.1 测试日志

MySQL 8.0.43 完整输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
=== MySQL PreparedStatement性能对比测试 ===
连接信息: mysql-prepared-test.cfsoq6muu0jv.ap-southeast-1.rds.amazonaws.com:3306/test
参数数量: 50000
测试轮次: 3

测试配置: useServerPrepStmts=false
参数空格数: 128
SQL长度: 6500023 字符
执行第1次查询...
第1次: 571ms (返回0条记录)
执行第2次查询...
第2次: 317ms (返回0条记录)
执行第3次查询...
第3次: 314ms (返回0条记录)

=== useServerPrepStmts=false 测试结果 ===
总执行时间: 1202ms
平均执行时间: 400.7ms
返回记录数: 0
Com_stmt_prepare: 0 -> 0

测试配置: useServerPrepStmts=true
参数空格数: 128
SQL长度: 6500023 字符
执行第1次查询...
第1次: 138ms (返回0条记录)
执行第2次查询...
第2次: 92ms (返回0条记录)
执行第3次查询...
第3次: 73ms (返回0条记录)

=== useServerPrepStmts=true 测试结果 ===
总执行时间: 303ms
平均执行时间: 101.0ms
返回记录数: 0
Com_stmt_prepare: 0 -> 1

MySQL 5.7.44 完整输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
=== MySQL PreparedStatement性能对比测试 ===
连接信息: mysql57-prepared-test.cfsoq6muu0jv.ap-southeast-1.rds.amazonaws.com:3306/test
参数数量: 50000
测试轮次: 3

测试配置: useServerPrepStmts=false
参数空格数: 128
SQL长度: 6500023 字符
执行第1次查询...
第1次: 639ms (返回0条记录)
执行第2次查询...
第2次: 681ms (返回0条记录)
执行第3次查询...
第3次: 480ms (返回0条记录)

=== useServerPrepStmts=false 测试结果 ===
总执行时间: 1800ms
平均执行时间: 600.0ms
返回记录数: 0
Com_stmt_prepare: 0 -> 0

测试配置: useServerPrepStmts=true
参数空格数: 128
SQL长度: 6500023 字符
执行第1次查询...
第1次: 117ms (返回0条记录)
执行第2次查询...
第2次: 77ms (返回0条记录)
执行第3次查询...
第3次: 76ms (返回0条记录)

=== useServerPrepStmts=true 测试结果 ===
总执行时间: 270ms
平均执行时间: 90.0ms
返回记录数: 0
Com_stmt_prepare: 0 -> 1

6.2 参考资料


报告生成时间: 2026-01-12
测试执行者: Kiro CLI
AWS Account: 872515255872

对姚顺宇的4小时访谈整理

节目来源:张小珺|商业访谈录 第 140 期
YouTube:https://www.youtube.com/watch?v=ttkd0t5qTD4
录制时间:2026 年 3 月
发布时间:2026 年 5 月 11 日

整理说明:本文基于 YouTube 自动字幕整理,原字幕经历了”中文语音 → 英文 AI 翻译 → 中文再翻译”的双重转译,口语化表达、术语、人名错漏较多。本文结合嘉宾公开背景资料(清华物理系本科、斯坦福理论物理博士、Anthropic 与 Google DeepMind 研究员)对关键错误做了校正,并在必要处补充背景注释。尽量忠于嘉宾原话和语气,包括其中的”小疯”言论、吐槽和批评。


关于嘉宾身份的重要澄清

硅谷 AI 圈有两位清华同届毕业、英文都叫 Shunyu Yao 的研究者,中文媒体常混淆:

姚顺雨(另一位) 姚顺宇(本期嘉宾)
本科 清华姚班(计算机) 清华物理系(基科班/学堂物理班)
博士 Princeton(NLP) Stanford(理论物理)
代表作 ReAct、Tree of Thoughts、《AI 下半场》 Non-Hermitian Skin Effect(非厄米趋肤效应)、Scramblon 理论
路径 OpenAI → 腾讯首席 AI 科学家(2025) Anthropic → Google DeepMind(2025)

本期嘉宾姚顺宇的公开履历校核:

  • 2015–2019 清华物理系本科,特等奖学金 + 叶企孙物理奖
  • 本科期间 3 篇顶刊(2 篇 PRL + 1 篇 PRB),第一作者与清华王中合作提出 非厄米系统拓扑能带理论新方法
  • 2019–2024 斯坦福大学理论与数学物理博士,导师 Douglas StanfordStephen Shenker,研究量子场论与量子引力动力学
  • 短暂加入伯克利做博士后(正式两周,节目中他说实际待了两三个月)
  • 2024 年 10 月 加入 Anthropic,从事强化学习方向,参与 Claude 3.7、4、4.5 的训练
  • 2025 年 9 月 19 日 从 Anthropic 离职,9 月 29 日 加入 Google DeepMind,Senior Staff Research Scientist
  • 参与 Gemini 3、Gemini 3 Deep Think、Gemini 3.1 Pro 的开发

字幕中所有”顺宇”与”舜宇”、”Anthropic”被译为”人类学/人本主义/人形生物/人为因素/人猿科技/安特罗皮克”等均为同一指代;”双子座/双子星”即 Gemini。


一、两个 Shunyu Yao(01:26)

姚顺宇主动介绍另一位姚顺雨:”我们的主要职业发展道路有一些重叠,所以看起来可能很难把我们区分开来。”他强调两人最大区别是:另一位从一开始就做计算机科学,而自己是物理出身,只是”某种意义上走到了这一步”

两人清华本科同届(姚顺雨在姚班,他在基科班),研究生一个去了 Princeton,一个去了 Stanford——“很奇怪,全世界都觉得 Stanford 是 CS 圣地,Princeton 才是物理圣地,我们俩恰好反着来。”

  • 两人在硅谷时每几周见一次,主要就是”瞎玩”——散步、吃饭、打扑克。
  • 对于另一位姚顺雨提出的 “AI 进入下半场”,姚顺宇坦言:”我一直不太懂上半场、下半场什么意思,这个定义我始终没搞清。”
  • 他自己的阶段定义是:“大家开始不再那么担心一件事,AI 能不能做到这个问题本身是不是定义明确,这是最大的变化。” 一年前 Anthropic 内部还担心追不上 OpenAI 的推理能力;现在 Gemini、OpenAI、Anthropic 三家没谁真担心”赶不上进度”了——难的是想清楚到底该做什么
  • 模型同质化、商品化了,纸面(benchmark)上差距缩到 1–2 个百分点,“大部分是噪声,不是信号”,真正的差异只在实际用户体验里:Claude 工具使用最强,Codex 最近追平,Gemini 日常推理更好、智能体编码还在追赶。

二、竞争与逃逸(07:15)

关于 OpenClaw(字幕原文,疑为某款 2026 年初爆火的智能体 Wrapper 产品)的产品判断

  • “圈内人其实不紧张。圈外比圈内紧张。”他认为 OpenClaw 没有证明什么新东西——Claude 4.5 Opus 发布时,工具使用能力已经领先 OpenAI 和 Gemini 3,只是当时没人包装成产品。
  • Manus 被 Meta 收购(注:节目录制后该收购已被撤销)、OpenClaw 被 OpenAI 收购,这说明”包装层”目前还无法摆脱模型公司的控制——“逃逸速度不够”
  • Wrapper 要活下来只有两条路:
    1. “成长够快”(Cursor 的打法)——在模型公司反应过来前占据足够用户心智,并训练自己的模型。他说 Cursor 现在跟 Anthropic 的关系”已经到了非常微妙的阶段”,Cursor 在训自己的 Composer,双方从亲密伙伴变成竞争对手。
    2. “市场小到模型公司看不上”(Midjourney 的打法)——“有损 Gemini 尊严的”那种细分市场。
  • 被问到 Lovart 是否算:”我觉得他们有机会。”
  • 对 2026 年的预测:模型应当实现 “训练时有限上下文,使用时无限上下文”(train with finite context, use with infinite context)——模型边和你持续交互边判断、丢弃不重要信息,成为真正的私人助理。今年肯定能做到,但有多条技术路径,还要实验验证。
  • 关于 Meta 收购 Manus:他”没完全想明白”,猜测最大好处是拿到一个强大的亚洲产品团队,”中国在产品端比美国更有天赋”;但 Meta 为什么自己做不出这种产品?他也没想清楚。

三、”Pre-train 没有到头”(25:22)

这是他最反主流的判断之一。

  • “2026 年第一季度,模型改进速度完全没有放缓。”
  • 他拒绝用 benchmark 增长来衡量:”benchmark 是定义在 [0, 100] 里的,越接近 100 增长当然越慢,但这不代表用户感受到的增长在慢。从 70% 到 75% 的价值可能比从 50% 到 60% 还大。”
  • 他的判断基于研究者的体感:模型越来越容易学——过去要花很大力气教会模型一件事,现在只要问题定义清楚 + 数据/环境构建对,模型几乎”自动就会”。
  • 预训练(pre-training)过去几个月一直在变强。”几个月前很多人说 Scaling Law 撞墙了,我的经验是没撞墙,接下来四个月也看不到到头的迹象。”
  • 为什么有人觉得撞墙了?他给出三种可能,并直指第三条最常见:
    1. 觉得这个范式本身到头了(可能但只是猜测)
    2. 觉得数据等条件不再满足
    3. “他们自己的工作里有 bug,但没意识到——我观察到绝大多数’撞墙’的人属于这一类。” 修一个 bug 带来的进步,往往比花哨的技巧多得多。
  • 遇到撞墙应该是心态问题:相信问题可解,就会系统性地做消融实验排查——“Gemini 和 Anthropic 在这件事上都做得很好。”
  • 当前主驱动:数据和算力(二者强相关)。算法更像阶段性跃迁(如 Transformer),之后是渐进提效。
  • “在相对清晰的范式(pre-train / post-train)内,主驱动是数据和算力。多模态生成算法还没收敛,仍是科学问题;但自然语言生成已经不是科学问题,只剩工程问题。”
  • “如果我估一个时间线,接下来四个月还会有进步。但 AI 领域谁也没法预测四个月以后。”
  • 谁在兴奋?”做产品的人兴奋于 OpenClaw,做模型的人兴奋于模型进展。Anthropic 和 Gemini 里的人更多在想:AI 很快会把我们取代,我们接下来该干嘛——而不是担心撞墙。”

四、Coding 的爆发(35:08)

为什么编程领域这一年半发展最快?他认为有两大结构性优势:

  1. 奖励信号(reward signal)定义清晰:SWE 任务天然可测,输入输出一匹配就是成功。
  2. 数据基座天然存在:GitHub 几十年沉淀了海量高质量代码,构建环境非常方便。

从产品角度,编码还有一个独特性:好程序员写的代码风格高度相似(简洁、结构清晰、易扩展、抽象合理),所以不需要像社交/游戏那种推荐算法去适应每个用户的口味——这大大简化了产品形态。

  • 他自己的代码产出中 90% 以上由模型生成(保守估计,实际可能 99%);但他花大量时间审 review 代码。”AI 辅助之后,最重要的变成了如何设计它、如何给它合适的 context。”
  • 被问谷歌允不允许用 Claude Code:”你这个问题差点让我丢工作了——谷歌不允许用 Claude Code。”(笑)
  • 工作效率提升 20–50 倍(相比一年半前),但他的工作时间反而更长:”因为能试的想法更多了,以前要等同事几小时才能搞懂一个文件,现在问 Claude 或 Gemini 5 秒就行。”
  • 对谷歌文化的吐槽:“谷歌已经不是那个沿岸划船(coast along)的谷歌了。GenAI 里没人摸鱼,除非你对技术彻底失去兴趣。” 他自己每天 9 点起查邮件和夜间实验,10 点到办公室,单身时干到 10–11 点,妻子在也会带回家干。
  • 下一个 Coding 级别的爆发点?“如果我看得清,我早就去创业了。”(笑)除了编程,其他方向市场都不够大——AIGC 市场受限于”人一天只有 24 小时”;最可能的大市场候选是交互式教育,但也远小于编程。
  • 关于程序员的未来:AI 最终会取代程序员,但是渐进过程;“AI 是高度集中化的技术,让少数人更强,让大多数人失去独特价值”;传统软件工程的终局可能是**”千分之一的人做完所有人的活,拿 100 倍的工资”**。”千分之一只是个比喻数字,也可能是万分之一或十万分之一……别太悲观,我是著名的悲观主义者。”
  • 活下来的那群程序员特征:技术强(充分不必要条件)+ 理解自己在大组织中的定位 + 规划能力强(能把复杂事切成小块分发给不同 AI)。
  • AI 研究本身是淘金热还是科学革命?“都有”。他说训练 AI 产品经理目前不太可能——因为”什么是好产品”没有客观标准,反馈信号太模糊

五、Seedance(50:10)

对字节跳动 Seedance(字节系视频生成模型)的评价:

  • “可能会让 DeepMind 多模态团队有压力,但不是范式级的变化。字节在多模态生成上一直相对强,主要是数据和细节做得好。”
  • 猜测原因是数据,因为多模态算法层面还没根本创新;但他”没在字节工作过,只能瞎猜”。
  • 评价从谷歌跳去字节的吴永辉:”偷偷看过他过去的代码提交和领导项目,他是我见过极少数资深但技术能力还特别强的人之一,我还不到评价他的水平。”
  • 中美模型差距:过去一年半明显在缩小,但是否会完全消失甚至反超,”是个悬而未决的问题”。
  • “中国在实际算力上处于明显劣势,但这个劣势反而催生了一些有趣的东西——中国模型公司非常擅长从其他模型蒸馏。”

六、”硬蒸”和”软蒸”(54:30)

回应 Dario Amodei 最近公开指控三家中国公司蒸馏他们模型:

  • “蒸馏本身是公开的秘密。”
  • 他把蒸馏分为两种:
    • “硬蒸”(brute-force distillation):直接拿 Claude 生成的 token 去强制训练自己的模型。“商业上不道德,智商上相当蠢——等于承认你连自己要做什么都不知道,只能模仿别人,把 benchmark 数字做得好看些。”
    • “软蒸”(smart distillation):在自己的数据 pipeline 里用其他模型做助手,或者用其他模型当 evaluator。“商业上灰色,但技术上其实很有意思——中国实验室可能是 multi-agent 训练领域的先驱:如果他们把多个不同公司、语言分布差异巨大的模型整合进统一训练系统,这才是真正的 multi-agent。”
  • 点名(后期应消音处理):硬蒸某家”之前可能做过,后来逐渐转软蒸”;“蒸得最少的是字节跳动,它的模型仍然非常独特。”
  • 关于豆包:
    • “豆包肯定不如 Gemini 或 Claude 聪明。但豆包的语音生成真的是世界最好的(直白说就是最好,委婉点说是之一)。”
    • 美国公司为什么不做这种方向?“数据问题 + 用户群差异。美国人更关注生产力,中国人才有那么多’人生问题’要问’豆包’。我自己生活很无聊,没什么有趣的人生问题——日常技术问题问 Gemini 就好。”(笑)
    • 豆包手机:”想法很好,但我不知道技术实现上开销多大——不能你让模型帮你订张高铁票,最后花的钱比票本身还贵,那是不能接受的。
    • 苹果 AI 策略:”表面看上去不在乎,其实太在乎了,只是如果太在乎又做不成,就显得自己太蠢。面子问题。

七、机器人(1:04:07)

  • 春晚看过演出,还去亚马逊搜过人形机器人价格,”比我想的便宜多了”,反映了中国硬件产业链的优势
  • 但软件侧:”机器人模型还处在特征工程时代——给定场景,针对这个场景做 RL 优化,每个人都知道怎么做,但泛化能力不强。”
  • “是否具备泛化能力,实际上是 AI 很多方向的分水岭。” 确定性单一场景做好不难,十几年前就能做到;语言模型是在 Transformer / GPT 之后才越过这个阈值——“在一个层面训练就能全面提升所有能力”。机器人还远没到。
  • 参观过 Google DeepMind 自己的机器人实验室和 Physical Intelligence:”实验室比语言模型实验室有趣多了——语言模型实验室就像普通办公室,机器人实验室真的是人工遥控机器人去各种货架取东西。”
  • 机器人目前连 GPT-1 阶段都没到,和多模态生成一样,都还没找到 scale 的办法

八、在 Underdog 之地赌一把(1:08:45)——成长经历

出生在宁夏大武口(一座因煤矿而生的城市),小学到高中在上海。性格自述:”我总是喜欢做我不擅长的事情。

关键人生选择——高中择校:他本可以被上海四大名校(上中、华二、交大附中、复旦附中)的普通班录取,但为了进**”稍差一些”的格致中学的竞赛班而放弃——“赤脚的不怕穿鞋的,值得一试。”**

参加物理竞赛未能进国家集训队(没拿到保送),后来高考也考不上清华。但命运转折:高三清华夏令营期间,听说清华对北京学生有独立招生,他当场给清华招生办老师发短信——“你给北京学生考试,凭什么不让上海学生也考?”——争取到考试机会,考过后签了”第一档降分”协议,最终录取清华。

人生最大的经验:“大胆一些。如果你不争取,就永远得不到。即使你争取,也未必能得到。但如果你不争取,就肯定得不到。”

对父母的评价:”中国家长能做到让孩子’讨论’已经不错了,我一般只是通知他们。我父母最好的地方是,当他们无法理解我在做什么时,他们选择不干涉。”

性格:”在意自己想做的事,别试图阻止我,我会竭尽全力;但我不想做的事,你逼也没用。”、”我更多是和自己竞争,不太愿意和别人竞争——当然如果你也很在乎,那我一定要比你厉害。”


九、非厄米系统与量子物理(1:19:44)

选择凝聚态理论”就是命运的安排”。清华基科班传统是”学生可以做物理以外的事,鼓励早进实验室做研究”——“基科班三分之二的学生最后都不做物理。”

本科导师是王中(Zhong Wang)(字幕写作”王忠”),当时还很年轻、学生不多。王中的博士导师是 张首晟(Shoucheng Zhang)(字幕写作”张守成/寿城”,斯坦福著名凝聚态物理学家,2018 年去世)。”王老师话不多,但很擅长把问题看清楚。”

非厄米系统工作的通俗讲解(他自己给出的进度条提示:不想听可以跳过):

  • 量子力学的基本假设:孤立系统演化由 Hamiltonian(厄米算符)描述。
  • 现实中绝大多数不是孤立系统(和环境交换粒子/能量),对应的 Hamiltonian 是非厄米的
  • 他们最初研究开放量子系统的拓扑现象时,发现解析计算(周期性边界条件)与数值计算(开放边界条件)的结果完全对不上
  • 后来发现:厄米系统的基本范式——布洛赫波假设——在非厄米系统里完全崩溃。非厄米系统的能量本征态全部会堆积在系统边界(即后来广为人知的 Non-Hermitian Skin Effect,非厄米趋肤效应)。
  • 他们建立了一整套描述开放边界非厄米系统本征态和动力学的框架——这是**范式级(paradigm shift)**的工作。

为什么没继续做下去?

  • “范式转变很难 catch,已经 catch 了一次就不想再 catch 同一次。”
  • “这是人性的弱点——我总想挑战自己不知道的事。”
  • 现在回头看,”如果当时继续做下去,那工作会成为这个方向上最重要的工作,我会更有名、更多引用、更好的教职;但科研生涯会变得不那么兴奋。”
  • 所以博士阶段转去搞理论高能物理(量子场论与量子引力),这两个方向”几乎没有任何联系”。

对”挑战难事”的反思:“说得好听点是挑战自己,说得难听点就是自虐。”、”如果一个人只为受虐而受虐,那是心理问题;但如果是为了获得信息、丰富经验和能力,那值得。”

本科学物理最大的收获:“把事情想清楚、做深度阅读、不要过分相信纯理论。”——因为非厄米那个发现本身就源于”数值计算和理论不符,深入追查才找到问题”。


十、高能物理(1:36:27)

承认博士阶段”对世界没有贡献“:

  • “高能物理已经发展到实验完全跟不上理论的程度。” 没有客观评判标准,靠”领域里几位老前辈的主观判断”。
  • “人的一生并不长,何必浪费时间为老年人服务。”
  • 五年博士学到的最重要一课:“做事情要有相对客观的评价标准”,或者说 “做对世界有影响的事”
  • 自我评价:”说实话,我的博士论文没人会说不好,但对世界的影响几乎没有。我个人非常不满意,但也没糟糕到让别人说我偷懒的程度——你可以满足所有外部期望,但自己骗不了自己。”
  • 满足小圈子标准 = 训练一个模型:“一旦进了那个小圈子,你知道评价标准是什么,做好很容易,即使你不认同这些标准。”
  • 博士后两三个月实际在伯克利(正式记录只有两周)后离职,伯克利老师很好:”我告诉他们我可能要去做 AI,他们说不急,先把现有工作保住再说。”

十一、物理与 AI(1:43:09)

物理学家做 AI 的优势

  • 硬技能上帮助其实很少。
  • 真正的帮助在性格/品味:探究本质、做事系统化(无论实验还是理论方法论)。
  • “这不是物理独有——CS、化学、生物背景的人也有这种特质。”
  • Anthropic 特别多物理出身的人,”主要是联系(connection)——联合创始人里两个技术一把手都是物理背景,于是就招了这类人。但到我加入时,这个惯性已经结束了。”

关于 AI 是不是黑箱

  • “一切都是黑箱,连物理也是。” 我们也不知道最微观层面的动力学。
  • 语言模型还没到”神经外科级别”的理解(除了 Anthropic 的 Interpretability 团队在极小网络上能做)。
  • 但 Scaling Law 已经是经验定律——“经验定律和科学定律的界限是模糊的。热力学定律最初也是经验定律,后来有了微观机制的理解才变成科学定律。未来 Scaling Law 可能也会这么演化。”
  • “智能涌现”这个词本身不科学——“对我来说,这更多是主观感受。真正的质变只有一个:技术上能 scale 起来,全面提升所有能力。这是我对’涌现’的唯一定义。”

为什么最终选 AI 而不是量子计算?

  • 两者都给年轻人机会,但量子计算瓶颈在实验平台——“那是我不擅长的,和我兴趣无关的东西很多”。
  • AI 更像 “17 世纪做热力学”——那时候人们甚至还不知道”热”是什么(还相信燃素说),但这并不妨碍做实验、总结出第一定律、第二定律、Clapeyron 方程等经验定律,最终推动热机发明改变世界。
  • “理论物理到实验物理的距离,比理论物理到 AI 还要远。AI 对我来说就是数值实验——有想法,设计实验验证,本质和做物理数值计算没区别。”
  • 对实验物理的敬畏:”大家都知道怎么搭光学平台,有人能搭出来,有人六年搭不出来——这种动手能力我不理解,感觉相当神秘。”

十二、在 Anthropic 训练 Claude 3.7 和 4.5(1:52:32)

入职经过

  • 2024 年 8–9 月,通过前同事联系上 Anthropic(第一个 manager 也是理论物理背景)。
  • 同期也联系了 OpenAI 和 DeepMind——“DeepMind 当时太慢了,最后是 Anthropic 谈成。” OpenAI 没找到合适位置。
  • 面试前把能自学的课程都过了一遍,手写实现了 Andrej Karpathy 的 nanoGPT。
  • 有两个团队接洽他(评估 vs 强化学习),他选了更不确定的 RL 方向

当时 Anthropic 的状态

  • 全公司 700–800 人,他加入的 “Horizon” 大团队只有 10–11 人,几乎就是整个后来的 RL 团队前身。
  • 对 Anthropic 的第一印象:”执行力非常强,相对自上而下的公司;人与人之间没有隐瞒,氛围非常好——因为规模小大家都认识。”
  • Anthropic 为什么能自上而下? 因为技术决策人就是公司联合创始人(Jared Kaplan 和 Sam McCandlish),而且 Dario 与他们互信足够。”其他公司做不到——Ilya 在的时候 OpenAI 或许能,但他后来莫名其妙丧失了决策权,然后就走了。”
  • 他与 Jared Kaplan 合作最多。
  • Anthropic 联合创始人团队 “没有一个离开过”,”他们是真正并肩战斗过的一群人——Scaling Law 论文、GPT-3 论文都是联名作者(Jared、Sam、Dario、Tom Brown、Benjamin Mann 等)。”——这是很多公司做不到的互信基础。

Claude 3.5 → 3.6 → 3.7

  • “Claude 3.5new 被外界叫 3.6,是因为 Anthropic 早期没产品能力——两个模型都叫一个名字(3.5),后来自己被迫接受外部给的 3.6 叫法。所以实际产品线是 3.5 → 3.5new(=3.6)→ 3.7。”
  • Claude 3 发布后 Twitter 上就有人发现它编码比 GPT-4 强;“这是 Anthropic 押注编程的一个信号来源,但最初可能是随机试出来的——纯粹技术原因,先自下而上冒出来,后来自上而下 all-in。”
  • 3.7 是 Anthropic 后训练(post-training)的分水岭:之前 post-training 是”打补丁”模式;3.7 之后才真正大规模 RL。
  • “在我加入时,大家已经知道要做大规模 RL,但不知道具体怎么做。” 2024 年 8–9 月,o1 还没发布,只知道 OpenAI 有个神秘项目叫 Strawberry。
  • 真正的秘诀(他能公开谈的部分):“把简单的事做得比所有人都干净。” RL 最简单的算法是 policy gradient,有很多复杂的算法但会带来 infra 难题;如何 trade-off 这些 detail 才是真正的 expertise
  • 他的一个重要观察:“很多 trick 其实没用。” 不同公司 sampler 和 trainer 的 numerical 差异依赖各自 infra,所以”你照抄别人的算法不一定有用——算法是整个系统的一部分”。”这就是我为什么不爱回答别人问 Anthropic / Gemini 怎么做——回答会误导他们。”

3.7 → 4.5

  • 他离开时 Anthropic 已经接近 2000 人(比他加入时翻倍以上)。
  • “我赶上了小公司的尾声”——三四个月后公司突然变大,文化开始混乱,”有些从外面进来的人带来和原文化的冲突”。
  • 他不喜欢的人“我觉得 ‘ideas are cheap’。真正难的是 implementation。我不喜欢那种每天大部分时间泡在 Slack 里谈 grand principles 的人——没什么用。”(笑)

离职原因

  • 主因:想学不一样的东西。”Anthropic 非常聚焦,只做语言模型相关,不做多模态生成、不太做底层工程和 infra——我想学这些。”
  • 约 40% 原因:不认同 Dario 的反华立场。”作为 CEO 个人他怎么想都可以,但把这种观点推到如此极端,是非常情绪化的反应。”
  • 40% 不是主因,但也不是无关紧要,更不是**”控股股东的原因”**。(笑)
  • 对 Anthropic 未来的看法(离开时):悲观——“API 卖 token 是门烂生意,价格战会来,只有谷歌能赢(供应链优势)。”但后来证明他太悲观了,Anthropic 在产品层面做得非常好(Claude Code、Cowork 等)。
  • 被问会不会后悔:”不太会。我的动机是换位置学东西。”
  • Claude Code 的诞生:“那几乎是当代少有的、还展现个人英雄主义的时刻。” 创始人 Boris Cherny(字幕译为”鲍里斯·切尔尼”)本来只是想给自己和同事提效,最后变成了整个产品。”很可能是和抖音同级别的交互层面变革产品。”

关于”英雄主义已经过去了”

这是贯穿访谈的核心观点之一:

“个人英雄主义在语言模型领域可能已经过去了——也就是 Transformer 那个时刻之后。”

“现在大家都是冲浪的人,本质上是那个浪,而不是你那个冲浪的人。”

“没有英雄,有时候甚至觉得旧时代的英雄有点蠢。”

“我对任何模型的贡献,我的 statement 永远是:我自己对那件事没那么重要;更多是我很幸运,有机会在那时候加入了一个重要项目,做了一些事。”

他特别指出:编程上 Anthropic 的成功确实还有”公司级英雄主义”(敢不敢赌、赌得够不够快),但模型内部的每个技术细节都是集体的。

对 AI Safety 的批评(非常犀利):

  • Anthropic 成立的初衷是 AI safety,但又要训练前沿模型——Anthropic 自己的解释是”必须做最强的模型才有话语权推动 safety 议程”。
  • **”这个想法非常天真——**现在看来这不可能发生。更可能的结果是所有人都有强大前沿模型,没人能阻止任何事。”
  • 真正的机制类比是 核武器多方持有、互相威慑——“靠一家公司自我立法去规制是不可控的——它只能自我规制,但自我规制等于没规制。”
  • 对 Anthropic 可解释性团队:只在非常稀疏、小的网络上有有趣进展,实用语言模型层面还没达到”神经外科级别”。

十三、”AI 本质是简单的”(2:35:03)

核心命题“AI 本质是简单的。”(他强调这是 statement 不是 conclusion)

解释:

  • 因为你可以做实验。相比物理(能量尺度限制了实验数据),AI 不受这种约束——想做什么实验都能做,只是需要时间扩算力、准备 infra,但没有根本性困难。
  • “AI 不会给人撞墙的感觉,不是因为方法穷尽了,而是因为想法太多了,挨个试不过来。”
  • 未来 6–12 个月 AI 会开始自己做实验——不是只写代码,而是运行实验 → 分析结果 → 提出新假设 → 设计新代码 → 跑新实验,这条链会逐渐闭合。

十四、在 Google DeepMind 训练 Gemini 3(2:41:10)

加入 DeepMind 的理由

  • 反对那种”研究员离开大厂加入小厂”的惯性——他反其道而行,因为他当时想要”学更多、更广”
  • “如果你真想把某个想法塞进最终产品模型里,谷歌可能是非常烂的地方;但如果你要的是研究自由、广阔视野,世界上找不到比 Gemini 更强的第二名。”
  • 加入时点(2025 年 9 月底)已经看好 Gemini——Gemini 2.5 那代让业内意识到”Google 正在搞明白”。
  • 他是因为个人联系被挖进去的,双向选择。
  • 为什么没去 OpenAI?“文化让我非常担心。直白说,真正能把事做成的人没 Gemini 那么多,甚至比 Anthropic 还少。”(笑)内部政治斗争也开始显现。
  • xAI:“我不理解。”(笑)”接触过的人后来都走了,我也不知道他们现在怎么样。”

Gemini 3 的转折点

  • Gemini 3 和 Nano Banana 两次叠加才是真正的转折点:Nano Banana 把很多新用户引到 Gemini App,Gemini 3 把他们留住。”只有 Gemini 3 不够——市场份额低于 10% 时,模型再好传播也慢。”
  • Gemini 当前市场份额可能在 20% 左右(他还没精确核查)。
  • “从局外人角度看,是 OpenAI 救了谷歌的命。” 如果 ChatGPT 当时真的完全吞掉了搜索,谷歌就完蛋了;但 OpenAI 做到了”让谷歌意识到重要性,但没做到吞掉搜索”,让谷歌得以反扑。
  • Chatbot 为什么没完全吞掉搜索?
    1. 搜索有大量”非常蠢”的需求——“我就搜一下在哪买米、哪里点好,不想等聊天机器人转半天最后给个链接还要再点一次。”
    2. Chatbot 形态还没达到终点。
  • “聊天机器人凭什么就是终极形态?过了这么多年,居然还只有一个聊天框,我真的觉得很蠢。”——“需要一个产品经理来解锁模型的全部能力。”(笑)

谷歌内部发生了什么

  • 外部看到模型性能大跳;内部是组织逻辑开始清晰
    • 预训练阶段已经有清晰框架——谁负责哪个 node 非常明确(以前非常混乱)。
    • 谷歌工程管理能力极强,预训练已经进入”谷歌的舒适区”,能可控地知道下一代不会坏,甚至能预估好到什么程度
  • Anthropic 走自上而下;谷歌仍然相对自下而上,但比过去更偏自上而下。
  • “不同文化都能 work”——大公司和创业公司的打法本质不同。
  • 谷歌的杀手锏:“找到一个极简的产品表达形式,所有人看起来都一样,然后在技术层面无情地碾压你,你根本竞争不过。” 搜索就是典型例子。
  • OpenAI 的位置:“现在没人的位置是稳固的。” Chatbot 是否是 super app 的终极形态?—“我完全没有理性答案,但感觉事情还没结束。”
  • 对国内”超级应用”叙事的吐槽:“我真的不懂——大家在抢一个 super app,前提是 chatbot 就是 super app 的形态。但我真的觉得 chatbot 很蠢,终极形态凭什么非是这个?”

谷歌的”英雄”

  • 后台的英雄:Sergey Brin(”重大决定最终还得他拍板”)。
  • 前线的英雄:Koray Kavukcuoglu(Google DeepMind CTO / 谷歌高级副总裁)。
  • Demis Hassabis 更偏科学方向(Isomorphic Labs 等),Gemini 日常他见到最多的是 Koray。

十五、技术预测和组织搭建(3:01:28)

预训练 vs 后训练

  • 纯技术上两者本质区别不大——最大区别在数据分布:预训练要 广(不需要 quality 特别高);后训练要 窄而精(quality 要求极高)。
  • 不同实验室组织方式:
    • Anthropic / Gemini:pre-train 和 post-train 分两支队伍。
    • OpenAI:更混乱——最早三队(pre-train、RL “Strawberry”、post-train),而且他们的 post-train 本身就是产品团队,”训模型的人也参与产品”。

对”下一个范式转变”的判断

  • 大概率不是范式级变化,但对谷歌特别有价值的两件事:
    1. 机器学习编码(ML coding):让 AI 能加速 AI 自身的研究闭环——谷歌是 AI 研究最完整平台(硬件 + 连接 + 模型),这件事对谷歌价值巨大。
    2. 长远规划 / 长时程(long horizon):每个人都觉得重要。
  • 对实现方向:
    • 预训练侧:sparse attention(稀疏注意力,DeepSeek 和学术界都在做)。
    • 后训练侧:类似 Cursor 那种外部上下文管理(让模型选择保留或扔掉哪部分)。
    • 两者本质相同——上下文 token 的 KV cache 也是一种权重。
  • “**一万个人有一万种’世界模型’**的定义。Gemini 的世界模型更像端到端训练(条件生成下一刻场景);李飞飞那种是另一回事——我不太懂她们实验室在做什么。”
  • Continual learning(持续学习)和 long horizon 本质没区别。
  • 主要精力在后训练方法(预训练不做正式工作)。
  • “Gemini 在 long context 上的一些技巧真的让我惊讶。”(笑)

AI 人才稀缺性质疑

  • 高薪是因为大家觉得稀缺,但**”可能没那么稀缺——训练一个人不难,只是你需要遇到做这件事的环境。过去有这种机会的人不多,所以市场上相对稀缺。另一方面,可能对某些人的吹捧也过头了,大家特别爱神话某些人。”**

他设计的面试题(可公开)

  • 要求候选人 24 小时从零做一个 RL 项目——自己选模型、数据、算法,然后和他讨论一小时。
  • 两个目的:
    1. 看候选人与 AI 合作的能力(现在写代码本身不再稀缺)——有个陷阱:如果完全把活丢给 AI 自己不理解,讨论一小时就暴露了
    2. 24 小时限制是看他重不重视这个机会——能不能熬夜。不重视的人连这 24 小时都熬不住。“(笑)”这里面还有些阴暗的小巧思。”

工程 vs 科学

  • “谷歌的预训练现在已经变成工程项目——自上而下、节点清晰、可评估。这是谷歌的强项。”
  • 后训练不确定性更大,仍是自下而上、每个人尝试不同方法。

组织的核心原则

  • “系统稳固 + 个人英雄不闪耀”“允许个人英雄闪耀但系统脆弱” 的 trade-off。
  • 他倾向前者——“系统不稳固的一个例子就是 OpenAI:一个人走,整个结构就可能塌。”
  • 对自己的要求:“研究员必须为整体考虑,不然不是好研究员。在学术界是’一人吃饱全家不愁’;在公司里你要对公司负责——这是两种完全不同的心态。”
  • 他承认:”我可能就是拉不下脸——既然签了合约,我觉得不按合约做没什么道理。”

TPU vs GPU

  • 大规模商业部署上没有优劣差异。开源生态 GPU 更好,但这对大规模部署不是瓶颈。
  • 设计理念不同:
    • GPU(尤其 Hopper 一代):单 pod 内 NVLink 带宽极高,但 pod 内卡少(8 张)。
    • TPU:放弃卡间两两互联,用 3D Torus 拓扑把更多卡组成一个大 rack,每张卡只与 3 个最近邻相连。如果编译器/分片写得好,总内存容量更大、通信瓶颈更少
  • TPU 缺点:小规模用不灵活、通用性差

对 xAI 的评价

简短、尖锐:“我不理解。他们一直都挺动荡的。”(笑)


十六、集体主义胜利(3:23:33)

对新实验室潮的吐槽

  • 最近硅谷一堆新 AI 实验室:”绝大多数新实验室会倒闭。
  • Thinking Machines 还在持续出新东西;但某些新实验室(后期消音)——“我完全不知道他们想干嘛,创始人其实已经离开赛场很久了。”

中美路线分化

  • 中美已分道扬镳。中国优势在消费侧
    • “中国能想出非常复杂、看起来很不自然的产品结构,让利润滚雪球——抖音你看视频不收 0.2 美元,但偷偷加广告、直播、电商。”
    • 美国这种玩法玩不转——“生产力软件:我帮你写代码,150 成本,200 卖给你,我赚 50,就这么简单。”
  • “Meta 就应该直接抄字节跳动——它又找不到自己的定位,做消费产品的能力又远不如字节。但美国过去十年有个正反馈循环:B2B 太容易赚钱,大家都不想烧脑研究如何赚消费端的钱。”

AI 人工神话

  • “我进这个行业的时候,个人英雄主义时代已经过去了——所以没有英雄。”
  • “没有哪个老登是你的亲戚——所以你觉得他傻,他就是傻,可以直接说他傻,无所谓。”(笑)
  • 为什么敢这么讲?
    1. “我在这个行业没有什么导师,没有什么旧友,我当然想喷谁就喷谁。”
    2. “这个领域足够客观——你在这个领域做得怎么样是有客观评价标准的,最终大家会尊重你。只要你观点自洽、不是乱喷,不用太担心因为观点得罪谁。”
  • 为什么来 AI:“AI 这个事本来也不太需要脑子,真的不太需要脑子。这个行业最重要的特质就是靠谱、做事细、对自己做的事情负责任。” 在物理里,他见过比自己聪明得多的人(比如他的博士导师 Douglas Stanford)——“他在那里,哪还需要我?”
  • 对旧时代 AI”英雄”的评价(点名后期消音,但线索明显):
    • XXX(某位以模糊表述见长的人)“我觉得他一直都挺蠢的”——“用 Pauli 的话说,他甚至不能算错,因为他说的东西都没有明确定义——我最讨厌这种模糊的人,模糊的东西没有意义。
    • 他愿意承认的英雄:
      • Haldane(霍尔丹,凝聚态物理拓扑态的奠基人)——“他第一次提出 Haldane model 和分数量子霍尔相关的东西,离后来整个领域搞明白拓扑态还隔了几十年,但他当时就能感觉到这件事重要,一直推动。”
      • Geoffrey Hinton(字幕译为”杰弗里·辛顿”)——“在大家都觉得 AI 这条路不确定时,他一直朝这个方向。这或许是英雄级别的人物。”
      • Transformer 集体(Noam Shazeer、Ashish Vaswani、Niki Parmar 等)——“这可能是一个英雄集体。”
  • 对”老登”(中文网络对守旧老年男性的贬称)的态度:
    • “大多数老登其实挺好的——人老了会分成两种:一种是德高望重、不再挑刺、真正指导年轻人;另一种是根本不知道自己在说什么,还特别爱挑刺和对人指手画脚。变老不一定就是老登。
    • 他不是一开始就这么直接的——“学生时代比较克制,但后来发现克制对自己没好处,对别人也没好处。进 AI 之后变得更直接——没有任何东西会阻挡我,而且这个领域足够客观。”

给年轻人的建议

  • 纯语言模型方向:“蓝海已经不是蓝海了,我赶上了末班车。”
  • 但 AI 是非常大的领域——多模态生成、机器人、用 AI 解决实际科学问题(如量子控制)都还是蓝海。
  • “对足够年轻的人,做现在最热的事未必是对的;做没人做的事,可能是更好的选择。”

关于自己的未来

  • 不会在谷歌长留(”如此公开地表达这一点——我觉得可能不会。”)。
  • “我还是会去挑战自己,需要折磨自己,只是得先找到值得折磨自己的东西。”
  • 不太可能再跳大厂;也没想做 AI for Physics——“很多人已经在做,多我一个不多,少我一个不少。”
  • 当前首要任务:把 ML coding 和 long horizon 推到相对稳定的状态。

推荐

  • 改变人生的书:“说实话我没有。” 最近读的是 汤川秀树(Hideki Yukawa,1949 年诺贝尔物理学奖)自传《旅人》(Tabibito)——“能看到一位后来非常成功的科学家,年轻时真实的挣扎。”
  • 休闲读物:《来自新世界》(贵志佑介,日本小说)。
  • 最喜欢的地方:夏威夷(因为喜欢大海)。
  • 食物:寿司。
  • 他认为最有影响力的 AI 论文:
    • Seq2Seq
    • Scaling Law 论文(Jared Kaplan 等 OpenAI 那篇)——“虽然具体方法可能不完全对,但它是第一篇把这种系统性研究方法引入领域的论文,至关重要。”
  • MBTI?“不知道。”

最后一问:”关键的赌注是什么?”

“Long horizon.(长时程)”


补充:几个交叉验证与背景注释

  1. 离职 Anthropic 原因的对照:姚顺宇在个人博客(alfredyao.github.io)的说法与访谈一致——强调”不想让自己的经验被特定实验室局限,尤其现在核心研究很少发表论文”。访谈中他直接说出 约 40% 是反对 Dario 反华立场,这在其博客和 36kr、新智元等公开报道中也有交叉证据。
  2. 参与的模型的可靠性:36kr 报道证实他参与了 Claude 3.7(agentic coding)和 Claude 4 family(RL numerics);Gemini 3 Deep Think 的参与也有谷歌自家公告确认。
  3. 非厄米趋肤效应:访谈中他描述的”周期/开放边界结果完全对不上、本征态全部堆积在边界”正是 PRL 论文 Edge States and Topological Invariants of Non-Hermitian Systems(Yao & Wang 2018)的核心发现,与本人描述完全吻合——字幕里的”王忠”实为王中(Zhong Wang)张守成/寿城实为张首晟(Shoucheng Zhang)
  4. 博士导师:Douglas Stanford 和 Stephen Shenker 是 Stanford Institute for Theoretical Physics 的顶级高能/量子引力学家,访谈中他特别说 Douglas Stanford “比我聪明得多”——是真诚的敬畏。
  5. “Claude 3.6 其实是 3.5 new”:这点与 Anthropic 官方命名历史一致,外部社区确实因 Claude 3.5 出了两个版本而自发叫后者”3.6”。
  6. 节目录制时间(2026 年 3 月)与发布时间(2026 年 5 月)之间已发生:Meta 对 Manus 收购被撤销、Cursor 可能被 SpaceX 收购、xAI 并入 SpaceX——文中相关表述按录制时状态保留,访谈中嘉宾对 xAI 的吐槽(”一直挺动荡”)反而被事态坐实。

核心观点速览

维度 姚顺宇的判断
预训练 远没到头,过去几个月一直在变强;觉得撞墙多半是代码 bug 没找到
后训练 真正大规模化始于 Claude 3.7;关键在数据分布是窄而精
Coding 爆发源于奖励信号清晰 + GitHub 数据基座;已是 AI-native 唯一大规模成功场景
机器人/多模态生成 都还没到 GPT-1 阶段,还在特征工程时代
Chatbot 形态 蠢,远不是终极形态,需要产品经理解锁
Wrapper 生存 要么成长够快(Cursor),要么市场够小(Midjourney);否则都被收购
AI 安全 Anthropic 的”造最强模型才有话语权”太天真;真正的机制类比是核武器多方威慑
蒸馏 硬蒸可耻且蠢;软蒸是 multi-agent 训练的先驱,技术上有趣
组织 系统稳固 > 个人英雄闪耀;OpenAI 是反例
英雄主义 语言模型领域已经过去;现在都是冲浪者,本质是那个浪
AI 本质 简单——因为可以做实验,受限的只是算力和 infra,无根本困难
给年轻人 语言模型蓝海已过;做没人做的事
个人风格 直接、可以喷人、”老登不是你亲戚”、拒绝模糊表述

AWS 云计算:全球第一的光环下,藏着怎样的真相?

AWS 是全球云计算市场占有率第一的厂商,这一地位已持续十余年。但”第一”是否等于”最好”?当我们抛开品牌光环,从架构设计、工程实践、性能数据、价格四个维度进行实测和分析后,得出的结论可能会颠覆很多人的认知。

本文所有结论均基于一手测试数据和抓包分析,不做任何主观外推。


一、设计理念:高可用的代价,用户买单

1.1 强制跨可用区:每次写入都要跨机房

AWS 的 RDS MySQL 默认部署模式是 Multi-AZ(多可用区),主备实例强制分布在不同的可用区。这一设计的出发点是高可用——单个机房故障时可以自动切换。但代价是什么?

每一次写操作,至少需要跨可用区至少 1 次:

  1. 应用写入主库 → EBS 通过网络同 AZ落盘
  2. 半同步复制 → 跨 AZ 将 binlog 发送到备库
  3. 备库确认收到 → 跨 AZ 返回 ACK

实测 AWS 可用区间 RTT 约 0.75ms 。这意味着仅网络延迟这一项,每次写操作就要额外付出 0.75ms 的开销,这在数据库上是无法忍受的慢慢慢!

以上是理论计算,我们来看一下实际业务体感:

  • AWS 上一次最简单的 INSERT:3.32ms(业务实测)
  • 同样的业务在 IDC 物理机:微秒级(0.x ms)

差距不是百分之几十,而是 数倍到一个数量级

1.2 对比:阿里云的灵活选择

阿里云 RDS 提供集群模式,允许将 2 个节点部署在同一可用区,在对延迟极度敏感的场景下实现接近 IDC 的性能。用户可以根据自身业务特点在”极致高可用”和”极致低延迟”之间做选择。

AWS 和华为云目前不提供这种灵活性,用户被强制接受跨 AZ 的延迟开销。

1.3 云盘延迟:贵不等于快

AWS 的 EBS 云盘走网络存储,延迟远高于本地盘。实测数据(fio 4K 随机读写,iodepth=1):

云盘类型 读延迟 写延迟
AWS io2(最贵) 393 us 306 us
AWS io1 588 us 868 us
AWS gp3 686 us 994 us

gp3 写延迟接近 1ms ,而阿里云 ESSD 在同等场景下可以做到 0.1~0.2ms 级别。AWS 最高档的 io2 写延迟(306us)仍然是阿里云高性能云盘的 2-3 倍

对于数据库这种对 IO 延迟极度敏感的负载,这意味着每一个 commit 都在额外等待。


二、工程实践:350 秒连接静默丢弃事件

如果说设计理念的问题还可以归结为”理念之争”,那么以下这个事件则暴露了 AWS 在工程实践和事故响应上的严重问题。

2.1 问题现象

业务迁移到 AWS 第 8 代实例(M8/C8/R8,Nitrov6 架构)后,Java 服务每隔 20~30 分钟出现批量连接超时:

1
Connection is not available; request timed out after 5006ms

网络延迟稳定在 ~8ms,0% 丢包,MySQL 健康。

2.2 根因:ENI 连接跟踪超时从 5 天骤降至 350 秒

通过 80 分钟、84595 个包的系统性抓包分析,定位到根因:

AWS 第 8 代实例的 ENI(弹性网卡)安全组连接跟踪,将 TCP Established 默认超时从 432000 秒(5 天)悄然改为 350 秒。

实例代次 Nitro 版本 TCP Established 默认超时
第 7 代及以下 Nitrov5 及以下 432000s(5 天)
第 8 代(M8/C8/R8) Nitrov6 350s

这是一个 1234 倍的缩减 ,且行为极为恶劣——超时后 ENI 静默丢弃数据包,不发送 RST,不通知任何一方。抓包中 84595 个包 0 个 RST

客户端和服务端都以为对方还在,TCP 连接变成”僵尸”——直到下次使用时才发现已死,此时应用只能等待重传超时(数十秒到数分钟),表现为”突然卡住然后超时”。

2.3 AWS 的事故复盘令人失望

这一事件中 AWS 的表现:

  1. 文档滞后:用户 4 月初碰到问题,4 月 7 日定位到中间设备释放连接,4 月 15 日还在抓包验证。而 AWS 直到 4 月 11 日才在文档中加入警告段(通过 Wayback Machine 快照对比确认)

  2. 变更未通知:从 432000s 改到 350s 这种破坏性变更,C8gn GA 公告(2025-06)中未提及超时变更。用户升级实例后莫名遇到连接问题,排查成本极高

  3. 比 NAT Gateway 更”哑”

    • NAT Gateway / NLB 超时后至少一侧会收到 RST,应用能感知”对端断了”
    • ENI conntrack 超时:双侧都收不到 RST ,包被静默丢弃,应用只能靠 OS 重传超时来发现
  4. 复盘质量:AWS 官方的事件复盘未能清晰阐述根因,定位路径模糊

2.4 “350 秒”——AWS 的系统性问题

350 秒这个数字在 AWS 生态中反复出现:

组件 空闲超时 超时后行为
NAT Gateway 350s(固定) 发 RST
NLB(2024-09 前) 350s(固定) 发 RST
GWLB 350s 发 RST
ENI Conntrack(Nitrov6) 350s(默认) 静默丢弃

社区早在 2021 年就有人踩坑(Paramount Tech Blog),2022 年 DBA 博客记录了 JDBC 挂起问题,2023 年 urllib3 专门开了 Issue。这不是新问题,但 AWS 在 ENI 层面重蹈覆辙,且行为更恶劣(不发 RST)。


三、性能数据:Sysbench 实测全面落后

以下数据来自 10 个环境的标准化 Sysbench 测试,使用 16 表 x 1000 万行(约 50GB 数据),MySQL Buffer Pool 16GB,故意制造 IO 压力以考验真实磁盘性能。

3.1 只写场景(oltp_write_only)—— 单线程 QPS

这是最能体现”每次写操作延迟”的场景:

环境 1 线程 QPS 对比 IDC
IDC(物理机) 19,282 基准
IDC(trx1) 15,367 80%
阿里云 12,484 65%
阿里云(trx1+repl) 5,832 30%
AWS io2 8,881 46%
AWS io2(trx1) 3,575 19%
AWS gp3 1,689 9%

AWS gp3 单线程写入性能仅为 IDC 的 9%,仅为阿里云的 14%。 即使用最贵的 io2 云盘(价格是 gp3 的数倍),开启 trx1 后也只有 IDC 的 19%。

3.2 读写混合场景(oltp_read_write)—— 64 线程 QPS

环境 64 线程 QPS 对比阿里云
阿里云 83,569 基准
IDC 69,255 83%
AWS io2 51,002 61%
AWS gp3 64,869 78%

3.3 点查询场景(oltp_point_select)—— 64 线程 QPS

环境 64 线程 QPS 对比阿里云
阿里云 328,098 基准
IDC 299,555 91%
AWS io2 157,480 48%
AWS gp3 228,321 70%

AWS io2 在纯读场景下也只有阿里云的 48% ,令人诧异。

3.4 延迟对比(95 分位,单线程)

场景 IDC 阿里云 AWS io2 AWS gp3
点查询 0.04ms 0.07ms 0.09ms 0.67ms
只写 0.52ms 0.99ms 1.61ms 5.99ms
读写混合 2.81ms 3.30ms 3.89ms 15.00ms

AWS gp3 的只写延迟是 IDC 的 11.5 倍,是阿里云的 6 倍。

3.5 小结

即便使用 AWS 最贵的 io2 云盘(2T 云盘价格是 8C32G 机器的 8 倍),性能仍然大幅落后于阿里云使用普通云盘的配置。云盘延迟是 AWS 数据库性能的致命瓶颈。


四、价格:花更多的钱,买更差的性能

4.1 AWS RDS MySQL 成本

以 16C64G、GP3 2TB 20000 IOPS、3 节点(1 主 1 Multi-AZ 备 1 只读副本)为例:

Intel(db.m5d.4xlarge):

  • 计算:¥204,964/年(折后)
  • 存储(GP3 2TB x3):¥83,589/年(折后)
  • 监控(CloudWatch):¥25,713/年(折后)
  • 合计:约 ¥314,266/年

ARM(db.m6gd.4xlarge):

  • 计算:¥183,718/年(折后)
  • 存储:¥83,589/年(折后)
  • 合计:约 ¥267,307/年(不含监控)

最新一代 Intel(m7i.4xlarge,ap-southeast-1):价格更高。

4.2 性价比对比

维度 AWS(io2,最贵) AWS(gp3) 阿里云
只写 64 线程 QPS 79,754 43,519 110,923
读写混合 64 线程 QPS 51,002 64,869 83,569
云盘写延迟(iodepth=1) 306 us 994 us ~100-200 us
价格档位 极高

AWS 用最贵的云盘(io2),花了最多的钱,性能仍然不如阿里云用普通云盘。

io2 的 2T 云盘年费约为同规格机器的 8 倍——付出如此高昂的代价,换来的却是垫底的性能表现。

4.3 隐性成本

除了直接的资源费用,AWS 还有大量隐性成本:

  • 排障成本:350 秒静默丢连接这种问题,排查周期以周计,需要系统性抓包分析
  • 架构妥协成本:被迫跨 AZ 部署,无法选择同 AZ 低延迟模式
  • 升级风险成本:实例升代时默认行为发生破坏性变更,无事先通知
  • 学习曲线成本:需要深入了解 ENI 连接跟踪、NAT Gateway 固定超时等独有”坑点”

五、RDS MySQL 小版本升级维护需要重启两次

正常工程师脑回路的升级流程:Slave 升级到新版本,HA切换,业务闪断一次立即恢复正常,然后升级集群其它节点,完毕。

但AWS RDS MySQL 小版本升级的时候Master要重启2次,是的他们的升级逻辑就是这么干的导致我们业务2次跌0,很难想象这是全球最牛逼的云服务厂商干出来的事情,关键还不改 最可气的是他们认为这不是bug,只是by design,照这个歪理就没有bug,都是设计好了的

用户在这里最无助的就是他们不认为是bug,而且绝对不会去改

六、EMR 默认 JDBC 驱动兼容性缺陷:用了开源不测试,出了问题让客户自己换 jar

6.1 问题现象

EMR 集群(Hive 3.1.3)执行 CREATE TABLE 报错:

1
2
MetaException: Table "partition_keys" has been specified with a primary-key
to include column "TBL_ID" but this column is not found in the table.

Metastore 后端是 RDS MySQL 8.0,设置了 lower_case_table_names=1(AWS RDS 支持的合法配置)。

6.2 根因

EMR 默认打包的 JDBC 驱动是 MariaDB Connector/J 2.7.2,而非 MySQL 官方驱动。该驱动的 DatabaseMetaData.getColumns() 方法在连接 MySQL 8.0 + lower_case_table_names=1 时存在 bug:

  • MySQL 8.0 在 lower_case_table_names=1 下,数据字典中所有标识符以小写存储
  • MariaDB Connector 查询 information_schema 时,不对表名做大小写归一化,返回的列名全部是小写(tbl_id
  • Hive Metastore 使用的 DataNucleus ORM 内部以大写定义主键列名(TBL_ID),做大小写敏感比较 → 匹配失败

MySQL 官方 Connector/J 很早就有 normalizeIdentifierCase() 方法处理此场景,替换为 MySQL Connector/J 8.0.33 后问题消失。

6.3 为什么 EMR 用 MariaDB Connector 而不是 MySQL 官方驱动

这是许可证原因,不是技术原因:

  • Oracle MySQL Connector/J 是 GPL v2(强 copyleft),商业产品分发时无法满足条款
  • Oracle 的 FOSS Exception 要求整体作品为自由软件,EMR 不适用
  • Apache 基金会将 GPL 列为 Category X 禁用许可,Hive/Spark 等上游项目本身就不能打包它
  • MariaDB Connector/J 是 LGPL 2.1(弱 copyleft),允许商业分发,协议兼容,能正常连接 MySQL

法律上没问题。但工程责任上呢?

6.4 AWS 的工程责任缺失

选择了 MariaDB Connector 作为默认驱动,连接的后端是 MySQL 8.0,lower_case_table_names=1 又是 MySQL Server 支持的合法参数组合——这条数据通路是 EMR 最核心的路径之一(Hive Metastore 每次建表、查表都走这里)。但 AWS:

  1. 没有充分集成测试lower_case_table_names=1 + MySQL 8.0 + MariaDB Connector 的组合不是什么边缘场景,是 Hive Metastore 的核心路径。AWS 自己的 RDS 文档还专门说明如何设置此参数,结果自家 EMR 的默认驱动不兼容自家 RDS 的合法配置
  2. 没有回馈上游:这个 bug 在 MariaDB Connector 中存在多年,AWS 作为最大的间接用户之一,从未提交过 patch 或 issue
  3. 没有文档提示:EMR 文档中不存在任何 Known Issues 警告此兼容性问题
  4. 修复方案甩给客户:官方答复是”可通过 bootstrap action 自行替换 jar”——把本应是产品质量保证的工作,转嫁为客户的排障成本

6.5 这不是个案,是模式

我们已经向 MariaDB 社区提交了 bug report(CONJ-1344),但这件事本质上暴露的是 AWS 对开源组件的态度:

“我用 LGPL 不用付费也不用回馈,出了问题客户自己换 jar。”

这在法律上没毛病,但在工程责任上是甩锅。一个年收入百亿美元级的云产品,连核心数据通路的驱动兼容性都不做充分验证——不测试自家 RDS 参数和自家 EMR 驱动的组合——确实说不过去。

这和前面的”350 秒超时不通知”、”小版本升级重启两次 by design”如出一辙:AWS 追求的是”能跑起来”而非”跑得对”,出了问题不认 bug 只认 design,修复靠客户自助。全球第一的产品,三流的工程责任感。


七、结论:惯性认知 vs 客观事实

AWS 能成为全球第一,有其历史原因:起步最早(2006 年)、生态最完善、全球覆盖最广。但”市场占有率第一”不等于”技术最优”,更不等于”性价比最高”。

从本文的实测数据来看:

维度 表现
设计理念 强制跨 AZ,牺牲延迟换高可用,不给用户选择权
工程实践 350s 超时静默丢包,变更不通知,复盘不透明
开源责任 用 LGPL 组件不测试不回馈,驱动兼容性问题甩给客户自行替换
性能 全场景 Sysbench 垫底,gp3 只写仅为 IDC 的 9%
价格 同等配置显著高于竞品,io2 价格是机器的 8 倍
性价比 花最多的钱,得到最差的性能

很多企业选择 AWS 的原因是”大家都在用””全球第一应该不会错”——这是典型的幸存者偏差品牌惯性。当我们真正用数据说话时,会发现这个”全球第一”的光环,更多是依靠先发优势和生态锁定维持的,而非技术和性价比的领先。

对于数据库这类对延迟和 IO 性能极度敏感的工作负载,在有选择的情况下,AWS 恐怕是最不应该选的那一个。

当然站在 AWS 立场有一个必杀技:AWS 的设计理念就是……


注:本文所有性能数据均来自实际测试环境,测试工具为 sysbench,测试代码开源。网络分析基于 84595 个包的系统性抓包。价格数据来自官方控制台和报价器。文档变更时间线通过 Wayback Machine 快照验证。

AWS 连接超时根因分析

问题现象

业务从本地机房迁移到 AWS 后,Java 服务访问跨机房 MySQL 数据库(AWS EC2 → 专线 → 本地机房 DB),每隔 20~30 分钟出现批量连接超时:

1
2
Failed to validate connection (No operations allowed after connection closed.)
Connection is not available; request timed out after 5006ms

关键特征:

  • 网络延迟稳定在 ~8ms,0% 丢包
  • MySQL 健康(wait_timeout=86400s, Threads_connected 正常)
  • 调整 HikariCP maxLifetime 从 30 分钟改为 20 分钟后,报错间隔也跟着变成 20 分钟
  • 旧服务(本地机房内部)无此问题,只有跨机房访问才出现

排查过程

第一轮:HikariCP 连接池分析

初始怀疑是 HikariCP 3.x 的 maxLifetime 机制导致连接集中过期。

验证方法:搭建 HikariCP 3.4.5 + MySQL 5.7 的独立 Demo,配置 poolSize=10, minimumIdle=maximumPoolSize, maxLifetime=90s,观察连接过期行为。

发现:HikariCP 在 maxLifetime 到期时主动异步替换连接,每个替换仅需 3-8ms:

1
2
10:32:23.996 Closing connection @6d21071: (connection has passed maxLifetime)
10:32:24.004 Added connection @60401ca4 ← 8ms 后替换完成

结论:在 MySQL 可达且网络正常(RTT < 20ms)的环境下,纯 maxLifetime 批量过期无法导致连接超时。HikariCP 的异步替换机制工作正常。问题的根因不在 HikariCP 本身。

第二轮:TCP keepalive 与中间设备分析

AWS → 本地机房的网络路径中存在防火墙(空闲会话 30 分钟清除),可能还有 NAT Gateway 等中间设备。

关键验证:反编译 MySQL Connector/J 5.1.49 字节码,确认 tcpKeepAlive 默认值:

1
2
3
// ConnectionPropertiesImpl.class 字节码
3970: ldc_w #519 // String tcpKeepAlive
3973: ldc_w #514 // String true ← 默认值 = true(从 5.0.7 开始)

同时通过 ss -tnpei 验证运行中的 JDBC 连接确实开启了 SO_KEEPALIVE:

1
ESTAB 127.0.0.1:62718 → 127.0.0.1:3316 timer:(keepalive,5.519ms,0)

AWS EC2 的 tcp_keepalive_time = 1200s(20 分钟)。如果中间设备的空闲超时 < 1200s,keepalive 探测会来不及续命,连接被静默丢弃。

第三轮:抓包分析定位精确超时

在 AWS EC2 上抓取了约 80 分钟的 MySQL 连接网络包(84595 个包,145 个连接),进行系统性分析。

核心发现

1. 零 RST —— 中间设备静默丢弃连接

84595 个包中没有一个 RST 包。中间设备删除会话后不通知任何一方,TCP 连接变成”僵尸”——客户端和服务端都以为对方还在。

2. 精确定位中间设备超时:340~350 秒

按连接空闲时间统计 Server 是否响应了客户端的 FIN:

空闲时间 Server 响应 结论
333.9s (5.6min) ✅ 正常响应 连接存活
334s ~ 358s 临界区
357.7s (6.0min) ❌ 无响应 连接已死
  • Server 正常响应 FIN 的 27 个连接:最大空闲时间均 ≤ 334s
  • Server 未响应 FIN 的 98 个连接:最大空闲时间均 ≥ 358s

中间设备空闲超时 ≈ 340~350 秒,后确认为 AWS EC2 Nitrov6(第 8 代实例)ENI 连接跟踪默认超时 350 秒。

3. 僵尸连接的死亡模式

正常连接关闭(空闲 < 350s):

1
Client → COM_QUIT → Server 响应 FIN+ACK → 四次挥手完成 ✅

僵尸连接关闭(空闲 > 350s):

1
2
3
4
5
Client → COM_QUIT    → 被中间设备静默丢弃 → 无响应
Client → 重传 (0.2s) → 丢弃 → 无响应
Client → 重传 (0.4s) → 丢弃 → 无响应
Client → 重传 (0.8s) → 丢弃 → 无响应
Client → FIN → 丢弃 → 永远无响应

根因

2026-04-15 更新:经查 AWS 官方文档 确认,350 秒超时的真正来源是 EC2 第 8 代实例(Nitrov6 架构)的 ENI 安全组连接跟踪(Connection Tracking)默认超时,而非此前推测的 NAT Gateway。

实例代次 Nitro 版本 TCP Established 默认超时
第 7 代及以下 Nitrov5 及以下 432000s(5 天)
第 8 代(M8/C8/R8 等) Nitrov6 350s

可通过 aws ec2 describe-network-interfaces --network-interface-ids <eni-id> --query 'NetworkInterfaces[0].ConnectionTrackingConfiguration' 查询,返回 null 表示使用默认值。控制台路径:EC2 → Network Interfaces → 选择 ENI → 空闲连接跟踪超时。

1
2
3
4
5
6
7
                340~350s                    1200s
ENI 连接跟踪(Nitrov6) keepalive
空闲超时 首次探测
─────────────────┼──────────────────────────────┼──────────
连接空闲 │连接跟踪条目清除 │探测发出
│连接变僵尸 │但已经晚了
│双端不知情 │

三个因素叠加导致问题:

  1. EC2 Nitrov6 ENI 连接跟踪超时 350 秒:第 8 代 EC2 实例(M8/C8/R8 等,Nitrov6 架构)的安全组连接跟踪将 TCP Established 默认超时从 432000s(5天)降至 350s。连接空闲超过 350 秒后,ENI 连接跟踪条目被清除,后续数据包被安全组静默丢弃(不发 RST)
  2. OS tcp_keepalive_time = 1200 秒:远大于连接跟踪超时,keepalive 探测在连接死后 850 秒才发出,来不及续命
  3. HikariCP 3.x 无应用层 keepalive:3.x 版本没有 keepaliveTime 功能,不会主动检测空闲连接的存活状态

maxLifetime 的角色:不是根因,而是暴露问题的时间点。改 maxLifetime 只改变了”何时发现尸体”,而不是”何时死亡”。

旧服务不受影响的原因:旧服务在本地机房内部访问数据库,不经过 AWS EC2,不受 Nitrov6 ENI 连接跟踪超时影响。

验证实验

在 AWS EC2 上对比测试(原始 keepalive vs 调优后的 keepalive):

原始配置(tcp_keepalive_time=1200s):

maxLifetime 结果
5min (300s) ✅ 成功(< NAT 超时 350s)
10min ❌ 失败
15min ❌ 失败
20min ❌ 失败
30min ❌ 失败

调优后(tcp_keepalive_time=20s, intvl=10s, probes=3):

maxLifetime 结果
5min ✅ 成功
10min ✅ 成功
15min ✅ 成功
20min ✅ 成功
30min ✅ 成功

低 keepalive_time 让 OS 每 20 秒发送一次探测包,持续重置 NAT Gateway 的空闲计时器,连接永远不会被丢弃。

修复方案

方案 0:修改 ENI 连接跟踪超时(根因级修复,推荐)

直接调大 EC2 ENI 的 TCP Established 超时,从根源解决问题:

1
2
3
4
aws ec2 modify-network-interface-attribute \
--network-interface-id <eni-id> \
--connection-tracking-specification TcpEstablishedTimeout=432000 \
--region <region>

或在 EC2 控制台:Network Interfaces → 选择 ENI → Actions → Change connection tracking → 设置 TCP established timeout。

优点:根因级修复,恢复到与旧代实例一致的行为(432000s / 5天),无需改 OS 参数或应用配置。
注意:仅对新建连接生效,已有连接不受影响。

方案 1:降低 OS tcp_keepalive_time(最快生效)

1
2
3
4
5
6
7
8
9
10
sysctl -w net.ipv4.tcp_keepalive_time=120    # 2 分钟,远小于 NAT 350s
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=5

# 持久化
cat >> /etc/sysctl.conf << 'EOF'
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
EOF

优点:全局生效,所有 TCP 连接(MySQL、Redis、MQ 等)都受益,无需改代码。
注意:120s 远小于 350s,留足安全余量。

方案 2:升级 HikariCP 4.x+ 启用 keepaliveTime(应用层修复)

1
2
3
4
spring.datasource.hikari:
keepalive-time: 120000 # 2 分钟,应用层主动 ping 空闲连接
max-lifetime: 1800000 # 30 分钟
connection-test-query: SELECT 1

优点:不依赖 OS 配置,应用层独立控制。
限制:需要升级 HikariCP(4.0+ 才有 keepaliveTime),可能需要升级 JDK。

方案 3:不升级 HikariCP 的临时方案

1
2
3
4
5
6
7
spring.datasource.hikari:
maximum-pool-size: 32
minimum-idle: 10 # 必须 < maximum-pool-size
idle-timeout: 120000 # 2 分钟淘汰多余空闲连接
max-lifetime: 300000 # 5 分钟(< NAT 350s)
connection-test-query: SELECT 1 # 借出时验证
connection-timeout: 10000 # 给更多时间创建替换连接

原理:maxLifetime=5min < NAT 超时 350s,确保连接在被 NAT 丢弃前主动替换。
缺点:5 分钟的 maxLifetime 较短,连接轮换频繁,增加数据库连接创建负担。

推荐组合:方案 0(根因修复)+ 方案 1 + 方案 2(ENI 层 + OS 层 + 应用层三重保险)。

经验教训

1. 跨网络访问必须关注中间设备的空闲超时

本地机房内部的 TCP 连接可以长期空闲而不被打断。但跨机房、跨云的网络路径上往往存在 NAT Gateway、防火墙、LVS 等有状态设备,它们都有空闲会话超时(通常 5~30 分钟)。

迁移到云上时,即使 ping 延迟正常、丢包率为 0,仍然需要检查中间设备的空闲超时配置。

设备 典型空闲超时
AWS EC2 Nitrov6 ENI 连接跟踪 350s(第 8 代实例默认)
AWS EC2 旧代 ENI 连接跟踪 432000s(5 天)
AWS NAT Gateway 350s(~6 分钟)
防火墙 1800s(30 分钟)
LVS (IPVS) 900s(15 分钟)
云厂商 SLB/NLB 300~900s

2. tcp_keepalive_time 必须小于路径上最短的空闲超时

操作系统默认的 tcp_keepalive_time 通常是 7200s(2 小时),AWS 默认是 1200s(20 分钟)。这些默认值在存在中间设备的场景下往往过大。

建议值:60~120 秒,覆盖绝大多数中间设备的超时配置。

3. SO_KEEPALIVE 必须开启才有效

tcp_keepalive_time 是系统级默认值,但只对设置了 SO_KEEPALIVE 的 socket 生效

组件 SO_KEEPALIVE 默认值
MySQL Connector/J 5.1.x true(从 5.0.7 开始)
MySQL Connector/J 8.x true
应用直接创建 Socket false
Druid 连接池 不控制(依赖驱动)

验证方法:

1
2
ss -tnpei dst <db_ip>:<db_port> | head -3
# 看 timer:(keepalive,...) → 有则开启,无则关闭

4. 静默丢弃是最难排查的连接故障

本案中 NAT Gateway 不发 RST,直接丢弃不匹配的包。这导致:

  • 客户端发送数据后只能等待重传超时(数十秒到数分钟)
  • 没有任何”连接已断开”的信号
  • 从应用层看就是”突然卡住然后超时”

排查手段:在客户端抓包,关注两个信号:

  • 发送数据后长时间无 ACK(→ 中间设备丢包)
  • FIN 发出后无响应(→ 连接在中间设备已不存在)

5. “修改 maxLifetime 后报错时间跟着变”不能排除中间设备问题

这个现象容易误导排查方向。直觉上会认为”报错时间跟 maxLifetime 走,说明是 HikariCP 的问题”。实际上:

  • maxLifetime < 中间设备超时 → 连接在死之前被主动替换 → 不报错
  • maxLifetime > 中间设备超时 → 连接已死 → maxLifetime 到期时操作已死连接 → 报错

报错时间跟 maxLifetime 走,恰恰说明存在一个固定的中间设备超时阈值。

6. 连接池不是万能的

连接池(HikariCP、Druid 等)管理的是 JDBC Connection 对象的生命周期,但底层 TCP 连接的存活状态取决于 OS 和网络。连接池无法感知”TCP 连接已被中间设备静默丢弃”——除非主动发送数据去探测。

这就是 HikariCP 4.x 引入 keepaliveTime 的原因:定期向空闲连接发送 SELECT 1,主动打破沉默,让死连接尽早暴露。

7. ENI为什么只丢掉进来的包,而不丢掉出去的包?

这个问题直接触及 AWS 安全组的工作原理。

核心原因:出站靠的是显式规则,入站靠的是连接跟踪。

安全组通常这样配置:

1
2
3
出站规则 (Outbound):  0.0.0.0/0  All traffic  → ALLOW   ← 默认就是放行全部
入站规则 (Inbound): 10.0.0.0/8 TCP 22 → ALLOW ← 只开放特定端口
(没有 "允许来自 172.20.64.240:3306 的回包" 这条规则)

连接跟踪活着的时候(空闲 < 350s):

1
2
Client 出站 → 匹配出站规则 (allow all) → 放行 ✅ → 同时创建跟踪条目
Server 回包 → 匹配跟踪条目 (return traffic) → 放行 ✅ ← 不看入站规则,靠跟踪放行

连接跟踪过期后(空闲 > 350s):

1
2
Client 出站 → 匹配出站规则 (allow all) → 放行 ✅   ← 规则还在,照样放行
Server 回包 → 无跟踪条目 → 回退检查入站规则 → 无匹配规则 → 丢弃 ❌

所以不对称的根源是:出站有兜底的 allow-all 规则,入站没有。Server 的回包以前全靠连接跟踪
“搭便车”进来,跟踪条目一过期,便车没了,入站规则又没有显式放行这个流量,就被丢了。

如果你在入站规则里加一条 allow from 172.20.64.240/32 port 3306,理论上即使连接跟踪过期,
回包也能通过显式规则放行——但这就变成无状态过滤了,一般不建议这么做。

附录

抓包统计数据

指标 数据
抓包时长 4796 秒(~80 分钟)
总包数 84595
总连接数 145
RST 包数 0
Server 正常响应 FIN 27 个(最大空闲 ≤ 334s)
Server 未响应 FIN 98 个(最大空闲 ≥ 358s)
中间设备空闲超时 340~350s(与 EC2 Nitrov6 ENI 连接跟踪默认 350s 吻合)

测试代码

测试 Demo 代码位于同目录,修改 db.propertiesbash run.sh 即可运行,无需编译。

TCP 排障入门指南

本文从团队知识库中提炼而来,面向刚接触网络排障的新同学。不讲大而全的理论,只讲排障时真正用得上的东西。

第一课:排障的核心思维

记住三句话,比记住任何工具都重要:

  1. 一个错误现象可能对应多个完全不同的根因 —— 不要看到报错就下结论
  2. 不要相信报错信息的字面意思 —— 比如 net_write_timeout 报错不一定是超时
  3. 拿证据推进问题 —— 每一步推理都要有抓包、日志、堆栈等证据支撑

排障工具的优先级:

1
2
3
4
5
6
7
抓包(tcpdump/wireshark)  ← 网络层面的终极证据,优先用

堆栈/火焰图(perf/jstack) ← 定位代码热点

日志分析 ← 但要警惕日志被吃掉的情况

监控指标 ← 宏观趋势,不够精确

第二课:你必须知道的 TCP 基础

三次握手

1
2
3
4
Client              Server
|--- SYN ---------->| Client 进入 SYN_SENT
|<-- SYN+ACK -------| Server 进入 SYN_RECV(半连接队列)
|--- ACK ---------->| 双方进入 ESTABLISHED(全连接队列)

握手失败的常见原因:

现象 原因 怎么查
精确 1s/3s/7s 超时 SYN 被丢弃后重传 全连接队列满?防火墙 DROP?
Connection refused 端口没人监听 ss -lntp 看端口
偶发连接超时 半连接/全连接队列满 netstat -s | grep listen
NAT 下偶发不通 tcp_tw_recycle 丢 SYN netstat -s | grep "time stamp"

新人必记:碰到精确的 1s、3s、7s 超时,几乎可以断定是 SYN 丢包重传。SYN 重传间隔是 1s→2s→4s→8s 指数退避。

四次挥手

1
2
3
4
5
主动方              被动方
|--- FIN ---------->| 主动方: FIN_WAIT_1
|<-- ACK -----------| 被动方: CLOSE_WAIT ← 最常见的堆积点
|<-- FIN -----------| 被动方: LAST_ACK
|--- ACK ---------->| 主动方: TIME_WAIT(等 60 秒)
状态堆积 说明 排查
大量 CLOSE_WAIT 你的应用没调 close() ss -tp 看是哪个进程
大量 TIME_WAIT 短连接太多,通常无害 tcp_tw_reuse 缓解

新人必记:CLOSE_WAIT 是被动关闭方的状态,问题一定在你这边的应用代码。

传输性能公式

1
理论最大吞吐 ≈ min(发送窗口, 接收窗口, 拥塞窗口) / RTT

速度上不去时检查:

  • Buffer 太小ss -tm 看 skmem,检查 tcp_rmem / tcp_wmem
  • RTT 太大:RTT 越大,慢启动越久,丢包恢复越慢
  • 丢包:一旦丢包 RTO 指数退避(最大 120 秒),速度断崖式下降

第三课:五个必会的排障命令

1. ss —— 看连接状态(替代 netstat)

1
2
3
4
5
6
7
8
# 看监听端口的全连接队列(Recv-Q 是当前排队数,Send-Q 是队列上限)
ss -lnt

# 看所有 TCP 连接的详细信息(含 buffer、RTT、拥塞窗口)
ss -tinp

# 看连接统计
ss -s

2. netstat -s —— 看协议栈统计

1
2
3
4
5
6
7
8
9
10
11
# 全连接队列溢出(数字在增长就是有问题)
netstat -s | grep "listen queue"

# SYN 被丢弃
netstat -s | grep "SYNs to LISTEN"

# tcp_tw_recycle 导致的丢包
netstat -s | grep "passive connections rejected because of time stamp"

# 丢包/重传汇总
netstat -s | egrep -i "drop|retran|overflow|reject"

3. tcpdump —— 抓包

1
2
3
4
5
6
7
8
9
10
11
# 抓指定端口,保存为文件(用 wireshark 打开分析)
tcpdump -i eth0 port 3306 -s0 -w mysql.pcap

# 抓所有网卡(别忘了 lo,nginx→tomcat 走的是 lo)
tcpdump -i any port 8080 -s0 -w all.pcap

# 只抓 RST 包
tcpdump 'tcp[tcpflags] & (tcp-rst) != 0'

# 只抓 SYN 包(排查握手问题)
tcpdump 'tcp[tcpflags] & (tcp-syn) != 0'

新人必记:抓包时一定要抓 所有网卡-i any),不要只抓 eth0。很多内部通信走 lo 网卡,只抓 eth0 会漏掉关键包。

4. tshark —— 命令行分析抓包

1
2
3
4
5
6
7
8
# 统计每个连接的 RT
tshark -r file.pcap -q -z io,stat,1

# 过滤 MySQL 错误
tshark -r file.pcap -Y "mysql.error_code != 0"

# 看 TCP 重传
tshark -r file.pcap -Y "tcp.analysis.retransmission"

5. 内核参数快速检查

1
2
3
4
5
6
7
# 一键查看关键 TCP 参数
sysctl net.ipv4.tcp_tw_recycle # 必须是 0!
sysctl net.core.somaxconn # 全连接队列上限,建议 ≥ 2048
sysctl net.ipv4.tcp_max_syn_backlog # 半连接队列
sysctl net.ipv4.tcp_retries2 # 重传放弃次数,内网建议 5-10
sysctl net.ipv4.tcp_rmem # 接收 buffer
sysctl net.ipv4.tcp_wmem # 发送 buffer

第四课:按现象查问题(速查表)

连不上

现象 第一步 第二步
Connection refused ss -lntp 看端口是否在监听 检查进程是否存活
超时 1s/3s/7s netstat -s | grep listen 看队列溢出 抓包确认 SYN 是否被丢
偶发超时(NAT 环境) sysctl net.ipv4.tcp_tw_recycle 如果是 1 立即改 0
部分机器不通 traceroute + 两端同时抓包 检查路由/ARP/交换机

连上了但是断开

现象 第一步 第二步
Connection reset 抓包看 RST 是谁发的 检查防火墙/中间设备
大量 CLOSE_WAIT ss -tp 找到对应进程 检查代码是否漏了 close()
服务切换后长时间不恢复 检查 tcp_retries2 调小到 5-10

连上了但是慢

现象 第一步 第二步
RT 偶发 40ms 毛刺 抓包看是否 Delayed ACK 设置 TCP_NODELAY
传输速度上不去 ss -ti 看 cwnd/ssthresh/rto 检查 rmem/wmem 是否太小
速度突然下降 抓包看是否有重传 检查 RTO 是否飙到 120s

第五课:四个真实案例(必读)

案例 1:报错说 net_write_timeout,其实是被 kill 了

迁移工具报 Consider raising value of 'net_write_timeout',调大参数无效。抓包发现 MySQL Server 在传数据途中夹带了 FIN 包,查 DB 日志发现是用户自己的监控脚本 kill 了慢查询。

教训:JDBC streaming 模式下任何连接异常都报 net_write_timeout,不要被字面意思骗了。抓包看谁先发 FIN 是铁证。

详见:历时 5 年的 net_write_timeout 分析

案例 2:Sysbench 性能只有预期的 10%

processlist 全是 Opening tables,调大 table_open_cache 无效。最后发现是 --tables=64 写错了(实际只有 32 张表),加上 --mysql-ignore-errors=all 把 Error 1146 全吞了。

教训:抓包能看到 Error 1146 和异常 RT(2200ms vs 正常 0.1ms),即使不知道问题在哪,抓包也能发现异常。

详见:Sysbench Opening Tables 卡慢

案例 3:数据库重启后业务 15 分钟才恢复

数据库 crash 重启后,业务长时间报错。原因是 tcp_retries2 默认 15,TCP 需要约 924 秒(15 分钟)才能感知到连接断开。

教训:内网把 tcp_retries2 改成 5-10。应用层心跳比 TCP Keepalive 更可靠。

详见:长连接黑洞

案例 4:开了 tcp_tw_recycle,NAT 下偶发连不上

服务端开了 tcp_tw_recycle,NAT 后面多台客户端的 TCP timestamp 不一致,导致 SYN 被 PAWS 校验丢弃。

教训:永远不要开 tcp_tw_recycle。4.12 内核已删除此参数。用 netstat -s | grep "time stamp" 诊断。

详见:tcp_tw_recycle + NAT 导致 SYN 丢包

第六课:新人上手清单

拿到一台新机器,先跑一遍这些命令建立基线:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 看内核版本(4.12 以下要特别注意 tcp_tw_recycle)
uname -r

# 2. 检查危险参数
sysctl net.ipv4.tcp_tw_recycle 2>/dev/null # 必须是 0 或不存在
sysctl net.core.somaxconn # 太小(128)要调大

# 3. 看当前连接状态分布
ss -s

# 4. 看是否有队列溢出(记下数字,过一会再看是否增长)
netstat -s | egrep -i "listen|overflow|drop|retran"

# 5. 看监听端口的队列使用情况
ss -lnt

延伸阅读

本指南的所有内容都来自团队知识库 ~/case/ 下的原始文档,想深入学习可以按以下路径:

  1. TCP 连接原理网络/就是要你懂TCP--连接和握手.md网络/就是要你懂TCP--半连接队列和全连接队列.md
  2. TCP 性能网络/就是要你懂TCP--性能和发送接收Buffer的关系.md网络/就是要你懂TCP--最经典的TCP性能问题.md
  3. 抓包技巧工具/就是要你懂抓包--WireShark之命令行版tshark.md网络/如何从几百万个抓包中找到一个异常的包.md
  4. 排障方法论网络/举三反一--从理论知识到实际问题的推导.md网络/程序员如何学习和构建网络知识体系.md

本文由 LLM 基于 wiki 知识库自动生成,最后更新:2026-04-07

普京的克里米亚 —— 高晓松谈俄乌局势(2014年)

本文根据高晓松2014年《晓松奇谈》节目音频转录整理,原视频约54分钟。


一、克里米亚为什么重要

在西方人心中的地位

克里米亚对中国人来说不算特别著名,大概只有军迷比较熟悉——中国第一批航母飞行员就在克里米亚的陆上模拟航母基地训练过。但对西方人来说,克里米亚可太著名了。欧洲人提到克里米亚、塞瓦斯托波尔,比提到基辅(乌克兰首都)还要熟悉。巴黎有一条重要大街就叫”塞瓦斯托波尔大街”——法国这么骄傲的国家,用一个俄国地名来命名街道,正是因为法军攻克塞瓦斯托波尔是法国军事史上最光荣的战役之一。

克里米亚战争:现代战争的雏形

1853-1856年的克里米亚战争是英法联军加奥斯曼土耳其帝国对阵沙俄。这场战争创下了大量的”世界第一”:

  • 第一次用电报指挥和发战报的战争——欧洲人第一次实时看到战争,相当于一场”直播的战争”
  • 第一次有照片的战争——摄影术刚发明,克里米亚战争留下了最早的战地照片
  • 第一批战地记者诞生于此
  • 第一次使用线膛枪(莱福枪)的战争
  • 第一次使用铁路运输的战争
  • 第一次有战地救护的战争——著名的南丁格尔就在克里米亚战场上首次开展护理工作,护士节因此纪念南丁格尔
  • 第一次蒸汽战舰参战
  • 天气预报图首次被应用于军事
  • Red Line“(红线)这个成语的起源——英军步兵画了一条红线对抗哥萨克骑兵冲锋

可以说,克里米亚战争奠定了现代战争的雏形,是人类历史上第一场真正意义上的现代化战争(美国南北战争是几年后的第二场)。

对俄国的战略意义

俄国历代沙皇梦寐以求一个出海口。彼得大帝找到了圣彼得堡的出海口,但那只通往北欧,容易被封锁。俄国拼命向南扩张,终于见到了黑海,打到了克里米亚。这是全体俄国人”痛哭流涕”的大事——终于可以进入地中海,接触欧洲文明的中心了。

克里米亚对俄国的军事地位极为重要:有了克里米亚,黑海舰队就有了自己的基地(塞瓦斯托波尔);没有克里米亚,就得租用乌克兰的基地,而租用的基地永远是不靠谱的——乌克兰随时可以涨价或收回。

二战中的克里米亚

二战德军第一能打的统帅曼施坦因元帅的成名作就是进攻克里米亚。他在缺乏坦克的情况下,带着德国步兵和一批罗马尼亚军队,面对拥有坦克、飞机和黑海舰队的苏军,艰苦地打下了克里米亚。围攻塞瓦斯托波尔时,德军调来了800毫米口径的超级大炮轰击要塞,创下人类战争史的纪录。曼施坦因在前线被升为元帅,从此一战成名。


二、普京——强人领导弱国

普京是什么人?用一句话概括:一个强人领导了一个弱国

俄国不管从GDP还是其他方面来看,都不能算一个强国。不能说有原子弹就算强国——朝鲜还有原子弹呢。一辆像样的汽车都制造不出来的国家(拉达已经非常古老了),不能算一个强国。

这种情况非常像一战和二战时期的德国——二战前德国也没有美国和苏联强,但有了强人领导,就敢于冒险:占领苏台德地区、吞并奥地利、入侵波兰。日本当时也不是最强国,但有强人领导,就敢冒险发动战争。

普京的冒险路径:车臣 → 格鲁吉亚(南奥塞梯)→ 克里米亚,一步步试探西方底线。


三、克里米亚的法理之争

普京的理由

克里米亚一直到1954年还是俄罗斯的。赫鲁晓夫是乌克兰人,他上台后把克里米亚划给了乌克兰——当时都在苏联这一个国家内,只是行政区划变动,谁都没当回事。就像中国解放后撤销热河省、察哈尔省一样,大家反正都在一个国家里。

而且你去问欧洲人,所有人都会说克里米亚是俄罗斯的——因为从小读到的文学作品、看到的战争英雄,都是跟俄国打仗。

普京没有提到的事实

1991年苏联解体时,克里米亚人民举行了公投——54%的多数决定跟着乌克兰走。这次公投从国际法和基本法理来说都是合理的:一个大国分裂,局势未定,由人民公投决定归属——就像德国统一时,东德解散后五个州各自公投加入德意志联邦。

一个已经在一起20多年的国家,其中一部分地区能不能随时公投决定离开?这在国际上是一个复杂问题。

各国公投的不同命运

  • 苏格兰:经过议会斗争,获得英国议会同意后公投,完全合法合理
  • 魁北克:加拿大同意公投,但约定了公投间隔年限
  • 加泰罗尼亚:西班牙不同意公投,所以全世界都不能承认
  • 科索沃:西方支持公投独立,但西班牙和罗马尼亚因自身”麻筋”没有承认

普京抓得最准的一点就是拿科索沃做类比:你们支持科索沃公投独立,为什么不能支持克里米亚?


四、各国的态度与利益博弈

德国:最值得敬佩的表态

高晓松表示最敬佩的是德国。因为德国本身是最多领土在外面的国家——东普鲁士首府柯尼斯堡(现在的加里宁格勒)在二战后割给了俄罗斯,康德就在那里出生长大。如果德国支持克里米亚回归俄罗斯的逻辑,那柯尼斯堡要不要公投回德国?波兰西部原来也是德国的领土……这将引发连锁反应。

但德国总理默克尔第一个站出来坚决反对普京吞并克里米亚,等于堵住了未来德国追讨失去领土的后路。这是非常伟大的:再次向全世界表态,承认二战以后的所有边界,不再追求”历史上的领土”。

法国:暧昧

法国经济差,俄罗斯向法国订购了两艘”西北风”级两栖攻击舰(高晓松误说为四艘),给法国造船厂提供了大量就业机会。

英国:暧昧

俄国寡头大量住在伦敦,买了切尔西足球队,洗钱成本20%归了英国银行,投资房产推高了伦敦房价。

其他欧洲国家

对俄罗斯天然气和石油的依赖,让他们不敢太”闹”。


五、日内瓦协议:像极了慕尼黑协定

2014年签署的日内瓦协议由俄罗斯、乌克兰、欧盟和美国四方达成。高晓松震惊地发现,这个协议只字未提克里米亚——等于默认归俄罗斯了。协议只要求乌克兰其他地方的非正规武装解除武装。

这和1938年的慕尼黑协定惊人地相似:当年英法默认苏台德地区归德国,希特勒答应”没有别的需求了”——然后转眼就吞并了奥地利,紧接着入侵波兰。

“历史上没有一次绥靖真的让对方消停。什么时候才真消停?兵临城下,你再往前一步我就开炮。”


六、联合国投票的微妙格局

联合国大会(非安理会,无法律效力)对克里米亚问题的投票结果:

  • 100国赞成谴责(以美欧为首)
  • 11国反对(基本是反美的国家:白俄罗斯、委内瑞拉、朝鲜、古巴等)
  • 58国弃权(最值得关注)
  • 24国缺席

弃权的58国中包括金砖四国(除俄罗斯外的中国、印度、巴西、南非),这是给西方一个明确信号:这个世界来了新玩家,不是你们几个大国商量完就完了。

美国宣布胜利:100对11。俄罗斯也宣布胜利:93国没有支持美国(58弃权+11反对+24缺席)。


七、谁是最大受益者

中国:第一大受益者

高晓松认为中国是克里米亚事件的最大受益者,理由是”国运”论:

  1. 冷战后期,西方为了拉拢中国对抗苏联,给了大量援助
  2. 苏联解体后,西方刚要对付中国,拉登来了(911),于是又需要拉拢中国一起反恐
  3. 好不容易击毙拉登,回头一看中国已经庞大极了
  4. 刚要说”不能让你再大了”,俄罗斯又冲上去了——替中国挡住了西方的注意力

俄罗斯:短期受益、长期堪忧

克里米亚”装兜里了”,但被孤立的伤害在全球化时代比一战二战时期要严重得多。


八、”俄国对中国的伤害不亚于日本”

高晓松直言:

  • 俄国从沙俄到苏联到今天,从没遵守过协议
  • 日俄战争期间双方在中国东北都没少犯罪
  • 二战末苏联把东北所有工厂、铁路全部拆走,银行黄金拉回苏联,发行废纸般的红军票
  • 华人在俄国备受歧视,在莫斯科的市场被抢了不止一两次
  • 在所有大国中,”对中国最好的就是美国”——建了清华大学、协和医院,给了大量援助,华人在美国可以当部长、州长、参议员

“不知道为什么网上的愤青天天骂美国、要跟俄国站一块。”



第二部分:事实校对

以下对节目中涉及的具体历史事实逐一查证,标注准确性。

校对1:克里米亚1950年代划归乌克兰

✅ 正确。 赫鲁晓夫于1954年2月19日签署法令,将克里米亚从俄罗斯苏维埃联邦社会主义共和国划归乌克兰苏维埃社会主义共和国。

校对2:”1991年公投54%决定跟乌克兰走”

⚠️ 部分正确,表述有误导性。 实际上1991年发生了两次公投:

  • 1991年1月20日:克里米亚自治公投,问的是”是否恢复克里米亚自治苏维埃社会主义共和国”,94.3%赞成——这次公投的本意是让克里米亚恢复为苏联的直接主体,而非留在乌克兰。
  • 1991年12月1日:乌克兰全国独立公投,克里米亚地区54.19%投赞成乌克兰独立。

“54%”这个数字来自后者。这不是克里米亚单独举行的”跟乌克兰还是跟俄罗斯”的公投,而是乌克兰全国公投在克里米亚地区的投票结果。

校对3:巴黎塞巴斯托波尔大街

✅ 正确。 巴黎确有 Boulevard de Sébastopol,长1,332米,宽30米,位于巴黎第1、2、3、4区之间,1855年以克里米亚战争中的塞瓦斯托波尔围攻命名。

校对4:克里米亚战争的多个”第一次”

更准确的说法是”最早之一”(one of the first),而非绝对第一:

说法 判定 说明
第一次用电报指挥 ⚠️ 最早之一 美墨战争(1846-48)中也使用过电报
第一次有照片 ⚠️ 最早之一 美墨战争有零星达盖尔银版照片;克里米亚是第一次大规模系统性摄影记录
第一批战地记者 ✅ 基本正确 William Howard Russell为《泰晤士报》做系统战地报道,被公认为现代战地记者先驱
第一次使用蒸汽战舰 ❌ 不准确 第一次鸦片战争(1840年)英国”复仇女神号”蒸汽船已参战;克里米亚是第一次使用铁甲蒸汽战舰
南丁格尔与战地救护 ✅ 基本正确 南丁格尔开创了系统化、专业化的现代护理体系

校对5:”Red Line源自克里米亚战争”

❌ 不准确,有两处错误:

  1. 正确名称是 “Thin Red Line”(细红线),不是 “Red Line”(红线作为”底线”的含义另有来源)
  2. 1854年巴拉克拉瓦战役中,是93苏格兰高地兵团以两列纵深抵挡俄国骑兵(非专指哥萨克骑兵),记者Russell描述为 “a thin red streak topped with steel”

校对6:”曼施坦因一辆坦克都没有”

❌ 不准确。 塞瓦斯托波尔围攻期间,第11集团军拥有约150辆坦克,编成中包括第22装甲师和约65辆三号突击炮。曼施坦因确实以步兵为主力、装甲力量相对薄弱,但说”一辆坦克都没有”是错误的。

校对7:800毫米口径大炮

✅ 正确。 指的是**”古斯塔夫重炮”(Schwerer Gustav)**,口径800毫米,是有史以来实战使用过的最大口径线膛武器。1942年在塞瓦斯托波尔围攻中发射了47发炮弹。另有三门600毫米卡尔臼炮参战。

校对8:”法国订购四艘大型登陆舰”

❌ 数量不准确。 实际是两艘(不是四艘)”西北风”级(Mistral-class)两栖攻击舰,分别命名为”符拉迪沃斯托克号”和”塞瓦斯托波尔号”。合同金额12亿欧元。

校对9:联合国投票100:11:58

✅ 完全正确。 2014年3月27日联合国大会第68/262号决议投票结果:100票赞成、11票反对、58票弃权、24国缺席。金砖四国(中印巴南)均弃权。

校对10:苏联策动外蒙古独立公投

✅ 基本正确。 1945年10月20日举行公投,官方结果100%赞成独立(487,409票赞成,0票反对),投票率98.47%。公投是在苏联压力下、中国被迫签署《中苏友好同盟条约》后进行的,100%的结果显然不可能是自由投票。

校对11:”美国援助超过中国赔款总和的数十倍”

❌ 夸大。 中国近代主要赔款(《南京条约》《马关条约》《辛丑条约》等)折合约7-13亿美元;美国二战租借法案援华约16.27亿美元加上其他援助约20-30亿美元,大约为赔款的2-4倍量级,远非”数十倍”。


校对总结

说法 判定
克里米亚1954年划归乌克兰 ✅ 正确
1991年公投54%跟乌克兰 ⚠️ 数字对,性质描述不够准确
巴黎塞巴斯托波尔大街 ✅ 正确
克里米亚战争多个”第一次” ⚠️ 多数是”最早之一”而非绝对第一
Red Line源自克里米亚 ❌ 应为Thin Red Line
曼施坦因没有坦克 ❌ 有约150辆坦克
800毫米大炮 ✅ 正确
法国卖四艘军舰 ❌ 是两艘
联合国投票数字 ✅ 完全正确
苏联策动外蒙古公投 ✅ 基本正确
美援超赔款数十倍 ❌ 实约2-4倍

第三部分:十年后验证——2014年预测 vs 2026年现实

高晓松在2014年做了若干关于未来的预测和判断。12年后,哪些被证实了?

预测1:”克里米亚这件事远远没完” ★★★★★

完全正确,甚至超出预期。

  • 2014年起,顿巴斯地区爆发武装冲突
  • 2014年7月,马航MH17被俄制导弹击落,298人遇难
  • 2022年2月24日,俄罗斯发动全面入侵乌克兰——二战以来欧洲最大规模地面战争
  • 战争造成数十万人伤亡,数百万难民

高晓松说得对:克里米亚只是一个开始。

预测2:”日内瓦协议就像慕尼黑协定” ★★★★★

慕尼黑类比精准。 日内瓦协议签字墨迹未干,顿巴斯冲突就全面升级。2015年明斯克协议同样未能约束俄罗斯。默克尔后来承认,明斯克协议在某种程度上只是为乌克兰争取了准备时间。绥靖确实没有让普京停下。

预测3:”中国是最大受益者” ★★★☆☆

部分正确,但有重大保留。

获益面:

  • 以大幅折扣购买俄罗斯石油天然气
  • 中俄关系中中方主导地位更加明确
  • GDP从2014年10.7万亿美元增长到2024年18.7万亿美元

代价面:

  • 中美关系急剧恶化,面临技术脱钩、芯片禁令
  • 被视为俄罗斯”沉默盟友”,在欧洲声誉下降
  • 经济增速从7%+降至~4.5%,房地产危机等内部问题
  • 与美国GDP差距以美元计反而从6.9万亿扩大到10.5万亿

“最大受益者”过于乐观。

预测4:”俄国长远被孤立受伤害” ★★★★☆

基本正确。

2022年后俄罗斯遭受史无前例的制裁:

  • 约3,000亿美元央行外汇储备被冻结
  • 超过1,000家跨国公司撤出
  • SWIFT切断
  • 国际刑事法院对普京发出逮捕令
  • 芬兰、瑞典加入北约(30→32国),”安全缓冲区”反而缩小

但俄罗斯经济在战时体制下并未崩溃,通过中印等国部分规避制裁,韧性超出预期。

预测5:”叙利亚反对派彻底失败” ★☆☆☆☆

严重误判。这是高晓松最大的错误。

  • 2015年俄罗斯直接军事介入后,阿萨德政权确实稳住了
  • 2016-2023年反对派退缩到伊德利卜等有限区域
  • 2024年12月——惊天逆转:反对派发动闪电攻势,12月8日推翻阿萨德政权。阿萨德出逃,反对派组建过渡政府

历史证明,”彻底”二字往往靠不住。

预测6:”等普京时代过去,中国几乎跟美国一样强大” ★★☆☆☆

与现实有较大偏差。

指标 中国(2024) 美国(2024)
GDP(美元计) 18.7万亿 29.2万亿
人均GDP ~1.3万 ~8.5万
军费 ~2,960亿 ~8,860亿

普京仍在位(2024年”连任”至2030年,修宪可执政到2036年)。中美差距以美元计反而扩大,人口老龄化、房地产危机、半导体”卡脖子”等使追赶放缓。

预测7(事实验证):法国军舰交易

交易最终被取消。 2014年9月法国暂停交付,2015年8月正式取消,退款约9.5亿欧元。两艘舰转售埃及。

预测8(事实验证):切尔西与俄国寡头

2022年后遭清算。 阿布拉莫维奇被英国制裁,切尔西以25亿英镑强制出售给美国财团。伦敦”Londongrad”时代终结,大量俄寡头资产被冻结。

预测9(事实验证):苏格兰独立公投

公投举行但独立被否决。 2014年9月18日,55%反对、45%支持。2022年英国最高法院裁定苏格兰无权自行举行第二次公投。

预测10:”不能一方用坦克一方用冰糖雪梨” ★★★★★

极具前瞻性。 2022年后西方政策发生根本转变:

  • 美国援乌超1,150亿欧元,包括防空导弹、HIMARS等
  • 德国设立1,000亿欧元特别国防基金
  • 从”只给防弹衣”升级到提供豹2坦克、F-16战斗机
  • 芬兰、瑞典加入北约

从”冰糖雪梨”转向大规模军事援助——虽然这个觉醒晚了8年。


总体评价

预测 准确度
克里米亚远远没完 ★★★★★
绥靖不会让普京停下 ★★★★★
中国是最大受益者 ★★★☆☆
俄国长远被孤立 ★★★★☆
叙利亚反对派失败 ★☆☆☆☆
中国将与美国一样强大 ★★☆☆☆
西方”冰糖雪梨”无法应对坦克 ★★★★★

高晓松在地缘政治大势上展现了相当敏锐的洞察力——对俄罗斯扩张意图和西方绥靖政策的批评极为准确。主要失误在于对叙利亚的判断(低估历史不确定性)和对中国崛起速度的过于乐观。

12年后回看,他在2014年的分析水准明显超出了当时大多数中文媒体评论者。最核心的判断——“绥靖不会带来和平,克里米亚只是开始”——被2022年的全面战争彻底证实。

0%