MoreRSS

site iconhuizhou | 萝卜修改

Golang 分布式相关的主题,读书笔记
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

huizhou | 萝卜的 RSS 预览

网页图标(Icon)那些事

2025-02-18 11:30:38

Featured image of post 网页图标(Icon)那些事

昨天涛叔的博客 发布了一篇关于友情链接的博客,我毛遂自荐向涛叔请求添加友情链接。涛叔很快回应了我,并且在邮件中友好的提醒我,可以给博客添加一个favicon(icon),这样方便RSS订阅用户快速的区分博客。当时我心想 favicon 是什么?(后端程序员伤不起)

后面我咨询了DeepSeek:
在网页设计中,图标(icon)是一个小而重要的元素。它不仅帮助用户快速识别网站,还能提升用户体验。

常见使用场景:

  • 浏览器标签页:显示在网页标题旁边。
  • 书签栏:用户收藏网页时显示。
  • 主屏幕图标:移动设备将网页添加到主屏幕时显示。
  • PWA(渐进式网页应用):作为应用图标使用。
    比如这样
    在浏览器标签页展示图标
    在浏览器标签页展示图标。
    在书签栏显示图标。
    在书签栏显示图标。

甚至在安卓手机 上,使用chrome浏览器的将网页添加到主屏幕功能。可以显示icon图标。
使用 Android Chrome 将网页添加到手机主屏幕

如何设置

设置icon 最简单的方式是在 网页的 <head> 中添加 一行。

1
<link rel="icon" type="image/png" href="/favicon.png">

如果您是使用 hugo 或者其他工具的话,可能会有favicon的设置。
一些大型网站 比如 google.comapple.com 它们可能需要考虑的问题更多,设置也并不完全一样。

一些需要注意的地方

为了优化使用体验,在各个场景下都达到最佳的显示效果, icon的的尺寸也是有说法。

常见尺寸:

  • 16x16:浏览器标签页图标。
  • 32x32:书签栏图标。
  • 64x64:高分辨率屏幕图标。
  • 180x180:iOS 设备主屏幕图标。
  • 192x192 和 512x512:PWA 图标。
    所以我们在一些网站上会看到设置多个icon 的现象。比如 Hugo官网
    Hugo 官网设置了两个 icon

现代浏览器都支持根据不同的场景,屏幕的PPI 选择不同尺寸的图标,尽量做到所有场景下都达到最好的显示效果。

图标格式的选择

icon 可以使用不同的图片格式,通过 type指定即可,常见的图标格式包括:

  • ICO:传统格式,兼容性好,支持多尺寸。
  • PNG:现代格式,支持透明背景,适合高分辨率屏幕。
  • SVG:矢量格式,无限缩放不失真,适合响应式设计。

多合一 Icon

如果觉得需要维护多个 icon 文件 比较麻烦的话,可以使用多合一icon(Multi-Resolution ICO 或 Multi-Size ICO)是一种包含多种尺寸和色深的图标文件。允许在一个文件中存储多个位图(BMP 或 PNG 格式)。每个位图可以具有不同的尺寸。
ICO 文件包含:

  • 文件头(Header):定义 ICO 文件类型及包含的图像数量。
  • 图像目录(Image Directory):描述每个图像的尺寸、色深、偏移量等信息。
  • 图像数据(Image Data):实际存储图像像素数据。
    浏览器需要一个图标时,它会从 ICO 文件中选择最合适的尺寸。缺点就是包含多个尺寸的 .ico 文件可能会比单个尺寸的文件大。
    本篇文章没有继续深挖,比如 Android Chrome 独有的 manifest.json 苹果设备 apple-mobile-web-app-capable 等。 感兴趣的朋友可以继续深挖。

  • 本文长期链接
  • 如果您觉得我的博客对你有帮助,请通过 RSS订阅我。
  • 或者在X上关注我。
  • 如果您有Medium账号,能给我个关注嘛?我的文章第一时间都会发布在Medium。

【译】Wise工程:2025年技术栈更新

2025-02-13 09:46:39

原文链接:https://medium.com/wise-engineering/wise-tech-stack-2025-update-d0e63fe718c7

Wise工程:2025年技术栈更新

截至2024财年,Wise已经为1280万活跃客户提供服务,每季度处理的跨境转账金额高达300亿英镑。超过60%的转账实现了即时到账,我们的Wise平台为全球银行和非银行机构提供支付服务。这一成就离不开我们以技术为核心的理念、稳健的架构以及专注的工程团队。

Wise的工作方式

Wise在全球主要地点拥有850多名工程师,他们被组织成独立的小组和部落。这些团队被赋予了创新和独立决策的权力,促进了透明度、信任和协作。

本文基于我们2022年的技术栈,涵盖了Wise技术栈的最新改进,帮助我们实现无国界的资金流动——即时、便捷、透明,最终实现免费。

使用Wise转账

我们的网页和移动应用

我们的网页应用基于CRAB(Wise特有的抽象层,构建在流行的Next.js框架之上),包含40个独立的应用程序,每个应用负责特定的产品功能,使得部署更加安全和易于管理。

在测试方法上,我们最大的变化之一是引入了Storybook,用于在开发过程中可视化单个React组件。Storybook与Chromatic配合使用,能够在每次更改后捕获快照,并突出组件的视觉差异。这些快照在代码更改过程中非常有效,帮助我们防止错误影响到客户。

Wise移动应用:更快、更智能、更高效

我们的iOS工程师通过将250多个Xcode模块从Xcodegen迁移到Tuist,并将Cocoapods切换到Swift Package Manager(SPM),升级了基础设施,从而实现了构建缓存的改进。团队还提高了灵活性,将零变更构建时间从28秒减少到2秒。借助先进的构建缓存,开发变得更加顺畅,并朝着使用SPM的Swift可组合架构方向发展。

我们的Android工程师则专注于大规模应用开发。主要Android代码库包含300多个Gradle模块和大约100万行代码,涵盖2个生产应用、6个示例应用、17个JVM模块、221个Android模块和65个多平台模块。我们提高Android开发速度的努力集中在以下几个关键领域:

  • 使用更多的BFFs在Android、iOS和网页团队之间共享代码逻辑。
  • 基于KSP构建代码生成工具。
  • 探索Kotlin多平台的应用。

在用户界面方面,我们已经全面转向Compose——首先用于设计系统,现在用于整个屏幕和导航。我们迅速采用了Kotlin 2.0和2.1版本。为了处理异步任务,我们使用协程和流,而我们的架构遵循标准的MVVM模式,并得到Google的Jetpack库的支持。

后端服务

Wise总共运行超过1000个服务。在后端,我们主要使用Java和Kotlin。自上次更新以来,我们专注于通过开发内部工具来提高自动化和效率,从而加快开发速度,并提供跨不同服务使用的标准库。

更快构建优秀应用

自上次更新以来,我们一直专注于通过自动化代码更新和可扩展的依赖管理解决方案来实现大规模工程。为此,我们:

  • 引入了一个内部微服务底层框架,基于最小配置原则构建,并作为构件发布,使我们能够更快地构建标准微服务。它配置了服务使用的常见功能,提供推荐的默认设置:安全性、可观察性、数据库通信、与Kafka的交互等,使团队能够专注于业务逻辑。
  • 通过内部Gradle插件集合改善构建管道的标准化。一个显著的例子是我们的插件,它标准化了GitHub Actions工作流。这使得通过简单的插件版本更新实现组织范围内的工作流更改变得轻而易举,使得在700多个Java代码库中推出SLSA等倡议变得轻松。
  • 引入了一种语言无关的自动化服务,使我们能够在大规模上对代码库进行复杂更改,并为拥有团队创建拉取请求进行审查。通过使用该服务,我们进一步推进了集中式Java依赖管理平台,通过自动化Java服务的依赖升级。

直接与本地支付系统集成

我们已在菲律宾上线了即时支付系统InstaPay,并获得了加入日本即时支付系统Zengin的许可。我们还获得了巴西PIX的接入权限。

在Wise,我们投入了大量精力来创建尽可能一致的架构,网络通过AWS Transit Gateways集中管理。英国、匈牙利和澳大利亚的物理数据中心集成的细节存在显著差异。我们的澳大利亚数据中心是AWS Outpost Servers的首次部署之一,使我们能够在尽可能多的基础设施中保持一致的AWS工具。

允许企业使用我们的API

我们的公共API允许企业直接集成Wise的跨境支付服务,使用安全的REST API,支持OAuth认证。这为企业提供了转账、货币兑换和账户管理的功能,以及全面的文档和开发者工具,以简化集成过程。

Wise平台支持超过70种货币和多种支付路线,提供无缝的全球连接解决方案。该平台包括内置的合规功能,允许在利用Wise广泛的全球基础设施的同时,实现无缝的跨境操作。

扩展Wise的基础设施平台

为了适应快速增长,我们专注于重建基础设施,以确保效率和灵活性,同时减少团队的运营负担。

引入我们的新Kubernetes支持的计算运行时平台

**计算运行时平台(CRP)**是我们新的可扩展平台,利用Kubernetes,使工程团队能够轻松托管应用程序,而无需管理复杂的基础设施设置。

发展我们的Kubernetes栈

自2018年以来,Wise一直依赖于使用Terraform、JSONNET和ConcourseCI构建的Kubernetes,以支持服务网格控制(Envoy)、PCI-DSS合规性和无摩擦的部署。虽然这一模型为我们提供了良好的服务,但我们需要一种更可扩展和标准化的方法。这就是我们引入CRP的原因:

  • Terraform仍然负责基础设施的配置,但我们从头开始重写了代码库,以提高灵活性和可维护性。
  • RKE2处理集群引导,Rancher管理整体集群状态。
  • Helm取代JSONNET,以提高可维护性和上游兼容性。
  • ArgoCD与自定义插件确保完全自动化的配置和一致性。
  • 我们的Envoy服务代理现在包括服务之间的无缝集成和发现,提高了平台的灵活性、弹性和监督。

因此,我们的Kubernetes集群数量从6个增长到超过20个,同时保持可维护性和效率。

更智能的自动扩展和成本优化

除了更好地配置和维护基础设施的能力外,我们还通过CRP引入了效率改进:

  • 我们正在构建一个灵活的、可选择的自动扩展解决方案,以降低云成本和团队的认知负担。
  • 自动化容器CPU调整大小(通过垂直Pod自动扩展器)现在在非生产环境中上线,并正在向非关键工作负载的生产环境推广。
  • 完全托管的边车容器(如Envoy代理)现在简化了产品团队的部署。
  • 扩展水平扩展,使用KEDA,根据每日和每周的流量模式优化工作负载。

对成本优化的关注使Wise更接近于零任务

构建可扩展、可靠和智能的数据基础设施

在Wise,我们的许多工作都与数据的移动和理解有关。无论是转账、更新实时仪表板,还是为后台的机器学习模型提供动力,我们的系统都在不断处理和分发大量信息。随着我们全球足迹的扩大,我们对更快、更安全和更灵活的数据处理方式的需求也在增加。以下是我们如何发展数据技术栈,以继续为客户提供可靠、便捷和高效的体验的快速概述。

为我们的数据骨干提供动力

在Wise,我们的数据库是我们所有工作的基础之一,因此我们在使其既稳健又易于管理方面投入了大量精力。在幕后,我们的数据库工程师正在解决一些引人入胜的技术挑战,推动金融数据管理的可能性。

  • 我们努力将大部分MariaDB和Postgres工作负载从EC2迁移到Amazon RDS。这一转变减少了维护任务,降低了运营开销,并提供了更强大的安全功能。
  • 同样,我们正在将自托管的MongoDB迁移到MongoDB Atlas,这使我们能够专注于构建新功能,而不是与扩展作斗争。
  • Redis继续为我们的内存工作负载提供支持。
  • 我们还在探索分布式数据库,以实现更大的关系可扩展性。

更智能的工作流编排和可观察性

  • 我们采用了一种名为Temporal的工作流引擎,以自动化关键任务,如切换和恢复测试。这有助于我们将停机时间降至最低,并保持符合严格的弹性法规。
  • 像RDS性能洞察和Percona监控与管理(PMM)这样的工具为我们提供了清晰的数据库运行状况视图,使我们能够及早解决问题。
  • 我们还在尝试使用直接的云SDK来管理我们的基础设施——逐步从Terraform Enterprise转向简化我们的配置流程。

保持数据流动

  • Kafka支撑着我们大多数实时数据的移动——无论是服务之间的异步消息传递、日志收集,还是分析的流式更新。
  • 我们的Kafka集群容量显著增长,并引入了诸如机架感知备用副本等功能,以提高容错能力。
  • 我们的内部数据移动服务帮助将信息从Kafka或数据库引导到Snowflake、S3 Parquet、Iceberg或其他目标。
  • 配置过程中的自动检查减少了人为错误,其日益增长的使用表明团队发现设置新管道变得更简单、更快捷。
  • 另一个内部服务,数据归档,现在在多个数据库中归档超过1000亿条记录。这不仅节省了成本,还使我们的数据库更易于备份和恢复。

将数据转化为洞察

Wise各团队使用我们的商业智能工具做出战略性、数据驱动的决策,以提升客户体验——从欺诈检测到个性化营销和预测分析。

  • 尽管我们仍然依赖Snowflake作为分析的核心组成部分,但我们已经在Amazon S3上建立了数据湖的基础,使用Apache Iceberg。得益于其强大的开放表格式,Apache Iceberg使我们能够更高效地在S3上存储大量数据。它允许我们在不需要重写所有数据的情况下修改表结构,从而加快查询速度并控制存储成本。此外,其活跃的开源社区不断推动改进,惠及我们的长期可扩展性。
  • 在我们的数据源和商业智能工具之间是Trino,它使我们能够在一个地方查询Iceberg表、Snowflake或甚至Kafka流。
  • 一个新的Trino网关处理工作负载分离和容错查询,而复杂的工作流仍由Airflow和dbt-core管理。有关此主题的深入了解,请观看我们数据工程师最近的会议演讲
  • 报告和仪表板使用Looker或Superset构建——团队选择最适合的工具集。

推动智能解决方案

我们的机器学习架构旨在支持探索和生产,无缝集成机器学习功能到产品中,以改善客户入职和欺诈预防,并利用负责任的人工智能技术。

  • 我们的数据科学家在Amazon SageMaker Studio中工作,选择JupyterLab或VSCode来构建实验和探索数据。
  • 大规模处理在EMR上使用Spark进行,而Airflow则协调数据收集、清理、模型训练和定期再训练,以保持每个步骤按计划进行。
  • 我们使用SageMaker特征存储来保持数百个特征在训练和推理中的同步,MLflow跟踪实验、指标和模型版本。这种设置简化了模型变体的比较或在需要时的回滚。
  • 当模型准备好投入生产时,我们通过基于Ray Serve的内部预测服务进行部署。
  • 多亏了MLflow插件,我们的数据科学家可以以最小的摩擦推出模型——加快欺诈检测、KYC或其他用例的推理时间,在这些情况下每毫秒都至关重要。
  • 自动检查有助于在数据漂移或特征不一致变成严重问题之前捕捉到它们。

解锁新的人工智能能力

我们创建了一个安全的网关,连接多个大型语言模型提供商,包括Anthropic(Claude)、AWS(Bedrock)、Google(Gemini)和OpenAI(gpt和o系列)。这种方法使我们能够在不处理单独凭证或复杂合规检查的情况下实验不同的模型。一个受LangChain启发的Python库封装了这些API,以加快原型设计。

对于需要引用内部文档、知识库或用户数据的情况,我们提供了一个自定义的检索增强生成(RAG)服务。它在生成响应之前从各种数据存储中提取最新信息——这是总结复杂文档或自动化客户服务工作流的便捷功能。

智能数据管理

我们的数据架构既庞大又复杂,因此我们建立了一个全面的库存系统和专门的治理门户,以显示数据存储的位置及其分类。

我们已在整个数据资产中实现了自动化数据发现,以了解创建了什么数据;谁创建了它;以及数据的类别是什么。我们正在利用我们的数据库存来支持数据删除、数据合规和数据发现的工作。这种设置不仅支持审计和法规的合规工作,还提高了开发者的生产力。

随着越来越多的工程师加入治理工作,我们能够推出更严格的政策、增强的隐私检查和自动化的数据生命周期管理。

开发者赋能——Wise的CI/CD演变

为了加强我们的交付管道和开发者体验,我们不断发展我们的CI/CD平台,以使开发者能够比以往更快、更可靠地将功能交付给客户。

CI改进:速度和安全性

从CircleCI迁移到GitHub Actions带来了优化的新可能性。通过实施详细的指标跟踪,我们发现了构建性能的关键见解。例如,通过预填充常用容器的缓存,我们将构建时间缩短了15%在我们每月50万次构建的规模下,这相当于每月节省超过1000小时。

我们一直在有条不紊地在我们的构建过程中实施SLSA框架,逐步加强我们的供应链安全。

CD转型:从Octopus到Spinnaker

在我们之前的文章中提到的CI/CD管道状态之后,我们的部署策略随着从Octopus(我们的内部工具)转向Spinnaker而发生了变化。这不仅仅是工具的更换——它代表了一种范式转变,从将部署视为简单的事务转变为将其视为有序事件序列。

这一转变使我们能够减少工程师在部署管理上花费的时间,并最小化缺陷到达客户的风险。这提高了开发者的交付速度,使我们能够更快地为客户提供服务,而不牺牲质量和稳定性。

高级金丝雀测试

Spinnaker的自动金丝雀分析已成为我们部署管道的基石。该过程在其简单性中优雅而强大:

  • 仅5%的流量路由到新服务版本进行测试
  • 对技术和业务指标进行全面的30分钟分析
  • 对重大异常触发自动回滚

因此,仅在2024年,这一系统自动阻止了数百次可能导致事件的部署,节省了数千小时的工程时间。

目前,Wise的超过一半服务已在Spinnaker上运行,预计到2025年中期将完成全面迁移,我们准备迈出下一步:实施托管交付,以协调整个SDLC,包括测试和数据管理。

LGTM堆栈的可观察性

我们改善了可观察性生态系统,以更好地监控、理解和优化Wise产品。可靠性工程师专注于构建一个更强大、高效和富有洞察力的可观察性平台,以应对我们快速扩展环境中的关键挑战。

专用的可观察性基础设施

我们实施了专用的可观察性CRP集群。这为在不同环境中运行的服务提供了开箱即用的可观察性。因此,我们简化了监控设置,减少了手动配置的负担。

统一的指标和监控堆栈

为了解决可扩展性问题,我们已从Thanos迁移到Grafana Mimir。这意味着我们现在完全运行在LGTM堆栈上:Loki用于日志,Grafana用于仪表板和可视化,Tempo用于跟踪,Mimir用于指标。作为我们在可观察性方面持续改进的一部分,我们正在试点测试Grafana Pyroscope,以对选定服务进行分析,探索性能洞察和优化的新维度。
我们的指标堆栈每秒接收约600万个指标样本,并处理我们最大指标租户的1.5亿个活动系列。
通过统一我们的堆栈,我们:

  • 在整个技术生态系统中标准化可观察性。
  • 增强日志、指标、跟踪和仪表板之间的关联。
  • 改善监控基础设施的性能和可扩展性。

可观察性的成本优化和效率

最后,我们继续投资于优化我们的可观察性堆栈。我们能够降低运营成本,提高资源利用率,并最终拥有更可持续的长期可观察性战略。请查看我们之前的文章,详细介绍了我们在这些倡议上所做的工作。

这一战略演变使我们的工程团队能够获得更深入、更具可操作性的洞察,同时确保我们的可观察性基础设施既强大又具有成本效益。

结论

总之,我们2025年的技术栈证明了Wise如何引领潮流,为全球1280万活跃客户提供最快、最可靠和最具成本效益的资金转移方式。对标准化和集成的高度关注意味着我们的系统旨在高效扩展,同时确保稳健的风险和合规管理。

我们的工程团队继续在所有领域精炼我们的基础设施,从移动和网页应用到后端服务和机器学习。这些努力简化并加速了跨境资金流动,确保我们为当前需求和未来增长做好准备。

我们致力于长期投资,构建最佳基础设施,以无缝管理您在全球范围内的资金。随着每一次技术增强和与支付系统的新直接连接,我们正稳步朝着实现无国界资金流动的愿景迈进。

Go1.24: mutex自旋优化,最大提升70%的性能

2025-02-11 11:16:36

Featured image of post Go1.24: mutex自旋优化,最大提升70%的性能

背景

Rhys Hiltner 在 2024 年提出了改进互斥锁的性能优化诉求。现在这个优化已经合并到即将发布的Go1.24中,在锁竞争激烈的场景下最多会提升70%的性能。
source https://github.com/golang/go/issues/68578

在基准测试 ChanContended 中,作者发现随着 GOMAXPROCS 的增加,mutex 的性能明显下降。
Intel i7-13700H (linux/amd64):

  • 当允许使用 4 个线程时,整个进程的吞吐量是单线程时的一半。
  • 当允许使用 8 个线程时,吞吐量再次减半。
  • 当允许使用 12 个线程时,吞吐量再次减半。
  • GOMAXPROCS=20 时,200 次channel操作平均耗时 44 微秒,平均每 220 纳秒调用一次 unlock2,每次都有机会唤醒一个睡眠线程。
    另一个角度是考虑进程的 CPU占用时间。
    下面的数据显示,在 1.78 秒的Wall-Clock Time内,进程的20个线程在lock2调用中总共有27.74秒处于CPU(自旋)上。

这些 lock2 相关的线程并没有休眠,而是一直在自旋,这将消耗大量的CPU资源。

新提案:增加spinning状态

通过上述的分析,作者发现在当前的lock2实现中,虽然理论上允许线程睡眠,但实际上导致所有线程都在自旋,导致了更慢的锁传递,带来了不少的性能损耗。
于是提出了新的设计方案《Proposal: Improve scalability of runtime.lock2》

核心优化点

mutex 的状态字添加了一个个新的标志位,称为 “spinning”

1
2
3
4
5
6
7
https://github.com/golang/go/blob/608acff8479640b00c85371d91280b64f5ec9594/src/runtime/lock_spinbit.go#L57
const (
	mutexLocked = 0x001
	mutexSleeping = 0x002
	mutexSpinning = 0x100
	...
)

使用这个 spinning位来表示是否有一个等待的线程处于 “醒着并循环尝试获取锁” 的状态。线程之间会互相排除进入 spinning状态,但它们不会因为尝试获取这个标志位而阻塞。

metux 的介绍可以参考以前的文章
https://pub.huizhou92.com/go-source-code-sync-mutex-3082a25ef092

Mutex 获取锁分析

1. 快速路径尝试获取锁

1
2
3
4
5
6
7
8
9
//https://github.com/golang/go/blob/adc9c455873fef97c5759e4811f0d9c8217fe27b/src/runtime/lock_spinbit.go#L160
k8 := key8(&l.key)
v8 := atomic.Xchg8(k8, mutexLocked) 
if v8&mutexLocked == 0 {
    if v8&mutexSleeping != 0 {
        atomic.Or8(k8, mutexSleeping)
    }
    return
}

fast 模式跟以前变化不大。如果成功(锁之前未被持有)则快速返回。这是最理想的情况,无竞争时的快速路径。

2. 自旋等待阶段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//https://github.com/golang/go/blob/adc9c455873fef97c5759e4811f0d9c8217fe27b/src/runtime/lock_spinbit.go#L208
if !weSpin && v&mutexSpinning == 0 && atomic.Casuintptr(&l.key, v, v|mutexSpinning) {
    v |= mutexSpinning 
    weSpin = true
}

if weSpin || atTail || mutexPreferLowLatency(l) {
    if i < spin {
        procyield(mutexActiveSpinSize)  //主动自旋
        // ...
    } else if i < spin+mutexPassiveSpinCount {
        osyield() //被动自旋
        // ...
    }
}
  • 如果快速路径失败,进入自旋等待阶段。
  • 通过 mutexSpinning 标志控制同时只允许一个 goroutine 自旋
  • 自旋分为procyield与osyield,两者的区别是:procyield会持续占有CPU,响应会更快,适合极短时间的等待,osyield会临时释放CPU,响应较慢,但是不会占用较多CPU,适用于较长时间的等待。
    这种两阶段自旋设计能够在不同竞争强度下都保持较好的性能表现。
  • 轻度竞争时主要使用主动自旋,保证低延迟
  • 重度竞争时快速进入被动自旋,避免CPU资源浪费

休眠等待阶段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//https://github.com/golang/go/blob/adc9c455873fef97c5759e4811f0d9c8217fe27b/src/runtime/lock_spinbit.go#L231
// Store the current head of the list of sleeping Ms in our gp.m.mWaitList.next field
gp.m.mWaitList.next = mutexWaitListHead(v)

// Pack a (partial) pointer to this M with the current lock state bits
next := (uintptr(unsafe.Pointer(gp.m)) &^ mutexMMask) | v&mutexMMask | mutexSleeping
if weSpin {
    next = next &^ mutexSpinning
}

if atomic.Casuintptr(&l.key, v, next) {
    weSpin = false
    semasleep(-1)
    atTail = gp.m.mWaitList.next == 0
    i = 0
}

如果自旋失败,goroutine 将进入休眠等待,然后将当前 M 加入等待队列(通过 mWaitList 链表),通过信号量(semasleep)使当前 goroutine 进入休眠,等待持有锁的 goroutine 在解锁时唤醒。

当某个线程解锁互斥锁时,如果发现已经有线程处于 “醒着并旋转” 的状态,就不会唤醒其他线程。在 Go 运行时的背景下,这种设计被称为 spinbit
这个设计的核心目的是:通过让一个线程负责 “旋转尝试获取锁”,避免所有线程都同时竞争资源,从而减少争用和不必要的线程切换

效果

 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
goos: linux
goarch: amd64
pkg: runtime
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
                │     old     │                  new                  │
                │   sec/op    │    sec/op     vs base                 │
ChanContended      3.147µ ± 0%    3.703µ ± 0%   +17.65% (p=0.000 n=10)
ChanContended-2    4.511µ ± 2%    5.280µ ± 7%   +17.06% (p=0.000 n=10)
ChanContended-3    5.726µ ± 2%   12.125µ ± 2%  +111.75% (p=0.000 n=10)
ChanContended-4    6.574µ ± 1%   13.356µ ± 4%  +103.16% (p=0.000 n=10)
ChanContended-5    7.706µ ± 1%   13.717µ ± 3%   +78.00% (p=0.000 n=10)
ChanContended-6    8.830µ ± 1%   13.674µ ± 2%   +54.85% (p=0.000 n=10)
ChanContended-7    11.07µ ± 0%    13.59µ ± 2%   +22.77% (p=0.000 n=10)
ChanContended-8    13.99µ ± 1%    14.06µ ± 1%         ~ (p=0.190 n=10)
ChanContended-9    16.93µ ± 2%    14.04µ ± 3%   -17.04% (p=0.000 n=10)
ChanContended-10   20.12µ ± 4%    14.12µ ± 1%   -29.80% (p=0.000 n=10)
ChanContended-11   23.96µ ± 2%    14.44µ ± 3%   -39.74% (p=0.000 n=10)
ChanContended-12   29.65µ ± 6%    14.61µ ± 3%   -50.74% (p=0.000 n=10)
ChanContended-13   33.98µ ± 7%    14.69µ ± 3%   -56.76% (p=0.000 n=10)
ChanContended-14   37.90µ ± 1%    14.69µ ± 3%   -61.23% (p=0.000 n=10)
ChanContended-15   37.94µ ± 4%    14.89µ ± 5%   -60.75% (p=0.000 n=10)
ChanContended-16   39.56µ ± 0%    13.89µ ± 1%   -64.89% (p=0.000 n=10)
ChanContended-17   39.56µ ± 0%    14.45µ ± 4%   -63.47% (p=0.000 n=10)
ChanContended-18   41.24µ ± 2%    13.95µ ± 3%   -66.17% (p=0.000 n=10)
ChanContended-19   42.77µ ± 5%    13.80µ ± 2%   -67.74% (p=0.000 n=10)
ChanContended-20   44.26µ ± 2%    13.74µ ± 1%   -68.96% (p=0.000 n=10)
geomean            17.60µ         12.46µ        -29.22%


source https://github.com/golang/go/issues/68578#issuecomment-2256792628

虽然在竞争较少的情况下,性能有降低,但是在竞争比较多的地方性能提升显著。平均来说,大约获得 29%的性能提升。期待后续能够优化这种情况吧。

mutex本次修改没涉及API层面改动,所以只要等 Go1.24 正式发布就能自动使用了。该特性通过GOEXPERIMENT=spinbitmutex 来控制,默认是开启的,也可以将它关闭,来使用原来的Mutex。


  • 本文长期链接
  • 如果您觉得我的博客对你有帮助,请通过 RSS订阅我。
  • 或者在X上关注我。
  • 如果您有Medium账号,能给我个关注嘛?我的文章第一时间都会发布在Medium。

go_fix 自动化代码迁移的全新利器

2025-02-08 15:05:21

Featured image of post go_fix 自动化代码迁移的全新利器

œ
随着项目规模不断扩大,代码库的维护与更新变得越来越繁琐。每当某个函数、常量或包路径需要替换时,手动查找和修改不仅费时费力,还容易出错。幸运的是,Go 语言在不断进步,最新接受的提案 go:fix工具为开发者提供了一种自动化迁移的解决方案。本文将带你从浅入深地了解 go:fix 的原理、应用场景以及具体使用示例。

一、go:fix 背景简介

在日常开发过程中,API 的弃用与替换是不可避免的。举例来说,当一个函数被标记为弃用时,我们可能希望所有对该函数的调用都替换为新的实现;当一个常量被重命名或迁移到其他包中时,我们也希望工具能够自动更新所有引用。 #32816 提出的这一方案正是为了实现这样的目标——通过在代码中添加特定指令,实现简单弃用项的自动迁移。

go:fix 工具主要通过两种机制完成自动化迁移:

  1. 函数内联(Inlining)
  2. 常量转发(Forwarding)
    接下来,我们将详细介绍这两种机制及其使用示例。

二、函数内联与常量转发

1. 函数内联(Inline Functions)

当一个函数被标记为需要内联时(例如通过 //go:fix inline 注释),go:fix 会自动将对该函数的调用替换为其函数体内的实现。这种机制常用于两种场景:

  • 弃用函数的替换:当某个函数不再推荐使用时,可以直接将其内部逻辑迁移到新函数。例如:
    1
    2
    3
    4
    5
    
    // Deprecated: prefer Pow(x, 2).
    //go:fix inline
    func Square(x int) int {
        return Pow(x, 2)
    }
    

如果代码中存在对 Square 的调用,工具会自动替换为 Pow(x, 2),从而逐步淘汰旧函数。

  • 包迁移:在包升级或重构过程中,可能需要将原先某个包中的函数调用替换为新包中的实现。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    
    package pkg
    
    import pkg2 "pkg/v2"
    
    //go:fix inline
    func F() {
        pkg2.F(nil)
    }
    

    这样,调用 pkg.F() 的代码将自动更新为 pkg2.F(nil),简化包路径更新的过程。

2. 常量转发(Forward Constants)

常量转发机制适用于常量重命名或跨包迁移的场景。只需在常量定义前添加 //go:fix forward 注释,工具便能将所有对该常量的引用替换为其目标常量。例如:

1
2
3
4
package example

//go:fix forward
const Ptr = Pointer

如果其他地方有如下调用:

1
fmt.Println(example.Ptr)

运行 go:fix 工具后,该调用会被替换为:

1
fmt.Println(example.Pointer)

此机制不仅支持单个常量,也可以对常量组同时生效。

三 go:fix 的优势与挑战

优势

  • 低风险迁移:自动替换确保新旧代码行为一致,降低因手动修改引入错误的风险。
  • 提高开发效率:通过自动化工具处理重复性修改任务,开发者可以将更多精力投入到核心业务逻辑中。
  • 一致性更新:确保代码库中所有弃用项都被统一更新,避免遗漏。
  • 无缝集成:GoFix 与 gopls(Go 语言服务器协议)等工具紧密集成,提供实时反馈,方便开发者及时发现和修正问题。

挑战

  • 复杂场景处理:对于一些特殊情况(例如常量组、iota 的用法)需要特别处理。
  • 跨包依赖:当替换项来自不同包时,可能涉及更多细节问题,需要确保新包的导入和引用正确。
  • 非确定性行为:工具在处理 map 遍历等非确定性场景时,需要特别注意替换的一致性。

四、结语

go:fix 的引入为Go语言的自动化代码迁移带来了新的可能性。通过简单的注释指令(如 //go:fix inline//go:fix forward ),开发者可以轻松实现对弃用函数、常量甚至包路径的自动替换,从而保持代码库的现代性和一致性。无论是大规模重构,还是逐步淘汰旧 API,go:fix 都能为你的项目维护工作提供极大的便利。

随着工具的不断完善和更多社区反馈的积累,相信未来 go:fix 能够覆盖更多复杂场景,进一步提升 Go 开发的生产力。如果你也在为手动修改代码而烦恼,不妨期待一下这款新工具,体验自动化带来的高效与便捷。

五、参考资料

https://github.com/golang/go/issues/32816
https://github.com/golang/tools/blob/master/gopls/internal/analysis/gofix/doc.go


  • 本文长期链接
  • 如果您觉得我的博客对你有帮助,请通过 RSS订阅我。
  • 或者在X上关注我。
  • 如果您有Medium账号,能给我个关注嘛?我的文章第一时间都会发布在Medium。

【译】如何通过 Google Spanner 实现万亿级数据存储与5个九的高可用性

2025-02-06 10:01:23

原始链接 https://blog.bytebytego.com/p/how-google-spanner-powers-trillions | 作者 ByteByteGo

免责声明:本文中的所有细节均来源于 Google 博客和研究论文,所有技术细节的原始版权均归 Google 工程团队所有。文末附有原始文章的链接。我们对这些细节进行了分析并提供了我们的解读。如果您发现任何不准确或遗漏之处,请留言,我们会尽力修正。

Google Cloud Spanner 是 Google 开发的一款革命性数据库系统,它巧妙地将传统关系型数据库的优势与 NoSQL 系统通常具备的可扩展性相结合。

专为跨多个区域处理海量工作负载而设计,Cloud Spanner 提供了一个全球分布、强一致性且高可用的数据管理平台。其独特之处在于,它既支持 SQL 查询和关系型数据结构,同时又实现了水平扩展能力,使其能够满足现代高负载应用的需求。

Cloud Spanner 的主要特性

  • 多版本数据库 采用同步复制技术,即使在区域故障的情况下也能保证数据的持久性与可用性。
  • TrueTime 技术 整合了 GPS 和原子钟,提供全球一致的时间线
  • 简化数据管理 提供熟悉的 SQL 接口,同时在后台处理分布式数据处理的复杂性。
  • 数据切分与动态分片 将数据按照连续的键范围(称为 splits)进行分区,并根据负载或数据量动态调整分片以优化性能。

总体而言,Google Spanner 为需要支持全球规模操作,同时保持传统关系型系统的稳健性和可靠性的企业提供了一种极具竞争力的数据库解决方案。

在本文中,我们将深入探讨 Google Cloud Spanner 的架构,以及它如何支持构成这一出色数据库选项的各项能力。

Cloud Spanner 架构概述

Spanner 的架构旨在支持其作为一个全球分布、强一致性及高可用性数据库的角色。

在最高层次上,Spanner 被组织为一个被称为 “Universe” 的逻辑实体,该实体跨越多个物理或逻辑位置,这些位置被称为“区域(zones)”。

每个区域都具有一定的独立性,并包含专用的 spanservers。这些服务器负责数据存储和事务处理,基于 Google 早期分布式存储系统 Bigtable 的概念,并在此基础上进行了增强以支持复杂事务和多版本数据。

架构图

关键架构组件

Cloud Spanner 通过将数据划分成更小的单元来进行管理,这些单元称为 tablets,并分布在多个 spanservers 上。

  • Tablets:每个 tablet 存储键值对数据,并附带时间戳用于版本控制。这种结构使得 Spanner 成为一个多版本数据库,能够根据需要访问数据的旧版本。
  • Colossus 文件系统:Tablets 存储在 Colossus 上,这是 Google 的分布式文件系统。Colossus 提供了容错性和高性能存储,使得 Spanner 能够实现存储与计算资源的独立扩展。
  • Splits:表中的数据依据连续的键值范围进行划分,这些范围称为 splits。当某个 split 变得过大或流量过高时,系统会自动将其分割成更小的部分并重新分布到不同的 spanservers,这一过程称为动态分片(dynamic sharding)。
  • 跨区域复制:每个 split 都会在多个区域间进行复制,以实现冗余和故障容错。

为了保证数据一致性,Spanner 采用了 Paxos 共识算法来管理跨区域的复制。每个 split 都有多个副本,Paxos 算法确保这些副本保持一致性。

  • Leader选举:在这些副本中,一个副本被选为领导者,负责处理该 split 的所有写事务,确保更新以一致的顺序进行。如果领导者出现故障,Paxos 会自动选举出新的领导者,从而在无需人工干预的情况下保持系统可用性。同时,非领导者副本可以处理读操作,从而减轻领导者的负载并提高扩展性。

数据分片与复制

Spanner 实例通常跨越某一地区内的多个区域,并将副本分布在这些区域中。这样的架构提高了系统的可用性,因为即便某个区域发生故障,其他区域仍能继续处理请求。对于全球部署,还可以将数据复制到不同大陆,以便为全球用户提供低延迟访问。

所有数据均存储在 Colossus 上,该系统为分布式、复制的文件存储而设计,通过在多台物理机器间复制数据来确保高耐久性,从而在硬件故障时能够恢复数据。文件系统与计算资源分离,使得数据库可以独立扩展并高效运行。

Colossus 文件系统

Paxos 共识机制

Paxos 是 Spanner 架构中的核心组件之一。其基本原理是通过分布式共识,让一组副本(称为 Paxos 组)就一个值(例如某事务的提交或负责更新的领导者)达成一致。

Paxos 架构图

领导者分配机制

  • 每个数据 split(即连续键范围)都关联有一个横跨多个区域的 Paxos 组。
  • 在 Paxos 组中,一个副本被指定为领导者,该领导者负责处理该 split 的所有写操作,从而保证更新协调一致。
  • 其他副本作为跟随者,不仅帮助分担读操作的负载,还为系统的扩展性做出贡献。

Paxos 领导者的主要职责包括:

  • 处理写操作:领导者接收写请求,并确保这些请求在多数副本确认后才进行提交,从而确保数据的持久性和一致性,即便部分副本出现故障。
  • 维护顺序:通过 TrueTime 为事务分配时间戳,确保写操作按照全局一致的顺序执行。
  • 与跟随者通信:领导者向跟随者广播提案,并收集确认信息来协调更新。

即使在分布式系统中不可避免会出现故障,Paxos 机制也能确保 Spanner 在面对这些问题时依旧保持可用性与一致性。若当前领导者因机器或区域故障而失效,Paxos 组将检测到这一情况并选举出新的领导者,从而避免系统停机。

事务处理机制

Cloud Spanner 使用强大而稳健的事务处理方法,确保数据一致性、可靠性和高性能。下面介绍写事务和读事务的工作原理:

写事务

写事务确保了原子性(全有或全无)和一致性(所有副本数据一致),由 Paxos 领导者协调处理,即便在出现故障时也能保证数据完整性。其基本步骤如下:

  1. 加锁:在修改数据之前,负责该 split 的 Paxos 领导者会对相关行加写锁。如果另一事务已持有冲突锁,则当前事务需等待锁释放。
  2. 通过 TrueTime 分配时间戳:利用 TrueTime 为事务分配全局一致的时间戳,该时间戳总是大于之前任何已提交事务的时间戳,从而保证时间顺序的一致性。
  3. 多数副本复制保证持久性:领导者在加锁并分配时间戳后,会将事务细节发送给 Paxos 组中超过半数的副本。只有在多数副本确认后,事务才被认为已提交,确保即便部分副本故障,数据也能得到持久保存。
  4. 提交等待:领导者会等待一个短暂的时段,确保提交时间戳对所有副本均已生效,然后再最终提交事务,使得后续所有读取操作都能反映该变更。

对于单个 split 内的写操作,例如用户希望在表中添加一个 ID 为 7、值为 “Seven” 的行:

  • Spanner API 会确定 ID 7 所在的 split,并将请求发送至该 split 的 Paxos 领导者。
  • 领导者对 ID 7 加锁、分配时间戳,并将变更复制给多数副本。
  • 在确保时间戳生效后,事务提交,所有副本应用该变更。

而对于涉及多个 split 的写操作(例如修改多个 split 中的 ID 2000、3000 和 4000),Spanner 则采用两阶段提交协议:

  • 每个参与的 split 都成为事务的参与者,其中一个 split 的领导者担当协调者角色。
  • 协调者确保所有参与者都已加锁并同意提交事务,然后再进行下一步操作。
  • 在所有参与者确认后,协调者提交事务,并通知其他参与者应用变更。

读事务

读事务经过优化,可在高负载下提供高性能的强一致性读取,同时无需加锁。

  • 强一致性读取:这类读取始终返回最新的已提交数据。系统通过 TrueTime 检查数据最新的时间戳,确保返回的数据是最新状态。例如,当客户端请求读取 ID 为 1000 的行时,系统会路由该请求至某个副本,并在返回结果前与领导者确认数据的最新性。
  • 陈旧读取:允许在一定程度上返回稍微过时的数据(例如最多延迟 10 秒),以换取更低的延迟。客户端在请求时,可以直接从副本读取数据,而无需等待领导者确认,从而加速响应。

下面的图示展示了强一致性读取的场景:

强一致性读取

而下图则展示了陈旧读取的场景:

陈旧读取

为了避免死锁——即多个事务相互等待释放锁的情况——Spanner 采用了 wound-wait 算法。其基本规则如下:

  • 如果一个较晚启动的(年轻的)事务请求被较早启动(较老)的事务所持有的锁,则该年轻事务等待。
  • 如果较老事务请求较年轻事务所持有的锁,则较年轻事务会被 “wound” (即中止),以便较老事务继续执行。
  • 这种策略确保事务始终能够推进,避免形成死锁循环。

Spanner 的设计确保了数据即使在故障情况下也能保持一致性和可用性。所有写操作的数据均存储于 Google 的 Colossus 分布式文件系统中,该系统通过将数据复制到多台物理机器上,即使部分机器或区域出现故障,也能从其他副本中恢复数据。TrueTime 则确保了在分布式环境中事务的全局一致排序,保证一旦某事务对一个客户端可见,则对所有客户端均可见。

TrueTime 技术

TrueTime 是 Cloud Spanner 的一项关键创新,使其能够作为一个全球分布、强一致性的数据库运行。TrueTime 解决了分布式系统中最具挑战性的问题之一:如何在分布于多个区域和数据中心的节点间提供全球同步和一致的时间视图。

TrueTime 基于原子钟和 GPS 时钟的组合工作,二者协同提供高度准确和可靠的时间同步:

  • 原子钟:基于原子振动频率计时,提供极高精度、漂移极小的时间测量。在 GPS 信号中断或不准确时,原子钟能保证时间的准确性。
  • GPS 时钟:依靠卫星信号提供准确的全球同步时间。但 GPS 系统可能会遇到干扰、天线故障,甚至伪造攻击的问题。

TrueTime 不将时间表示为单一的点,而是表示为一个时间区间,明确体现了分布式系统中固有的不确定性:

  • TTInterval:TrueTime 提供一个时间范围 [earliest, latest],保证实际的全球时间落在此区间内。区间宽度由时钟漂移和网络延迟等因素决定。
  • 误差范围与同步:通过大约每 30 秒与时间主机(原子钟和 GPS 时钟)同步一次,系统可将不确定性区间保持在一个较小的范围内(通常在 10 毫秒以内)。

TrueTime 具有以下重要特性,使其在分布式数据库中发挥关键作用:

  • 全局外部一致性:确保所有副本中事务以相同的全局顺序进行序列化。例如,如果某事务提交早于另一事务开始,TrueTime 能保证时间戳反映这种全局顺序。
  • 无锁读取事务:允许 Spanner 执行无锁的只读请求,这些事务可以在不加锁的情况下访问数据的一致快照,从而提升系统扩展性和性能。
  • 原子模式更新:在分布式系统中,模式更改(如修改表结构)通常十分复杂。TrueTime 将模式更新视为具有特定时间戳的事务,确保所有服务器一致地应用更改。
  • 历史数据读取:TrueTime 允许基于指定时间戳读取数据的一致快照,方便进行审计或调试。

总结

Google Spanner 在数据库工程领域是一项重大突破,它完美地将传统关系型数据库的可靠性和结构性与 NoSQL 系统的可扩展性和全球可用性相结合。通过创新的架构设计,依靠 Paxos 共识机制以及 TrueTime 技术,Spanner 能够高效地处理分布式事务、保证外部一致性,并在全球范围内保持高性能运行。

Google Spanner 正在重新定义分布式数据库系统的可能性,为可扩展性、可靠性和创新设定了新的标准。


参考文献


  • Long Time Link
  • If you find my blog helpful, please subscribe to me via RSS
  • Or follow me on X
  • If you have a Medium account, follow me there. My articles will be published there as soon as possible.

DeepSeek:AI 竞赛中的黑天鹅

2025-02-04 18:22:30

Featured image of post DeepSeek:AI 竞赛中的黑天鹅

本文是最近一次关于DeepSeek在线讨论的总结,感兴趣的读者可以可以观看在线会议。
录像录制文件:https://meeting.tencent.com/crm/Nxg95wna26 密码:2PBC

最近,DeepSeek 在 AI 领域引发了广泛讨论。作为一个 AI 模型,其性能表现让整个行业为之一震,甚至被称为“AI 领域的拼多多”。这次技术突破不仅挑战了英伟达和 OpenAI 等巨头的传统叙事,也让全球 AI 产业重新评估开源模型的竞争力。

在这篇文章中,我们将深入探讨 DeepSeek 的核心技术、其带来的产业冲击,以及未来 AI 发展可能的路径。

一、推理效率的革命:从硬件优化到算法创新

近期AI领域最引人注目的进展之一,是推理效率的显著提升。通过KV缓存压缩低精度计算(FP8) 等技术,模型的推理成本被压缩至传统方法的十分之一以下。这一突破并非依赖算力的简单堆砌,而是通过算法与硬件的协同设计实现。例如,动态剪裁冗余的中间状态生成、基于规则验证的奖励机制(Verifiable Reward),使得模型在长上下文推理中减少重复探索,显著提升有效token利用率。实验表明,优化后的模型在相同硬件条件下,推理速度可提升6-7倍,且错误率未出现显著波动。

这一趋势对行业产生深远影响:边缘设备部署成为可能(如手机端运行复杂COT任务),同时倒逼闭源模型重新评估其商业逻辑——当开源模型以1/10 的成本实现95% 性能时,“算力霸权"叙事面临挑战。

二、蒸馏技术的双刃剑:捷径还是天花板?

蒸馏(Distillation)作为追赶闭源模型的核心手段,其本质是通过模仿教师模型的输出分布快速提升小模型性能。然而会议揭示了两大隐患:

  1. 多样性丧失:过度依赖蒸馏会导致模型陷入"参考答案陷阱”,放弃独立探索能力。例如在数学推理中,模型可能通过记忆高频解题路径而非真正理解逻辑来"欺骗"评测指标;
  2. 能力天花板:蒸馏数据的质量直接受限于教师模型的能力边界。当闭源模型转向新一代架构(如非Transformer设计)时,蒸馏路径可能因底层能力不匹配而失效。

有趣的是,部分团队通过混合训练策略找到了平衡点:使用蒸馏数据冷启动模型,再通过强化学习(RL)注入自主探索能力。这种"先模仿后创新"的路径,或将成为追赶者的标准范式。

三、开源VS闭源:生态博弈的新平衡

开源模型的爆发(如DeepSeek-R1)正在重构行业格局。其核心价值不仅在于技术透明性,更在于开发范式的根本转变

  • 场景定制化:开发者可通过微调小模型(如7B参数级别)在垂直领域达到商用级表现,而无需依赖闭源API的通用能力;
  • 硬件去中心化:配合AMD MI300等异构计算架构,开源模型在非英伟达生态中展现出惊人适配性,打破算力垄断的潜在威胁;
  • 安全可控性:闭源模型因数据隐私和监管风险,在金融、医疗等敏感领域的落地受阻,而开源方案提供了自主可控的替代路径。

但闭源阵营并非被动:OpenAI等头部玩家正通过超级算力押注(如500B StarGate项目),探索下一代架构,试图在智能边界上拉开代际差距。这场竞赛的本质,是"工程优化红利"与"原始创新风险"的博弈。

四、算力需求的再思考:短期扰动与长期确定性

尽管高效模型降低了单次训练成本,但行业对算力的渴求并未减弱,而是呈现结构性分化:

  • 探索者:仍需投入天量算力验证新架构(如非Transformer模型)、多模态融合等高风险方向,单次实验成本可达千万美元级;
  • 追赶者:通过算法改进(如MoE动态路由、数据筛选流水线)将同等性能的模型训练成本压缩80%,但需持续投入以应对闭源模型的代际跃迁;
  • 应用层:推理算力需求呈指数增长,尤其是在实时Agent、多模态交互场景中,模型需在百毫秒内完成复杂决策链。

Meta等公司的资本开支指引(2025年同比增长60%)印证了这一点:算力投入正从"军备竞赛"转向"精准打击",更强调单位算力的智能产出效率。

五、中国团队的启示:小米加步枪的破局之道

中国AI团队的技术突破揭示了一条独特路径——在算力约束下极致优化工程能力。典型案例包括:

  • 数据效率革命:通过奖励验证机制(如数学问题可自动评判),将强化学习的数据需求量降低90%;
  • 训练流水线创新:采用"预训练-蒸馏-强化学习"三阶段Pipeline,在2000张GPU集群上实现对标万卡规模的效果;
  • 硬件异构适配:与国产芯片厂商深度合作,探索FPGA、ASIC等定制化方案替代通用GPU。

这种"压强式创新"虽难以突破绝对技术边界,却在应用落地上构建了独特优势。当行业进入"拼落地"阶段时,这种能力可能比单纯的技术领先更具杀伤力。

六、未来展望:智能进化的下一站

  1. 推理与训练的边界消融:AlphaGo式的蒙特卡洛树搜索(MCTS)可能被引入语言模型,实现"动态思考-验证-迭代"的闭环推理;
  2. 过程奖励的突破:当前结果导向的奖励机制将被过程质量评估取代,如同围棋中对每一步棋的胜率预测;
  3. 多模态的本质价值:视觉-语言联合训练并非为了生成炫酷的图片,而是通过空间推理能力提升抽象问题解决水平(如几何证明)。

DeepSeek 的成功并非偶然,它代表了一种 AI 发展路线的变革,即更高效、低成本的 AI 训练方法。这场技术革命的核心矛盾,始终是探索者与追赶者的共生关系。 尽管短期内它无法彻底改变 AI 产业的格局,但其所引发的行业讨论,可能会对未来 AI 发展方向产生深远影响。开源 VS 闭源高效优化 VS 极端算力派,这些问题将在未来几年持续主导 AI 产业的发展。


  • 本文长期链接
  • 如果您觉得我的博客对你有帮助,请通过 RSS订阅我。
  • 或者在X上关注我。
  • 如果您有Medium账号,能给我个关注嘛?我的文章第一时间都会发布在Medium。