分类 技术志 下的文章

日志查询从 70 小时到 10 秒?VictoriaMetrics 联创揭示 PB 级日志处理性能奥秘

本文永久链接 – https://tonybai.com/2025/08/20/large-scale-logging-made-easy

当日志规模达到 PB 级别,传统的关系型数据库(如 PostgreSQL 或 MySQL)往往力不从心,不仅性能急剧下降,运维成本也变得难以承受。在 FrOSCon 2025 大会上,VictoriaMetrics 的联合创始人兼CTO、fasthttp作者、资深 Go 工程师Aliaksandr Valialkin 发表了题为“大规模日志处理变得简单”的演讲,深入剖析了专为日志设计的数据库如何通过一系列精巧的工程设计,实现单机处理 PB 级数据的惊人性能。

本文将和大家一起听演讲,并了解其分享的核心技术——包括列式存储、时间分区、日志流索引和布隆过滤器——并看看为什么这些技术能将日志查询速度从理论上的 70 小时超大幅缩短至 10 秒,以及为何传统数据库在这场竞赛中注定落败。

什么是“大规模日志”?一个与时俱进的定义

在探讨解决方案之前,演讲者 Aliaksandr Valialkin 首先抛出了一个引人深思的问题:究竟什么是“大规模日志”? 业界通常用每日的数据量来衡量,是 GB、TB 还是 PB?然而,这个定义是浮动的。Aliaksandr 提出了一个更具工程实践意义的定义,它将问题从抽象的数字拉回到了具体的物理约束上:

当你的日志无法装入单台计算机时,它就达到了“大规模”。

这个定义的巧妙之处在于,它将“规模”与具体的硬件能力和软件效率紧密地联系起来。一台搭载着普通硬盘、运行着 PostgreSQL 的服务器,可能在处理每日 GB 级日志时就会捉襟见肘。然而,一台配备了高速 NVMe 硬盘、拥有数百 CPU 核心和 TB 级内存的“巨兽”,在运行像 VictoriaLogs 这样的专用数据库时,其处理能力可能是前者的数千倍。在这种情况下,即便是每日 PB 级的日志,也可能不属于“大规模”的范畴。

这个定义为我们接下来的讨论奠定了基础:在诉诸昂贵且复杂的分布式集群(水平扩展)之前,我们是否已经通过选择正确的工具,充分压榨了单机(垂直扩展)的潜力?

单机处理 PB 级日志:一场从 70 小时到 10 秒的性能优化之旅

为了具象化地展示专用日志数据库的威力,演讲者构建了一个思想实验:在一台配备了顶级 NVMe 硬盘(理论持续读取速度 4 GB/s)的 Google Cloud 虚拟机上,查询 1 PB 的日志数据。

起点:暴力扫描 (理论耗时: 70 小时)

如果我们将 1 PB 的原始日志直接存储在硬盘上,并进行一次全盘扫描,理论上需要的时间是:

1 PB / 4 GB/s ≈ 1,048,576 GB / 4 GB/s ≈ 262,144 秒 ≈ 72.8 小时

这在任何生产环境中都是完全无法接受的查询延迟。

第一步:高压缩率带来的飞跃 (理论耗时: 4.6 小时)

专用日志数据库的第一个魔法在于其惊人的数据压缩能力。根据 VictoriaLogs 用户的真实反馈,对于典型的结构化或半结构化日志,压缩比通常在8x 到 50x 之间。

我们取一个相对保守的 16x 压缩比。这意味着 1 PB 的原始日志,可以被压缩到仅有 64 TB 的磁盘空间——这恰好是 Google Cloud 单个虚拟机可挂载的最大磁盘容量。

此时,全盘扫描的时间大幅缩短:

64 TB / 4 GB/s = 16,384 秒 ≈ 4.55 小时

这已经是一个巨大的进步,但对于即时的问题排查来说,仍然太慢。

优化的核心基石:列式存储 (Columnar Storage)

传统关系型数据库(如 PostgreSQL, MySQL)采用行式存储 (Row-oriented Storage)。这意味着一张表中,同一行记录的所有字段(列)在物理上是连续存储的。

[Row1: ColA, ColB, ColC] [Row2: ColA, ColB, ColC] ...

这种存储方式在处理事务性(OLTP)负载时非常高效,因为它能一次性读取或更新整条记录。但对于日志分析这种分析性(OLAP)负载,却是灾难性的。当一个查询只需要分析 ColA 字段时,数据库仍然被迫从磁盘上读取包含 ColB 和 ColC 的完整行数据,造成了大量的 I/O 浪费。

专用日志数据库则借鉴了数据仓库的设计,采用列式存储 (Columnar Storage)

将结构化日志按字段(列)进行拆分,将所有日志中同一个字段的值物理上连续存储在一起。

[ColA: Row1, Row2, ...] [ColB: Row1, Row2, ...] [ColC: Row1, Row2, ...]

这种设计的优势是颠覆性的:

  1. I/O 效率:当查询只涉及 ColA 和 ColB 时,数据库只需读取这两列的数据,完全跳过 ColC,I/O 量可以减少几个数量级。
  2. 压缩效率:同一列的数据具有极高的相似性。例如,log_level 列只包含 “info”, “warn”, “error” 等少数几个值;http_status 列只包含 200, 404, 500 等数字。将这些同质化的数据放在一起,其压缩效果远非混合了各种类型数据的行式存储可比。专用数据库还能根据每列的数据特征(如常量、枚举、时间戳、IP 地址等)自动选择最优的专用编码 (Specialized Codex),进一步提升压缩率,有时甚至能达到上千倍。

回到我们的实验,假设查询只涉及所有日志字段中的一小部分,需要读取的数据量从 64 TB 减少到了 4 TB。查询时间随之骤降至:

4 TB / 4 GB/s = 1024 秒 ≈ 17 分钟

仅仅列式存储还不够,为了避免全列扫描,还需要更智能的数据组织方式。

第二步:按时间分区 (理论耗时: 1 分 40 秒)

日志数据天然带有强烈的时间属性。几乎所有的日志查询都会带上时间范围。专用日志数据库利用这一点,将数据按时间(例如,每小时或每天)进行物理分区。每个分区可以是一个独立的目录或文件。

当一个查询带有 time > T1 AND time < T2 的条件时,数据库可以在查询开始前就完全跳过时间范围之外的所有数据分区,无需读取任何磁盘块。

假设我们的服务保留了 30 天的日志,而我们的查询只关心其中 3 天的数据。需要扫描的数据量等比例减少 90%:

4 TB * (3 / 30) = 400 GB

查询时间进一步缩短至:

400 GB / 4 GB/s = 100 秒 ≈ 1 分 40 秒

第三步:按日志流 (Log Stream) 索引 (理论耗时: 10 秒)

另一个重要的日志维度是其来源。演讲者将“日志流”定义为来自单个应用实例的、按时间排序的日志序列。例如,在一个 Kubernetes 集群中,每个 pod 的每个 container 都会产生一个独立的日志流。

通过为每个日志流(通常由 service, hostname, pod_name 等标签组合定义)建立索引,数据库可以在查询时,只扫描那些与查询条件(例如 service=”api-gateway”)匹配的流。

假设我们的系统中有 1000 个日志流,而查询只涉及其中的 100 个。需要扫描的数据量再次减少 90%:

400 GB * (100 / 1000) = 40 GB

查询时间最终缩短至惊人的:

40 GB / 4 GB/s = 10 秒

我们成功地将一个理论上需要 70 小时的查询,通过一系列精巧的工程设计,在单台机器上优化到了 10 秒以内!

第四步:为“大海捞针”准备的布隆过滤器 (Bloom Filters)

对于需要查找唯一或稀有子串(如 trace_id, user_id, ip_address)的“大海捞针”式查询,全量扫描即使优化后也可能很慢。为此,专用数据库引入了布隆过滤器。

布隆过滤器是一种空间效率极高的概率性数据结构,它可以快速地告诉你一个元素“绝对不存在”“可能存在”于一个集合中。它可能会有误报(说“可能存在”但实际不存在),但绝不会漏报。

通过为每个数据块(block)中的所有词元(word tokens)构建一个布隆过滤器,数据库可以在查询时:

  1. 先检查数据块的布隆过滤器。
  2. 如果过滤器显示目标 trace_id 绝对不存在于此块中,则完全跳过对该数据块的读取和解压

这可以将此类查询的性能再次提升高达 100 倍,实现亚秒级的响应。一个 64 TB 的压缩日志,其布隆过滤器索引的大小可能在 640 GB 到 6.4 TB 之间,这是一个典型的空间换时间策略。

为何传统数据库在海量日志场景中注定失败?

演讲清晰地指出了 PostgreSQL 或 MySQL 在处理大规模日志时的几个根本性缺陷,这些缺陷导致它们无法与专用数据库竞争。

  1. 行式存储的原罪:如前所述,这导致了严重的 I/O 浪费和低下的压缩率。
  2. 随机 I/O 的噩梦:由于缺乏自动的、基于日志特性的物理分区,查询一个时间范围内的特定日志流,在行式数据库中会退化成对磁盘上数百万个不同位置的随机读取。考虑到机械硬盘和 SSD 的随机 I/O 性能远低于顺序读取,这将导致灾难性的性能表现。
  3. B-Tree 索引的“水土不服”
    • 体积庞大:B-Tree 索引的大小通常与数据本身的大小在同一个数量级。对于 PB 级数据,索引本身就需要 TB 级的内存才能高效工作,这在成本上是不可接受的。
    • 不适合分析型扫描:B-Tree 擅长快速定位单条或少数几条记录,但对于需要扫描数百万行的分析型日志查询,其效率远低于专用日志数据库的稀疏索引(例如,仅索引每个数据块的起始/结束时间戳和流 ID)。
  4. 致命的写放大 (Write Amplification):传统数据库为了维护事务性和索引,会频繁地在磁盘上进行小块数据的原地更新(in-place updates)。这在现代 SSD 和 NVMe 硬盘上会触发“读取-修改-写入”的内部操作,一个 4KB 的逻辑写入可能导致 512KB 的物理写入,极其低效且会严重损耗硬盘寿命。而专用日志数据库通常采用仅追加(append-only)的写入模式,数据块一旦写入便不可变,这与现代存储硬件的工作原理完美契合。

日志系统技术选型的建议

在深入探讨了 VictoriaLogs 的设计哲学后,Aliaksandr Valialkin 还在演讲的最后分享了他对当前主流开源日志数据库的看法,并回答了现场观众的提问。这部分内容为我们提供了宝贵的技术选型参考。

主流开源日志数据库横向对比

当决定从传统数据库迁移时,开发者通常面临以下几个选择:

  1. Elasticsearch

    • 优点:功能强大,生态成熟,是全文搜索领域的王者。
    • 缺点:资源消耗巨大,尤其是内存。Aliaksandr 指出,要在 Elasticsearch 中存储 PB 级的日志,“准备好为基础设施花费数千万美元”。其横向扩展的运维复杂度也相对较高。
  2. Grafana Loki

    • 优点:设计理念新颖,只索引元数据(标签),不索引日志内容,旨在降低存储成本。与 Grafana 无缝集成。
    • 缺点:运维和配置相对复杂。更重要的是,它在处理高基数(high cardinality)日志字段(如 trace_id, user_id)时存在性能问题,这正是许多现代可观测性场景的核心需求。
  3. ClickHouse

    • 优点:一个极其快速的开源列式分析数据库,性能卓越。
    • 缺点:灵活性是一把双刃剑。要用好 ClickHouse 存储日志,你需要成为半个专家,深入理解如何正确地设计表结构、选择分区键、设置排序键等,配置门槛较高。
  4. VictoriaLogs (演讲者推荐):

    • 优点:吸收了上述方案的优点,同时致力于简化运维。它内置了所有前面提到的优化技术,并且默认开启,无需复杂配置。其架构设计使其能够轻松处理高基数数据,并实现了从树莓派到大型服务器的平滑扩展,而无需调整配置。

现场 Q&A 精华:深入 VictoriaLogs

现场观众的提问也帮助我们进一步了解了 VictoriaLogs 的一些关键特性和未来规划:

  • Q: 为什么选择Go?

    • A: 在过去十多年里,演讲者主要使用 Go 语言编写代码。Go 是他的首选编程语言。他喜欢 Go,因为Go是一门非常简洁且富有生产力的语言。用 Go 编写高性能的代码很容易,而且与其他之前使用的编程语言相比,Go 的代码通常更容易阅读和维护。演讲者喜欢编写有用的开源软件,并且喜欢让这些软件能够开箱即用,不需要查阅大量文档,也不需要进行复杂的配置。这是许多开源项目所欠缺的一个特性,但演讲者认为它对最终用户至关重要。他喜欢创建为速度和低资源消耗而优化的服务器。这也是他创建 VictoriaMetrics 的原因,它是一个用于指标(也称为时间序列数据)的开源数据库,非常高效和快速。最近,他又创建了 VictoriaLogs,这是另一个专门用于存储日志的数据库。
  • Q: VictoriaLogs 是否提供 UI?

    • A: 是的。它内置了一个用于快速日志调查的 Web UI,并且提供了功能完备的 Grafana 插件,允许用户构建任意复杂的仪表盘。其查询语言是自研的 LogSQL,被设计得比 Loki 的 LogQL 等更强大,支持在单次查询中进行复杂的数据转换和多维度统计计算。
  • Q: 是否支持日志不可篡改(immutability)?

    • A: VictoriaLogs 不支持对已存日志的修改,只支持未来的删除操作(且该功能可被禁用),这在一定程度上保证了数据的不可篡改性。但它目前没有提供基于密码学的签名验证功能。
  • Q: 多租户支持如何?

    • A: VictoriaLogs 原生支持多租户,并且可以轻松处理数万级别的租户,这与 Loki 等因架构设计而在租户数量上受限的系统形成了对比。
  • Q: 对于更大的存储需求(如单个 EC2 实例挂载 450TB 磁盘),你会如何选择?

    • A: 演讲者建议,虽然技术上可行,但他会选择水平扩展。他认为单节点存储的数据量最好有一个平衡点(例如 16TB 的压缩数据),因为过大的单节点会给备份和恢复带来巨大的运维挑战(可能需要数小时)。
  • Q: 未来的路线图是什么?

    • A: 近期最重要的主线功能是支持将历史日志分层存储到对象存储(如 S3)中。系统将能够透明地将冷数据归档到更廉价的存储,并在查询时无缝地拉取,进一步降低成本。至于是否会支持完全无本地磁盘、直接读写对象存储的模式,团队表示会在此功能实现后再做评估,因为需要解决对象存储带来的高延迟问题。

小结:为你的工作选择正确的工具

Aliaksandr Valialkin 的分享为所有处理大规模数据的 Go 开发者提供了清晰、深刻的工程指引:不要试图用一把锤子(通用关系型数据库)去拧所有的螺丝。理解问题的本质,并选择专为该问题设计的工具。

对于日志处理,这意味着:

  • 拥抱专用数据库:当你每天的日志量超过 TB 级别,或者发现现有的日志系统运维成本高昂、查询缓慢时,从 PostgreSQL/MySQL 迁移到像 VictoriaLogs、ClickHouse 或 Loki 这样的专用系统,将带来数量级的成本节约和性能提升。
  • 优先垂直扩展:在投入到复杂且昂贵的水平扩展(分布式集群)之前,先通过使用正确的单机软件,充分压榨现代硬件的潜力。这不仅能节省成本,还能极大地降低运维的复杂性。

正如演讲者所倡导的“小数据”运动理念:许多所谓的“大数据”问题,在正确的工具和架构面前,完全可以在单台计算机上被更简单、更高效地解决。 对于追求性能、效率和简洁性的 Go 开发者而言,这不仅是一次技术分享,更是一堂关于工程哲学的深刻课程。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

Rust 2025 深度解读:在十周年里程碑上,Niko Matsakis 如何擘画下一个时代的灵魂与蓝图?

本文永久链接 – https://tonybai.com/2025/08/18/rust-in-2025

大家好,我是Tony Bai。

2025 年 5 月 15 日,Rust 语言迎来了其 1.0 版本发布的十周年纪念日。这是一个充满里程碑意义的时刻,不仅是对Rust过去十年辉煌成就的回顾,更是展望未来的关键节点。值此之际,Rust 语言团队负责人、核心开发者 Niko Matsakis 发表了一系列题为“Rust in 2025”的纲领性博客文章,系统性地阐述了他个人对 Rust 未来发展的深邃思考。本文将融合 Niko 在十周年庆典上的感言与“Rust 2025”系列的技术蓝图,和大家一起解读一下Niko对下一个时代Rust演进路径的擘画。

回望十年 —— 指引 Rust 航程的两大“北极星”

任何对未来的展望,都必须植根于对过去的深刻理解。在十周年庆典的感言中,Niko Matsakis 将 Rust 的非凡成功,归功于其传奇创始人 Graydon Hoare 从一开始就为这门语言设定的两个坚定不移的“北极星”。它们不仅塑造了 Rust 的技术内核,更铸就了其独特的社区文化。

技术北极星:拒绝妥协,“我们可以拥有好东西”

Graydon Hoare 最初为 Rust 设定的目标是“创建一种‘不会吃掉你衣物’的系统编程语言”。这个看似风趣的目标背后,是一种对行业“常识”的根本性挑战。Niko 将其精炼为一句充满信念的口号:“是的,我们可以拥有好东西 (Yes, we can have nice things)”

这句话的深层含义在于,Rust 拒绝接受在软件开发中长期存在的、看似不可避免的“魔鬼交易”:

  • 性能 vs. 安全: 传统观念认为,要获得 C/C++ 般的极致性能和底层控制力,就必须放弃内存安全,开发者需要像走钢丝一样,为每一个内存操作的正确性负全责。
  • 抽象 vs. 效率: 高级语言如 Java 或 Go 提供了垃圾回收和丰富的抽象,带来了更高的生产力,但在性能敏感的“基础软件”领域,开发者又必须小心翼翼地规避其抽象带来的性能开销,比如 GC 停顿(STW)。

Rust 的技术北极星,就是要在这一点上实现突破。它通过借鉴 C++ 的“零成本抽象”理念,并独创性地引入所有权、借用和生命周期等概念构成的类型系统,实现了编译期的内存安全保证。这使得开发者能够像使用 OCaml 等高级语言一样,编写富有表现力、高度抽象的代码,同时又能获得媲美 C/C++ 的运行性能。这一定位,精准地命中了“基础软件”开发的核心痛点,也成为了 Rust 在过去十年中攻城略地的最强武器。

文化北极星:社区的力量与谦逊的协作

如果说技术北极星定义了 Rust 的“硬实力”,那么文化北极星则塑造了其无与伦比的“软实力”。Niko 强调,Graydon 从项目伊始就认识到构建正确文化的重要性。这份远见卓识,集中体现在由他亲自撰写的《行为准则 (Code of Conduct)》中。

“提供一个友好、安全和欢迎的环境,无论经验水平、性别认同和表达、残疾、国籍或其他类似特征如何……友善和礼貌应被优先考虑……并认识到‘很少有唯一的正确答案’,‘人们有不同意见’,‘每个设计或实现选择都带有权衡’。”

这些条款不仅仅是空洞的口号,它们已经内化为 Rust 社区的行事准则。Niko 坦言,如果没有这种真正开放、尊重的协作氛围,Rust 绝不会是今天的样子。无数伟大的想法——从 Brian Anderson 创造的、沿用至今的 #[test] 语言基础设施,到 Sophia Turner 和 Esteban Kuber 对编译器错误信息的革命性改进——都源于社区成员的自发贡献。

Niko 分享了一个极具代表性的故事,来诠释这种“集体所有”的文化。2024 年,当计算机科学顶级学术组织 ACM 将其 SIGPLAN 软件奖授予 Rust 时,一个难题出现了:获奖名单上应该写谁的名字?核心贡献者们无法达成一致,提出的名单从数千人到“空无一人”。最终,这份荣誉归于一个由领导力委员会决定的名单,并以 “所有过去与现在的 Rust 贡献者” 结尾。

这个故事完美地诠释了 Rust 的成功之道:它是一场由全球成千上万开发者共同参与的、去中心化的伟大协作。这种文化,是 Rust 能够持续进化、不断吸纳新思想的根本保障。

2025 使命 —— 聚焦基础软件,深化语言哲学

在“两大北极星”的持续指引下,Niko Matsakis 在其“Rust in 2025”系列中,为 Rust 的下一个发展阶段确立了更加聚焦的核心使命:显著降低编写和维护“基础软件 (Foundational Software)”的门槛。

所谓基础软件,即“构成其他一切软件基石的部分”。Rust 如今已在这一领域遍地开花:

  • 云原生基础设施: AWS 的几乎所有服务背后都有 Rust 的身影,其 Firecracker 微型虚拟机更是完全由 Rust 构建。
  • 开发者工具链: 从命令行工具到大型构建系统,Rust 正在重塑开发者的工作流。
  • 终端应用与嵌入式: 亚马逊 PrimeVideo 在 Web 端使用 Rust 编译的 WebAssembly 播放视频;在嵌入式领域,Rust 的应用也已“上天入海”。
  • 操作系统内核: Windows 和 Linux 两大主流操作系统内核,都已开始集成 Rust 代码。

为了让 Rust 在这条道路上走得更远,Niko 提出了几个关键的指导原则,它们可以被看作是 Rust 核心设计哲学的深化与具体化。

原则一:人体工程学飞轮 —— 用“拉伸目标”驱动普适性改进

一个有趣的观点是,Niko 认为尽管 GUI(如 Dioxus, Tauri)或 Web 前端(如 Leptos)可能永远不会是 Rust 的“最佳应用场景”,但这些高层应用的探索对 Rust 而言至关重要。

他将此称为“拉伸目标 (Stretch Goals)”。这些项目试图将 Rust 推向其舒适区之外,必然会对其人体工程学 (ergonomics) 提出更高的要求。为了在这些领域与 JavaScript/TypeScript 等语言竞争,Rust 必须变得更简洁、更方便。而这些为了满足高层应用而进行的改进——无论是更强大的宏系统、更灵活的类型系统,还是更智能的编译器——最终会“涓滴”下来,惠及所有 Rust 开发者,包括那些专注于编写内核模块或网络服务的底层系统工程师。这是一个正向的“人体工程学飞轮”。

原则二:全栈覆盖 —— 单一技术栈的生产力红利

Niko 观察到一个趋势:许多团队最初只打算在某个对延迟敏感的特定服务(如 Discord 的数据平面)中使用 Rust,但最终却将其扩展到整个技术栈。原因在于,一旦团队跨过了最初的学习曲线,Rust 的生产力相当可观。使用单一语言可以共享库、工具和知识,从而极大地降低了维护成本和认知负荷。正如 Niko 所说:“简单的代码,无论用何种语言编写,都是简单的。” 确保 Rust 在高层应用中也“足够好用”,是在为用户提供构建全栈应用的能力,这本身就是一个巨大的价值主张。

原则三:“平滑的迭代式深化 (Smooth, iterative deepening)”

这是 Niko 提出的一个核心设计哲学,也是对 Rust 学习曲线问题的直接回应。他理想中的用户体验应该是:

  1. 上手简单: 用户可以快速启动并运行一个简单的项目。
  2. 渐进深入: 当项目变得复杂,用户需要更多控制权时,他们应该能够以一种局部化的方式进行优化或重构,而无需一次性学习大量复杂的背景知识。

这个过程应该是“平滑”的,像走在一个缓坡上,而不是面对一面“悬崖”。许多技术要么上手极难,要么从“简单模式”切换到“专家模式”时需要彻底重写或学习一套全新的概念。Rust 并非总是能完美做到这一点,但这是其持续努力的方向。

技术蓝图 —— 以“可扩展编译器”实现“丝滑互操作”

如果说“赋能基础软件”是战略目标,那么 Niko 提出的技术蓝图就是实现这一目标的具体战术。其核心可以概括为一句话:通过构建一个“可扩展的编译器”,实现“丝滑流畅的语言互操作 (silky smooth language interop)”。

核心问题:基础软件生于一个多语言世界

Niko 清醒地认识到,基础软件的世界是异构的。C 语言长期以来是计算世界的“通用语 (lingua franca)”,而 C++ 则构建了庞大的软件帝国。Rust 若想在这些领域取得成功,就不能成为一个孤岛,而必须成为一个优秀的“连接者”。

注:在成为一个优秀“连接者”的道路上,Go恰恰是做的不够好的那一个!

他将语言互操作的需求分为两大场景:

  • 场景一:最小公分母 (Least Common Denominator, LCD)

    • 目标: “一次编写,多处使用”。比如,用 Rust 编写一个核心业务逻辑库,然后将其打包成 SDK,供 Android (Kotlin)、iOS (Swift)、Web (WASM) 和桌面端调用。
    • 特点: 调用方向主要是单向的(从其他语言到 Rust),暴露的 API 相对简单,易于在不同语言中惯用地表达。
    • 愿景:“语言互操作领域的 serde”。 Niko 提出了一个极具启发性的构想。正如 serde 库定义了一套通用的序列化/反序列化 Trait (Serialize, Deserialize),而具体的数据格式(JSON, YAML 等)则由社区以独立的 crate 实现一样。他也期望能有一个核心的互操作框架,定义通用的 API 规范,然后由社区为不同的目标语言(Python, Java, Swift 等)开发具体的“后端”实现。
  • 场景二:深度互操作 (Deep Interop)

    • 目标: 与某一特定语言进行深度、双向的集成。
    • 特点: 通常发生在用 Rust 逐步替换大型 C++ 或 Java 应用的模块时,或者在像 Linux 内核这样的 C 项目中嵌入 Rust 代码。这需要处理复杂的类型、内存模型和调用约定。
    • 重点:C 和 C++ 是重中之重。 由于历史原因,这两个语言构成了现有基础软件的最大存量。Niko 对 cxx、crubit 等项目以及 Rust 基金会的“Rust-C++ 互操作性倡议”给予了高度评价。

核心解决方案:“可扩展编译器 (The Extensible Compiler)”

如何实现上述宏大的互操作目标?其他语言(如 Swift/Zig 对 C/C++)的做法是,将对特定语言的支持“烘焙 (bake it in)”进编译器。Niko 认为 Rust 应该走一条更具自身特色的道路——构建一个可扩展的编译器

这个构想的本质,是对现有的过程宏(procedural macros)机制进行一次彻底的“超级充电”。目前的过程宏非常强大,但其接口极其简单:“输入一堆 Token,输出一堆 Token”。它对编译器的内部状态一无所知。Niko 设想的未来过程宏(或者说编译器插件)将拥有前所未有的能力:

  1. 检查类型信息: 这是最大的突破。宏将能够查询编译器已经推断出的类型信息,从而做出更智能的代码生成决策。这将彻底改变 ORM、RPC 框架和 FFI 绑定的编写方式。
  2. 按需生成代码: 宏将能够在编译的更后期阶段(如单态化 monomorphization)被调用,根据具体的类型实例化请求来生成代码。这意味着可以避免编译大量永远不会被使用的模板代码,同时能与编译器的优化过程更紧密地集成。
  3. 影响诊断信息和 Lint: 宏将能向编译器提供信息,以生成更贴近用户原始代码的、高质量的错误和警告信息,而不是目前常常出现的、令人困惑的宏展开后代码的错误。
  4. 定制语言规则: 在更遥远的未来,甚至可能允许宏在一定程度上定制方法分发等语言核心行为,为领域特定语言(DSL)的嵌入提供无限可能。

这个“可扩展编译器”的愿景,其影响远不止于语言互操作。它将赋能社区,以 crate 的形式创造出今天难以想象的各种工具和库。Niko 以 F# 的类型提供者 (Type Providers) 为例,展示了这种能力可以如何彻底改变开发者与外部数据源(如数据库、Web API)的交互方式。

注:感叹一下!过程宏如今已经足够复杂了!按这个思路下去,未来将可能更复杂:(,心疼一下过程宏的开发者!不过,对于过程宏的最终用户,也许这能够提供更强大、更智能、更用户友好的功能。

结论 —— 稳定性与进化,无畏地创造未来

“没有停滞的稳定性 (Stability without stagnation)”是 Rust 最重要的价值观。在我看来,一种语言一旦停止进化,它就开始死亡。

Niko Matsakis 的这句话,为整个“Rust 2025”愿景提供了最终的注脚。这份蓝图,正是 Rust 践行“稳定性与进化”并存理念的生动体现。

它同样展现了一种成熟和自信的姿态。Niko 明确表示,我们不需要“Rust 福音派特别行动队 (Rust Evangelism Task Force)”。Rust 的目标不是说服全世界放弃其他语言,而是让 Rust 与其他语言更好地协同工作。当向现有项目添加 Rust 变得异常简单时,它的价值自然会吸引开发者。这是一种基于实力的吸引,而非基于宣传的推广。

在十周年的感言结尾,Niko 也分享了他的个人感悟。作为 Rust 的核心开发者,他们每天面对的是无尽的 Bug、不符合人体工程学的设计和永无休止的 RFC 讨论。有时,这会让人感到沮丧。但他发现,唯一的“解药”,就是走出去和真实的用户交流,去看看大家正在用 Rust 构建的那些令人惊叹的东西。

那一刻,他们会再次记起,这一切的最终目的,是赋能人们去构建和重构我们赖以生存的基础软件。或者,用 Felix Klock 的经典名言来说,就是去“无畏地创造 (hack without fear)”

Rust 的第一个十年,已经证明了其“北极星”的正确性。而“Rust 2025”愿景,则为第二个十年的航程,设定了清晰、务实且激动人心的航向。这场关于 Rust 未来的对话,不仅关乎一门编程语言,更关乎我们如何构建一个更可靠、更高效、更安全的数字世界。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats