Presentation: Accelerating Netflix Data: A Cross-Team Journey from Offline to Online

TL;DR · AI 摘要
Accelerating Netflix Data: A Cross-Team Journey from Offline to Online - InfoQ InfoQ Homepage Presentations Accelerating...
核心要点
- 主题聚焦:Presentation: Accelerating Netflix Data: A Cross
- 来源:InfoQ,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
加速 Netflix 数据:跨团队从离线到在线的旅程 - InfoQ
InfoQ 首页 演讲 加速 Netflix 数据:跨团队从离线到在线
AI、机器学习与数据工程
InfoQ AI 工程认证(7月25日):AI 演示已经成功。现在你需要让它变得可靠。
加速 Netflix 数据:跨团队从离线到在线的旅程
点赞
新下拉阅读列表
- 阅读列表
查看演讲
- 垂直
- 水平
- 全屏
速度:
- 1x
- 1.25x
- 1.5x
- 2x
下载
- 演示文稿
49:55
总结
Raj Ummadisetty 和 Ken Kurzweil 分享了 Netflix 架构向 CloudStream 的转型,这是一个可重复的数据捕获、转换和部署框架。他们讨论了如何将关键值抽象从无状态转变为有状态,以安全地传输数TB的批量数据。软件架构师将学习如何利用数据访问模式、使用“Pathfinder”原型,并实现99%更快的部署速度。
人物介绍
Raj Ummadisetty 领导 Netflix 数据抽象的开发,专注于可扩展、高性能的解决方案。此前,Raj 在亚马逊和 Facebook 做出过重要贡献。Ken Kurzweil 领导 Netflix 的数据移动团队。在加入 Netflix 之前,Ken 曾在亚马逊、Shutterfly 和 Gannett Media 担任工程职位。
关于会议
软件正在改变世界。QCon San Francisco 通过促进开发者社区中的知识和创新传播,赋能软件开发。作为以实践为导向的会议,QCon 专为技术团队负责人、架构师、工程总监和项目经理设计,这些人员在团队中推动创新。
INFOQ 事件
- 2026年7月16日,东部时间下午1点:面向代理时代的工程:如何规范、构建、测试和运营AI驱动系统 演讲者:Juveria Kanodia - Harness 工程高级总监
- 2026年8月6日,东部时间下午1点:构建用于高风险事件响应的AI代理评估 演讲者:Brianne Bujnowski - Datadog AI 高级产品市场经理,Benjamin Barton - Datadog 高级软件工程师
演讲稿
Rajasekhar Ummadisetty:我是 Raj Ummadisetty,今天与我一同分享的是 Ken Kurzweil。我们都是 Netflix 数据平台组织的软件工程师。在数据平台组织中,我来自在线数据存储团队,而 Ken 来自数据移动团队。今天,我们很兴奋地分享一个大规模架构转型的故事,这个转型改变了我们在 Netflix 中移动数据的方式。具体来说,我们将带您了解我们的 CloudStream 项目,该项目旨在高效地将数TB的数据从离线数据系统转移到在线服务系统。当我们提到离线数据系统时,指的是我们的数据仓库,在运行时这些数据不会被电视等设备访问。相比之下,在线数据系统位于关键路径上,能够以高速和随机访问的方式提供数据。实现这一转型要求我们从根本上重新思考架构和核心原则。结果,我们成功将数据部署时间减少了90%,并将成本降低了70%。
大纲
我们首先将讨论驱动您即将听到的所有技术和战略决策的核心理念——信心即货币。我们将向您展示这一原则如何以安全、可观测性和验证为基础,在每一步行动中引导我们的决策。随后,我们将介绍实现这一工作的关键架构基础——我们的抽象层,重点阐述键值抽象及其如何通过安全、可观测性和验证原则建立。这为接下来要解决的重大问题奠定了基础:将海量数据集从离线数据系统迁移至在线数据系统。接着,我们将带您了解我们针对首批用例子集(不可变数据集)所设计的架构愿景和创新解决方案。然后,我们将探讨将键值抽象从无状态系统转变为有状态系统的复杂架构转型,这一转变帮助我们实现了显著的性能提升。我们将把整个过程归纳为可重复使用的捕获、转换和部署框架。最后,我们将向您展示我们的未来规划,并总结关键经验。
信心即货币
信心即货币。它是任何组织中信任、决策和进步的基石。个人信心本身并不足以支撑成功。真正重要的是赢得利益相关者的信任。当您在架构中展示安全性,证明系统能够保护自身和用户时(例如通过限流操作或优雅处理错误),利益相关者会更加信任您。可观测性使系统具备监控、测量和理解其内部状态及进展的能力。验证则使系统能够明确证明其已实现预期目标。通过聚焦这些原则,您可以建立利益相关者对您方法和目标的信心。在Netflix,应用程序通过一层间接访问数据库。这是我们有意为之的关键架构选择,我们称之为抽象层。例如,目前Netflix整个Cassandra集群中,仅有16%的集群被应用程序直接访问。
这一比例仍在持续下降。我们绝大多数集群都通过抽象层进行访问。我们处理着整个抽象层集群约7000万QPS的请求量,其中最大的单个抽象层处理约800万QPS。一个抽象层可以由多个Cassandra集群支撑,最繁忙的Cassandra集群每秒可处理约180万次读取和490万次写入。
抽象层
现在让我们探讨一下应用团队在核心业务问题之外所面临的挑战,以及我们如何通过抽象层来解决这些问题。在直接访问模式下,每个应用团队必须理解特定的数据库技术及其持续变化。通过抽象层,他们可以获得稳定且统一的接口。应用团队现在可以完全专注于解决核心业务问题,而无需担心选择合适的数据库。在直接访问模式下,每个应用团队必须根据其访问模式了解如何进行扩容、何时添加缓存,并且还需要精通集群管理。抽象层使我们能够针对访问模式进行优化,并集中管理集群。如果我们发现某个用例是读取密集型的,我们可以为该场景专门配置一个缓存集群以优化资源消耗。此外,每个应用团队在没有抽象层的情况下,还需要解决如何与内部系统集成的问题,例如与所集成数据库的自定义身份验证机制。
通过抽象层,数据平台可以集中解决这些问题,并为所有应用提供统一的解决方案。每个数据库也有其特定的限制。例如,如果使用Cassandra,当发送大块数据时,集群可能会变得不稳定。通过抽象层,我们可以高效地解决这些限制。例如,在处理大块数据时,我们通过一种称为“分块(chunking)”的机制高效解决这个问题。通过分块,可以将这些大对象拆分为更小的对象,并在集群中进行分布。在Netflix,我们有多种抽象层来满足应用团队的需求。对于需要存储键值数据的应用,我们提供了键值抽象层;如果需要存储文档,我们提供了实体(Entity)抽象层;如果数据具有时间属性,我们提供了时间序列(Time Series)抽象层;如果需要存储属性图,我们提供了GraphKV抽象层,还有更多其他抽象层。我在此处附上了一篇博客文章的链接,详细介绍了我们构建的基础架构,该架构使我们能够在此基础上构建所有这些抽象层。
接下来,我们将重点关注其中一个特定的抽象层——KV抽象层及其采用背后的故事。键值抽象层作为分布式HashMap服务运行。它是一个两级映射,外层映射为字符串类型,我们称之为ID,映射到一个排序的键值对映射,我们称之为项目(items)。高层次的架构包括一个无状态服务器,该服务器连接到控制平面,获取命名空间信息,并初始化与数据库的连接。应用随后可以使用我们的高级客户端,该客户端提供基于SLO的请求重试、本地缓存等功能,并抽象了底层协议细节(例如我刚才提到的分块机制)。或者,应用也可以直接使用低级客户端,向服务发送请求,服务将该请求转换为数据库查询,执行查询后将响应返回给应用。我在此处附上了一篇关于键值抽象层的博客文章链接,详细介绍了其架构和提供的功能。
我们并非一直都有抽象层。过去应用团队通常直接与数据库集成,但这种架构自由与“变化是唯一不变的”现实发生了冲突。关键转折点出现在Cassandra宣布从3.0版本开始将弃用Thrift协议,仅支持SQL协议时。这意味着所有使用Thrift协议直接连接Cassandra集群的应用团队都必须进行迁移。这是一次大规模的公司级迁移。作为数据平台团队,我们意识到这并非唯一一次核心技术变更的时刻。我们希望保护应用团队免受未来类似破坏性迁移的影响。我们成功说服了大多数应用团队进行最后一次迁移,将应用逻辑从Thrift协议更新为键值接口,因为对于此次及未来类似迁移,我们将负责处理。
API迁移是第一步。我们专注于之前提到的三个核心原则:安全性、可观测性和验证性。系统立即获得了积极反馈。应用团队能够立即验证功能和非功能需求,因为向KV迁移不需要初始数据迁移。这使他们能够使用真实数据进行开发、实验和测试,且没有任何风险。他们能立即获得反馈,了解哪些工作正常、哪些存在问题。这一切无需任何改动。即使在提交并部署到生产环境时,他们也确信如果出现任何问题可以轻松回滚。这是一个真正的双向门流程,允许在出现问题时轻松回滚,并实现可观测性和安全性。他们清楚地知道迁移过程所处的阶段,以及验证结果。应用团队可以直接使用自己的数据进行验证。
这一过程完成了API迁移。应用团队现在通过我们的抽象层——键值抽象层连接数据库。下一步是迁移集群。我们首先进行了双写操作。主集群(旧集群)继续确认写入操作,同时将写入操作镜像到次级集群。在此模式下,我们获得了关键信号,例如扩展需求、潜在错误和潜在回归,从而建立了初步信心。随后是数据迁移。在此场景中,由于模式从Thrift模式迁移到KV数据模型,我们必须迁移数据。其他通常需要数据迁移的场景包括根据访问模式更改底层数据库技术本身。例如,如果我们决定某个用例更适合使用DynamoDB而非Cassandra,或从多租户集群切换到单租户集群。在此特定场景中,由于底层模式从基于Thrift的模式迁移到KV数据模型,我们必须迁移数据。
Ken Kurzweil: 数据迁移并不容易。我们当时有数百个Cassandra集群和数千张表需要迁移,而这些集群都在实时处理流量。当时我们并不清楚自己在做什么。在最初启动时,迁移系统已经具备了从一个数据存储复制到另一个数据存储的功能,但这个功能远远不够。它就像一个无法穿透的黑箱。我们和相关方完全不清楚数据迁移处于哪个阶段,唯一能知道的是迁移是否完成或彻底失败。现有系统缺乏安全性。如果我们过于激进地开始数据传输,而源集群和目标集群的规模没有适当调整,就可能造成集群负载过重,影响依赖这些集群的应用可用性。尽管这个问题对数据迁移本身至关重要,但对KV的整体迁移来说却并非关键。我们仍然能够迁移KV集群并帮助客户,特别是在我们逐步解决数据迁移问题的过程中。
从客户的角度来看,他们已经完成了迁移,感到满意。剩下的工作就落在我们身上。我们需要建立他们对我们迁移底层数据能力的信心,因此我们回到核心原则。我们需要确保安全性,需要实现可观测性,需要增加验证机制。为了解决安全性问题,我们对现有系统进行改造,使其能够监控源集群和目标集群,并在关键指标偏离正常范围时自动降低传输速率。我们尝试并实施了各种限流机制。即使像跟踪P90读写延迟这样简单的措施也证明非常有效。我们的方法是迭代的。我们研究出现的问题,尝试不同的解决方案,并采用有效的方案。核心目标是提升系统安全性。然而,作为副作用,迁移过程现在可以利用闲置容量,在非高峰时段扩容,在高峰时段缩容。
安全性机制实际上让我们变得更高效。我们通过添加功能来报告数据传输过程中的进度,从而增强了可观测性。尽管最初这个问题被认为很难,因此被排除在第一个系统之外,但事实证明这是整个项目最有效的改进。能够告诉相关方我们已经完成了X%的进度,或者这张表需要多少时间完成,这改变了整个局面。这种可见性使我们能够识别需要扩容的集群,以适应特定的时间表或预算。此外,这种新的洞察力使我们能够有效规划。我们收集指标和经验,可以预测未来。建立一个可验证的系统是另一个挑战。我们开始采访相关方以了解他们的担忧,并实施机制来捕捉他们预测的差异。我们的奇偶校验方法本身就是一个独立的讨论主题。总之,我们努力获得相关方的信心。
一旦我们对自身迁移能力充满信心,能够独立完成数据迁移,并启用双写功能后,所有数据(包括历史数据和未来数据)都会同时写入两个集群。将旧集群中的历史数据复制到新集群的过程,本质上只是数据的复制操作。迁移完成后,我们可以通过校验数据集确保数据在两个集群中都存在。随后,我们就可以进行流量切换。此时,我们可以将读取请求从旧集群切换到新集群,从而实现数据源的变更。当我们确认一切正常后,停止向旧集群写入数据,最终可以将其下线。至此,整个迁移过程圆满完成。我们成功完成了迁移,尽管过程中遇到了诸多挑战,但这次经历非常成功,也让我们收获颇丰。
批量数据迁移
完成迁移后,我们对复用所开发的技术充满期待。例如,我们开发的安全限流机制。我们开始寻找可以将这些技术适配到更通用场景和数据迁移场景中的机会。我们开始与各个应用团队进行交流。我们发现,有些应用团队每天多次生成数据集,并将其写入我们的数据仓库。随后,这些团队会将大量数据迁移到自己的在线数据存储中,以便为在线应用提供服务。这些数据包括广告的信号和元数据、推荐系统的预计算排名、基于用户行为的特征生成,以及各种生成嵌入向量和特征的机器学习应用。传统处理数据集的方式虽然简单,但在大规模场景下却极其低效,因为团队通常使用Spark等批处理系统,仅仅将数据读取后直接以单条记录的形式写入目标系统。
这种方式经常导致他们有效地对自身应用发起DDoS攻击,被自己的流量所淹没。我们称这种现象为“噪声邻居”问题。批量数据加载会消耗资源,引发资源竞争并影响应用性能。当然,我们可以通过扩展规模来应对,但当没有执行批量任务时,这种扩展会导致大量闲置容量,造成金钱浪费。我们也可以通过反压机制减缓处理速度,但不幸的是,这会牺牲应用依赖的数据准确性。虽然我们可以通过调优在小规模场景中做出取舍,但面对TB级的数据集时,这些方法完全失效。在如此规模下,这些方法即使投入大量资金,也需要数天时间才能完成加载。这最终成为阻碍高价值业务应用的关键瓶颈,因为这些应用无法通过我们现有的方法得到有效支持。
当我们与已实施这些解决方案的客户讨论使用案例时,开始在他们的仪表板上发现一个共同模式。他们会有这样的堆栈图,展示数据集随时间变化的各个版本。实际上,你可以在图表中看到从一个数据集到另一个数据集的转换可视化。我们看到这个过程需要数小时。在这些小时里,我们还能看到他们实际上同时在提供两种版本的数据,一部分是旧数据,一部分是新数据。分析这些使用案例时,我们开始发现两种访问模式逐渐显现,一种是可变模式,另一种是不可变模式。在可变使用案例中,应用程序会从键值存储系统中读取和写入数据。在特定情况下,批处理作业只是补充数据。在不可变使用案例中,批处理作业仅向数据存储写入数据,而应用程序只是从中读取数据。
这实际上是只读操作。理解这些访问模式使我们能够简化许多使用案例,并利用这一特定使用案例的不可变性。这些案例不需要Cassandra来达成共识。我们只需要以只读方式提供服务。我们有一个理论。与其通过前端门通过Cassandra存储数据,我们可以通过将这些数据集转换为RocksDB SSTables,然后直接加载到KV节点上。这应该更便宜且性能更高。在这些情况下,我们不需要运营Cassandra集群。每次想要进行数据演进时,只需启动一个KV实例似乎是一个合理的方法。实际进行文件生成的I/O和计算密集型工作可以完全离线完成。我们可以完全消除在线服务的竞争。我们可以在新的专用KV节点上以网卡和磁盘允许的最大速度按行速率预生成这些文件,从而大幅减少引入新数据集所需的时间。我们会启动新节点,重新路由流量,并清理之前的节点。
从概念验证到路径finder
为了验证这个理论,我们构建了一个概念验证。尽管最初对架构存在反对和怀疑,但概念验证的结果无可辩驳,验证了我们的想法。它确实有效。它很快。它很便宜。概念验证被证明是将非信徒转化为信徒的最有效方式。在概念验证中,服务器实现了KV API,托管了我们离线生成的数据,并有另一个服务作为协调器,负责将信息传递和路由给客户端。它们可以将请求路由到正确的节点。在获得功能原型后,我们立即制定了生产版本的初步路线图。我们最初的估计包括构建和增强现有基础设施,这些基础设施已经包括自助服务配置、CI/CD管道和部署系统,但这些是无状态系统,我们需要将其扩展到有状态操作。我们被一个面临关键业务截止日期的特定团队接触,他们提出了紧急请求。
我们开始制定一项策略,以加快进度而不牺牲长期目标。在深入研究POC后,我们发现通过调整路线图,可以利用现有的高级客户端,并构建一个POC,使我们能够以有限的方式将强化版的客户端部署到生产环境。当我们构建此类系统时,我们称之为“开拓者”(Pathfinder)。开拓者是一种你有意计划迁移的软件。开拓者能够为愿意承担一定风险的利益相关者解除关键业务用例的阻碍,同时在提供价值的同时,让你尽可能多地学习。开拓者是你与利益相关者建立互利关系的一种方式。他们可以得到其他情况下无法获得的功能,而你则能与愿意参与的人员一起探索未知的未知领域。我们抽象了POC客户端在名称、解析和路由方面的实现,并将其置于功能标志后,发布了改进后的高级KV客户端,使我们能够无缝切换现有KV功能集、开拓者以及尚未交付的生产KV实现。这意味着当我们的产品真正准备就绪时,应用团队无需更改代码,我们可以透明地将流量从临时设置切换到生产基础设施。
开拓者运行速度很快。从根本上说,它很简单,我们对其有充分的理解。我们构建了工具和方法,用于衡量部署数据集所需的时间,并且对吞吐量和延迟的性能有深入的理解。我们利用这些基准测试,与KV生产实现的开发过程进行性能对比。它们并不相等。KV团队能够使用我们的基准测试自行运行,并专注于瓶颈问题,反复优化,直到我们所有人都感到满意。最终,我们生产出一个不仅性能与开拓者相当,而且改进措施普遍适用于所有KV用例的KV版本,使所有应用团队(无论是否使用我们正在构建的新技术)都受益。开拓者还让我们学会了如何转换数据集并将其存储在S3中。一旦数据集进入S3,我们就可以随时部署它们。
只要我们完成高级增强功能,就可以部署到生产环境并解除关键的业务需求。我们部署了一个为生产环境强化的新版本协调器(coordinator)。我们让应用团队引入新发布的客户端。随后,控制平面被指示下载数据集并更新协调器,客户端从协调器读取数据并路由请求。这一过程持续到另一个数据集在离线状态下准备就绪并部署到S3中。新节点被创建,数据被加载,协调器被更新,旧节点被移除。
KV 无状态到有状态
Rajasekhar Ummadisetty: 通过Pathfinder项目,我们成功解除了关键应用团队的阻碍并提供了支持。这不仅解决了迫在眉睫的需求,还为我们赢得了宝贵的时间来构建生产环境基础设施。Pathfinder项目带来的经验为后续工作奠定了基础。如前所述,这需要将我们的键值抽象层从无状态系统转变为有状态系统,并更新部署流程,使其不仅能处理代码部署,还要支持数据部署。回顾键值抽象的无状态架构,从高层次来看,我们之前使用的是无状态服务器。这些服务器连接到控制平面,获取命名空间信息,连接数据库后启动。当所有服务器启动完成后,应用现在可以向它们发送请求。由于所有服务器都相同且无状态,任何服务器都可以处理请求。它们只需将请求转换为数据库查询,执行后将结果返回给应用。
转向有状态架构后,服务器不再保持无状态。每个服务器存储数据的子集,使其在管理的数据方面各具独特性。为实现这一协调,我们引入了多个新的控制组件。首先是分区组管理器。服务器通过与分区组管理器通信来获取唯一租约,该租约定义了服务器负责的数据子集。我们还引入了中央路由管理器。路由管理器跟踪所有有状态的KV集群、有状态的命名空间,以及每个命名空间中哪些服务器托管了哪些数据部分。即使在KV集群内部,我们也引入了集群路由层,该层与中央路由管理器通信并缓存特定于该KV集群的信息。它跟踪该KV集群内可用的命名空间以及数据具体托管的位置。
KV集群和集群路由的额外职责是将路由信息传递给连接到该集群的应用。应用端的客户端可以使用这些路由信息将请求路由到特定的数据节点。我们还扩展了部署基础设施以支持有状态数据部署。当触发新的数据部署时,第一步是捕获需求。这些需求来自应用团队,例如每秒预期的读取次数是多少?数据集的大小是多少?随后我们将这些应用层面的需求转化为基础设施层面的需求,例如使用什么类型的实例、需要多少实例、需要多少副本、要托管的数据集是什么?根据这些需求,我们随后会创建一个自动扩展组并等待节点启动。每个服务器节点首先与控制平面通信,获取命名空间,类似于无状态架构,但随后会与分区组管理器通信,获取之前提到的唯一租约,以确定需要托管的数据部分。之后会连接到S3,获取离线生成的数据文件子集,拉取这些文件并加载初始化。当所有节点启动完成后,我们会启用预发布阶段。预发布阶段用于应用团队在将数据集提升到生产环境前进行验证。
如果还记得,传统的数据摄入方法导致了我们称之为“锯齿模式”的现象。在此模型中,数据存储库中的旧数据集会在数小时内逐渐被新数据集取代。在此缓慢过渡期间,应用团队有时间窗口观察数据被替换时的渐进变化。这使他们能够设置监控和告警,以在问题发生时及时发现回归或数据损坏。尽管专用的验证系统会是理想的选择,但团队通过依赖这种漫长的摄入窗口来监控和响应问题,从而绕过了这一限制。在我们更新后的流程中,这种过渡窗口变得非常小,几乎可以忽略不计。数据摄入本身可能需要几分钟时间,但一旦新数据被摄入到新节点,从旧数据集切换到新数据集的过程只需几秒钟。
因此,之前的监控和告警机制不再有效,因为应用会突然一次性暴露于整个新数据集。这会增加数据损坏等问题的影响范围,因为不再有渐进式部署。正因如此,在切换数据集之前,验证变得更加关键。这也是我们为何在新的部署流程中引入专用验证阶段的关键原因之一。在预发布阶段,应用团队可以启动验证器应用,这使他们能够连接到预发布集群,执行请求,验证数据,建立信心,然后向我们发送信号以推进数据集。一旦我们收到此信号,就会更新路由信息。路由信息会传递到应用端。客户端随后使用这些更新信息将请求路由到新数据集。
我们等待并监控,确保所有请求在几秒钟内从旧数据集转移到新数据集,但我们会保留旧数据集以防出现任何回归或问题,从而可以立即回滚。一旦我们确认新数据集按预期正常工作,就会销毁旧数据集。
从Pathfinder到生产环境
至此,我们完成了从无状态到有状态基础设施的关键值抽象转换,生产基础设施已准备好支持关键用例。如果还记得,我们曾通过Pathfinder基础设施解除了一个关键应用的限制,现在是时候将该关键应用从Pathfinder基础设施迁移至关键值基础设施,并验证我们的假设:通过抽象化并最初专注于增强客户端,可以为迁移提供这种灵活性,使迁移对客户应用团队透明。我们分两个精心控制的阶段执行了此次迁移,以限制影响范围并确保平稳过渡。在第一阶段,我们将Pathfinder协调器替换为KV集群路由。重要的是,KV集群路由继续将路由信息传递给应用,使请求仍指向Pathfinder数据节点。
这使我们能够在最小化风险的同时逐步引入新组件。这也是一扇可逆的双向门。如果出现任何问题,我们可以快速切换回原始协调器。一旦我们确认应用流量已正确通过KV集群路由,我们便进入第二阶段。在这一阶段,我们向KV数据节点加载与Pathfinder节点上相同的dataset。当KV节点完全加载后,我们更新路由信息,使客户端请求现在指向KV数据节点而非Pathfinder节点。随着请求从Pathfinder节点过渡到KV节点,迁移过程完成。此次迁移对客户端应用团队完全透明。他们无需进行任何更改或操作,所有配置均由我们安全地管理。如果观察到任何回归问题,我们可以立即恢复到之前的状态。在整个过程中,我们依赖于安全机制、可观测性和验证措施。我们之前运行的基准测试使我们确信KV生产基础设施的性能将与Pathfinder基础设施相当。事实上,应用团队并未察觉到任何差异。
胜利成果
我们对创新和跨职能协作的承诺不仅提供了技术解决方案,还创造了巨大的商业价值。我想强调三个关键用例,这些用例此前在使用传统数据迁移流程时面临挑战,而我们通过新方案使它们取得了成功。第一个用例涉及迁移海量数据集。使用传统方法,根本无法满足客户应用的SLO要求。加载时间将需要数天,每年产生数百万的基础设施成本。通过新架构,我们现在可以在40分钟内加载数据集,并在几秒钟内切换完成。这直接将部署时间减少了99%,并节省了70%的成本。另一个用例涉及高频率的版本化特性数据,数据量较小但更新频率极高。我们将数据加载时间缩短至10分钟以内,并实现了90%的运营成本节约。此外,该用例需要在数据集版本之间进行回滚和前进操作,而这一能力此前并不可用。
第三个用例可能是最强大的胜利案例,即启用了平台开发。一个应用团队能够基于我们的解决方案构建了一个强大的机器学习平台。该平台现在使多个团队能够快速部署和使用自定义ML特性,证明我们的工作不仅是技术修复,更是推动业务创新的真正加速器。这些关键用例释放了重大的商业投资,并促使我们正式化了使这一切成为可能的架构原则。
架构泛化 - 捕获、转换、部署
Ken Kurzweil: 在开发批量数据迁移系统时,我们概括出一个称为“捕获、转换、部署”的框架。该框架使我们能够以模块化、可复用和可重复的方式构建系统。这使我们能够将工作分配给不同团队,主要是因为每个团队都清楚各个阶段的输入和输出。传统方法会导致一个耦合的系统,直接将数据集部署。将阶段拆分为捕获、转换、部署,使每个阶段能够解耦并独立开发和优化。在捕获阶段,我们创建并存储数据集的不可变工件,确保可以引用并提供我们捕获时数据集的原始状态。主要目标是为后续处理提供不可更改的工件。捕获可以直接进入转换,或者我们可以使用多个捕获来生成增量,从而产生更高效的部署工件。
对于KV,在转换阶段,我们可以将捕获的工件转换为为部署设计和优化的格式。对于KV,我们使用了RocksDB,但这可以是任何格式。目标是根据目标定制数据集,使其针对每个目标进行优化。部署涉及协调和传输阶段工件到数据存储,并以确定性方式将这些数据集上线。这可能包括部署新集群、加载数据或管理流量切换。执行部署步骤时,它与捕获和转换步骤无关,这至关重要,因为它意味着我们可以以简单的方式向前或向后回滚到之前的版本。我们的应用团队一直在持续更新他们的数据集。我们的系统会捕获该数据集,无论是触发还是计划执行,然后捕获将其转换为部署格式。
在我们的情况下,例如之前讨论的RocksDB SST文件,或者最近正在测试的Cassandra SST文件。这种捕获、转换、部署方法可以扩展,并为我们提供了一种推理未来增强和优化的方式。通过将数据迁移分解为三个独立步骤,我们可以重复使用和交换组件,并且可以为新的数据存储集成新的转换阶段而不会干扰现有流程。当某个组件得到优化,例如更快的数据集捕获方法,性能优势将扩展到整个生态系统。该框架赋予基础设施和应用团队能力,使他们能够更轻松地独立部署和回滚数据集。这种能力促进了数据验证、性能测试和风险缓解。确定性工件部署可以作为可靠的保护网,在这些数据迁移操作中增强信心和安全性。明确的阶段划分使团队能够协作,在我们的情况下,是数据迁移团队、KV团队和UX团队。他们可以独立地在不同组件上工作,因为他们可以验证各自的交付成果。
未来
让我们谈谈即将到来的未来。我们正在积极将最近在不可变数据集上获得的经验应用到可变数据集上。在我们特定的案例中,捕获阶段将保持不变,但转换阶段现在可以使用Apache Cassandra分析项目生成Cassandra SSTables。部署阶段包括将这些文件加载并生成到正在处理流量的实时Cassandra集群中。我们定制的编排工具和Cassandra内置的文件加载、压缩及冲突解决机制使我们能够继续推进。我们已经构建了这个系统,并正在进行测试,未来我们很兴奋能与大家分享。我对数据迁移工具生态系统和我们现在拥有的技术感到兴奋,这里是一瞥未来的景象。我们已经革新了从和向Cassandra集群读写Cassandra SSTables的能力。之前的所有工作都适用于此,但我们拥有了新的能力。
我们已经能够使用机制将Cassandra SSTables导出到S3。这就是我们如何执行备份的。我们最近提升了读取和转换它们的能力。更近一步,我们获得了将它们写入并导入到实时Cassandra集群的能力。此外,我们具备将数据写入任何数据存储格式的能力,并允许我们在抽象层后面迁移到任何数据存储。例如,如果成本或性能权衡需要,我们可以从Cassandra切换到DynamoDB。
关键要点
以下是我希望你能带回组织的要点。信心就是资本。安全、可观测性和验证是一组架构原则,我们在每次需要建立信心时都会参考这些原则。抽象是一种超能力。抽象和我们使用间接方法的能力使我们能够执行大规模但无缝的迁移。你应该分析并利用访问模式,与利益相关者沟通,了解他们的使用场景。这就是创新发生的地方。一个POC(概念验证)相当于100次会议。我们在说服利益相关者方面发现这至关重要。路径探索者允许你通过有意识地选择想要学习的内容、迁移方式以及要放弃的内容来加快进度。POC和路径探索者帮助我们规划未来。最后,像我们使用捕获、转换、部署这样的架构模式。这使团队能够更快、更独立地思考系统和组件的构建。
问答环节
参与者1:在整个迁移过程中,哪些关键的可观测性指标帮助你们确保应用团队在终端仍然保持预期的正确性和幂等性?
Ken Kurzweil:通常,我们关注的关键指标是吞吐量、延迟和错误率。除此之外,我们的客户参与了迁移过程,因此在转换期间他们能够提前获知情况。大部分依赖于我们能够向他们提供保证,即我们已经完成了数据一致性检查,这些工作大部分已经完成,使我们能够建立信心。我们最担心的是遗漏少量记录,而不是数百万条。如果出现问题,你可能需要数月才能发现,因此必须确保为零。
Rajasekhar Ummadisetty:在初始迁移过程中,针对Thrift相关的迁移,这种抽象层的优势之一就是可以将幂等性直接构建到抽象层中。我们所有具有修改功能的API都带有幂等性令牌。这保证了无论请求发送到哪个后端,这些请求都能保持幂等性。
Ken Kurzweil:为什么选择RocksDB?我们实际上评估了多种不同的文件格式。最初我们考虑过Hollow,这是一个内部开发的项目,非常酷。当时以及现在,它都适合在JVM内存中运行,是一个非常理想的使用场景。我们也专门评估过SQLite,SQLite是一个非常优秀的文件格式。我来告诉你为什么没有选择它。我们首先考虑过Cassandra的SSTables,我们认为自己肯定可以编写它们,但作为独立的格式,它们的支持度较低。当我们向支持者和反对者展示这些方案时,有人提出:为什么不使用Memcached的ext格式?在所有这些方案中,我们最终建立了一个矩阵,用来评估这些格式的支持程度和文档完善程度。
这种格式是否专为外部消费而设计?它在压缩方面具体做了什么?如果有两个文件,它是否会自动进行压缩,还是需要我们手动处理?还有其他指标。例如,SQLite在所有方面都符合要求,除了它不支持压缩。你可以动态加载它,基本上可以打开SQLite库,甚至可以连接两个不同的数据库。但你无法让它合并两个表。而RocksDB则满足了所有需求,它有良好的支持,是一种专为外部使用而设计的格式,具备在线压缩功能和挂载能力。
参与者2:在RocksDB的相同粒度下,你们有没有考虑过ClickHouse?它也执行类似形式的压缩,以及所有这些功能?
Ken Kurzweil:没有,我们没有考虑过ClickHouse。这是特指文件格式,是独立的文件格式吗?
参与者2:相同的文件格式,用于时间序列数据。
Ken Kurzweil:没有,我们没有考虑过。
参与者3:在你们尝试说服客户使用Pathfinder时,是否制定了明确的策略?比如,是先解决最难的问题,优先说服最大的客户或最重要的使用场景?还是选择一个客户,其需求是新功能且不涉及业务关键性,即使出现延迟或可靠性问题、数据一致性问题,也可以接受?因为Pathfinder本身既是你们自我验证的工具,也是向客户证明其价值的手段。
Ken Kurzweil: 在我们那个开拓者阶段,真正需要寻找的是那些希望参与其中、有切身利益的早期采用者。他们正在寻找一项新功能。对我们来说,我们特别关注的是能够扩展到整个团队的需求,但我们也发现了一些特定客户,如果无法交付某些功能,他们就会放弃合作。这些客户真的需要这个产品。我们当时讨论的这个具体客户,是推动我们进入开拓者阶段的重要用例,这是一个非常关键的场景,它依赖于其他多个环节的协同。他们非常愿意承担一定风险,作为特定客户帮助我们完成这个过程。在开拓者阶段选择客户时,我们特别希望找到那些愿意与你合作、共同应对未知挑战的决策者。
如果你能找到这样的客户,他们将是最佳合作伙伴,因为如果出现任何问题,他们会是第一个告诉你的人。他们将成为你最坚定的支持者。在这个具体案例中,他们是我们必须构建的用例中规模最大的一个。这有点像那个老生常谈的“吃青蛙”理论——如果你在一天开始时就吃掉那只青蛙,之后一整天都不用再面对它了。这个场景正是如此。如果我们能解决这个特定问题,就一定能够覆盖Netflix其余所有需求。当我们在那个阶段实现了稳定的部署后,我确信可以继续推进。毫无疑问,你必须找到合适的客户。更重要的是,要找到那些能推动你突破现有技术边界、拓展实施范围的客户,这样当你进入实际应用场景时,就不会只做一些简单的测试就上线,然后发现通用场景的复杂程度比预期高出好几个数量级。
参与者4:当你们从前端加载迁移到Cassandra再到RocksDB SST时,能否分享一下直接使用Cassandra与后端加载到RocksDB的负载时间节省情况?
Ken Kurzweil:节省非常显著。在我们这个具体案例中,针对最大客户的标准部署周期需要数天时间才能以合理速度加载价值数百万美元的集群。但对这个客户来说,这仍然不够,因为他们希望以比我们加载数据所需数天更高的速度更新数据。在开拓者阶段的具体实现中,我们成功将这个时间缩短到了27分钟。从验证这个理念的角度来看,这是一次完全成功的尝试。随着我们逐步增加更多优化措施,这个时间增加到了40分钟,但这恰恰证明了这种方案是可行的。目前我们向Cassandra迁移时也看到了类似的效果,但影响程度略低,原因在于加载Cassandra的SSTables时需要处理状态合并的问题。你实际上需要执行压缩阶段,而我们刚才描述的整个过程都是离线完成的,我们只是直接替换新的实例。这个过程非常快速。
参与者5:你们的抽象层是否增加了延迟或导致了其他问题?
Ken Kurzweil:当然,它确实增加了一层。
Rajasekhar Ummadisetty:是的,确实如此。我们观察到,它增加的额外延迟对于应用团队来说并不像其带来的好处那样重要。最初我们担心应用团队可能难以说服自己接受这个额外的跳转步骤。但当我们展示出这一方案的优势后,这种权衡就变得非常值得了。
参与者6:相关地,你在演讲开头提到除了我们在这里讨论的抽象层之外,还有许多其他数据抽象层。我很好奇,你们是否遇到过试图开发抽象层却最终发现它并不适合当前场景的情况?当时发生了什么?
Rajasekhar Ummadisetty:确实遇到过。有些情况下,抽象无法概括这些API的子集。例如,如果你使用关系型数据库,它有SQL接口,这是一个非常广泛的API表面积。如果你想通过部分API子集来抽象SQL接口,可能无法覆盖所有使用场景。这些情况需要我们深入思考:如何缩小API表面积,使其真正适配我们的抽象方案?
See more presentations with transcripts
Recorded at:
Jul 09, 2026
by
- Rajasekhar Ummadisetty
- Ken Kurzweil
#### Related Sponsors
- Alert Fatigue Is Costing You: The State of Production Reliability and AI Adoption
#### Related Sponsor
在与实时AWS遥测数据连接的完整配置环境中探索NeuBird AI Playground。尝试你的第一个查询!
#### This content is in the AI, ML & Data Engineering topic
##### Related Topics:
- AI, ML & Data Engineering
- QCon San Francisco 2025
- Transcripts
- Offline-First
- QCon Software Development Conference
- Case Study
- InfoQ
- Data
- Cloud
- Related Editorial
- Popular across InfoQ Google Releases A2UI v0.9: Portable, Framework-Agnostic Generative UI Agentic AI Architecture Oracle Quietly Halves Free Tier Ampere A1 Compute Limits with No Public Announcement OpenTelemetry Graduates to CNCF's Highest Maturity Level Node.js 26: Temporal API Enabled by Default, V8 14.6, and a Round of Deprecations Spite-Driven Engineering: A New Blueprint for Cloud Security in the AI Native Era