Meta的数据工程:内部技术栈的高级概述

Meta的数据工程:内部技术栈的高级概述

本文概述了我们作为Meta数据工程师日常使用的内部技术栈。我们的想法是阐明我们所做的工作,以及工具和框架如何使我们的日常数据工程工作更高效,并分享我们在此过程中做出的一些设计决策和技术权衡。如果你想了解更多关于数据的相关内容,可以阅读以下这些文章:
Excel中的Python:将重塑数据分析师的工作方式
如何成为数据分析顾问?
成为更好的数据分析师的5个习惯!
Noteable:自动进行数据分析的ChatGPT插件

我们所说的数据仓库是Meta用于分析的主要数据存储库。它不同于实时向用户提供内容的“图形数据库”(TAO)。它是数百万个Hive表的集合,使用ORC的内部分支进行物理存储(您可以在这里阅读更多信息https://engineering.fb.com/2015/03/17/core-infra/even-faster-data-at-the-speed-of-presto-orc/)。我们的exabyte规模的数据仓库(1exabyte等于1,000,000 tb)非常大,因此无法在一个单独的数据中心中进行物理存储。相反,数据分布在不同的地理位置。

由于数据仓库不是物理上位于一个单一区域,因此它被划分为“名称空间”。名称空间对应于数据仓库的物理(地理)和逻辑分区:与类似“主题”相对应的表在相同的名称空间中分组在一起,因此可以在相同的查询中有效地使用它们,而无需跨位置传输数据。

如果需要在查询中使用来自两个不同名称空间的表(例如:名称空间a中的table1和名称空间B中的table2),那么我们需要复制数据:我们可以选择将table2复制到名称空间a,或者将table1复制到名称空间B。然后我们可以在两个表都存在的名称空间中运行查询。数据工程师可以通过基于web的工具在几分钟内创建这些跨名称空间的副本,并且它们将自动保持同步。

名称空间对整个数据仓库进行分区,表本身也进行分区。数据仓库中的几乎所有表都有一个ds分区列(ds表示YYYY-MM-DD格式的日期),它通常是数据生成的日期。表还可以有额外的分区列来提高效率,并且每个单独的分区存储在一个单独的文件中,以便快速建立索引。

Meta系统中的数据仅在满足收集数据的目的所需的时间段内保留。数据仓库中的表几乎总是有有限的保留时间,这意味着比表的保留时间(例如90天)更早的分区将被自动归档(匿名并移动到冷存储服务)或删除。

所有表都与一个oncall组相关联,该组定义了哪个团队拥有该数据,以及用户在遇到问题或对该表中的数据有疑问时应该参考谁。

将数据写入仓库的三种最常见的方式是:

  • 数据工作流和管道,例如由Dataswarm管道插入的数据(下面有更多细节),通常通过查询仓库中的其他表获得。
  • 日志,例如,来自服务器端或客户端日志框架的数据。
  • 生产图数据库中实体的每日快照。

在处理如此庞大的数据仓库时,寻找分析所需的数据似乎是大海捞针。值得庆幸的是,Meta的工程师们开发了一种名为iData的基于Web的工具,用户可以简单地通过关键字进行搜索。然后iData将查找并显示与该关键字最相关的表。它是一个用于数据仓库的搜索引擎:iData以一种智能的方式对搜索结果进行排序,通常会在最前面的结果中找到您要查找的表。

为了显示最佳结果,它考虑了每个表的几个特性:数据新鲜度、文档、下游用法的数量(在特殊查询、其他管道或仪表板中——通常,在许多地方使用的表可以被视为更可靠)、内部Workplace帖子中提到的次数、与之相关的任务的数量,等等。

它还可以用于高级搜索,例如搜索包含特定列的表,这些列被分配给特定的oncall组,等等。

除了表格之外,iData还可以用于查找其他类型的数据资产(例如仪表板),并且还包括谱系工具,用于探索任何资产的上游和下游依赖关系。这使得可以快速确定用于生成高级仪表板数据的管道以及位于其上游的日志记录表。

数据仓库可以通过许多不同的入口点进行查询,但Meta的数据工程师通常使用Presto和Spark。这两者都是开源的(Presto最初是在Meta开发的,并于2019年开源),Meta使用并维护自己的内部分支——但经常从开源存储库中重新构建以便保持最新状态,并将功能贡献回开源项目。

我们主要关注业务影响、设计和优化,因此我们的大多数管道和查询都是用两种方言(Spark SQL或Presto SQL)之一的SQL编写的。虽然我们也利用Spark的Java、Scala和Python API来生成和管理复杂的转换,以获得更大的灵活性。这种方法提供了对数据和业务逻辑的一致理解,使任何熟悉SQL的数据工程师、数据科学家或软件工程师都能理解我们所有的管道,甚至编写他们自己的查询。更重要的是,了解数据及其来源有助于我们遵守众多的隐私法规。

Presto或Spark的选择主要取决于工作负载:Presto通常更高效,用于大多数查询,而Spark用于需要大量内存或昂贵连接的繁重工作负载。Presto集群的规模设计得足够大,以便大多数日常的即席查询(通常扫描数十亿行数据,这在Meta规模下被视为轻量级查询)在几秒钟内产生结果(如果涉及复杂的连接或聚合,可能需要几分钟)

Scuba是Meta的实时数据分析框架。数据工程师和软件工程师经常使用它来实时分析日志数据的趋势。它也被软件和产品工程师广泛用于调试目的。

可以通过Scuba web UI(类似于Kibana之类的工具)或通过SQL方言查询Scuba表。在Scuba web UI中,工程师可以在不编写任何查询的情况下快速可视化日志表的趋势,显示最近几分钟生成的数据。

Scuba中的数据通常直接来自客户端或服务器端日志,但Scuba也可以用于查询数据管道、实时流处理系统或其他系统的结果。每个数据源可以配置为将数据的抽样百分比存储到Scuba中。通常将日志记录器配置为将其所有行写入Hive,但将较小百分比的数据写入Scuba,因为将数据导入和存储到Scuba更加昂贵。

Daiquery是Meta数据工程师每天使用的工具之一。它是一种基于web的笔记本体验,作为查询任何数据源(仓库、Scuba等)的单一入口点。它包括一个带有多个查询单元格的笔记本界面,用户可以快速运行和迭代针对数据仓库的查询。默认情况下,结果显示为表格,但内置的可视化工具允许创建许多不同类型的图。

Daiquery针对快速查询开发进行了优化,但不支持更复杂的查询后分析。对于这一点,用户可以将他们的Daiquery笔记本升级为Bento笔记本。Bento是Meta对托管Jupyter笔记本的内部实现,除了查询之外,它还支持python或R代码(针对不同的用例提供一系列自定义内核),并可以访问各种可视化库。除了数据工程师使用,Bento还被数据科学家广泛用于分析,机器学习工程师用于运行实验和管理工作流程。

Unidash是数据工程师用于创建仪表板的内部工具(类似于Apache Superset或Tableau)。它与Daiquery(以及许多其他工具)集成:例如,工程师可以在Daiquery中编写他们的查询,创建图表,然后将其导出到新的或现有的Unidash仪表板。

我们的仪表板通常显示底层数据的高度聚合视图。每次加载仪表板时,运行查询来聚合底层数据的成本通常非常高。在许多情况下,数据工程师可以通过编写管道将数据预聚合到仪表板的适当级别来解决这个问题,但在某些情况下,由于仪表板本身的复杂性,这是不可能的。为了帮助解决这些问题,我们的内部Presto实现包括一个名为RaptorX的扩展https://prestodb.io/blog/2021/02/04/raptorx/,它可以缓存常用数据,并可以为时间关键型查询提供高达10倍的加速。

大多数Unidash仪表板都是通过web界面创建的,允许快速迭代和交互式开发。Unidash仪表板也可以通过python API创建,它允许仪表板更容易扩展到更高的复杂性,并使仪表板更改更容易进行审查(但初始设置可能会更复杂一些)

图片由作者提供

数据工程师开发管道来生成关键数据集,通过使用Daiquery和Unidash等工具来实现决策,Meta的数据工程师还编写代码来定义数据管道,与内部系统接口,创建团队特定的工具,为公司范围的数据基础设施工具做出贡献,等等。

Meta的大多数工程师使用高度定制的Visual Studio Code版本https://code.visualstudio.com/作为IDE来处理我们的管道。它包含大量自定义插件,由内部团队开发和维护。我们使用Mercurial的一个内部分支来进行源代码控制(最近以Sapling的形式开源),以及一个近乎单一的结构——Meta的所有数据管道和大多数内部工具都在一个存储库中,日志记录器定义和配置对象在另外两个存储库中。

数据管道大多用SQL编写(用于业务逻辑),用Python代码封装(用于编排和调度)

我们用于编排和调度管道的Python库在内部被称为Dataswarm。它是Airflow的前身,是内部开发和维护的。如果你想了解更多关于Dataswarm的内部工作原理,可以参考2014年一位参与Dataswarm工作的软件工程师做的一个很棒的演讲,这个演讲可以在YouTube上找到。虽然该框架自那时以来不断发展,但该报告中的基本原则至今仍然适用。

管道建立在称为“操作符”的块上。管道是一个有向无环图(DAG),每个操作符是DAG中的一个节点。

Dataswarm中有许多操作符,它们可以分为几个主要类别:

  • WaitFor操作符,一种等待某些事情发生的操作符(通常是特定上游表中的一个分区登陆到仓库中)
  • 查询操作符,用于在引擎上运行查询(通常用于查询仓库的Presto或Spark)
  • 数据质量操作符,对表中插入的数据执行自动检查
  • 数据传输操作符,在系统之间传输数据
  • 杂项操作符(例如:发送电子邮件,通过聊天发送消息,调用API,执行脚本…)

定义一个简单管道的代码如下所示:

图片由作者提供

我们的内部VSCode扩展在保存时处理管道定义并计算DAG:

图片由作者提供

如果任何SQL语句中有错误,自定义筛选器甚至会在尝试运行管道之前显示警告。这些扩展还允许数据工程师使用实际输入数据安排新版本的测试运行,并将输出写入临时表中。

如果你重新阅读上面的代码,你可能会注意到一些冗余。在本例中,我们要求第一个操作符等待my_data_source的今天的分区登陆,而在第二个操作符中,我们要求框架等待my_operator1,因为我们需要my_staging_table中存在分区。但是我们可以通过查看SQL查询来推断出这一点:WHERE ds= ”意味着我们依赖于这个表的分区。作为工程师,我们不喜欢重复自己。

Meta的一个工程师团队解决了这个问题,并建立了一个名为统一编程模型(UPM)的框架https://engineering.fb.com/2022/11/30/data-infrastructure/static-analysis-sql-queries/,它确实做到了这一点:当在Dataswarm管道中使用时,它会解析操作符中的SQL查询,并正确推断每个操作符需要等待哪些分区。(请注意,这只是UPM提供的一个特性,将在“数据工程的未来”系列文章中详细介绍)。通过使用UPM,可以自动推断出所有的“WaitFors”和依赖项。然后可以将管道代码简化为其核心业务逻辑:

图片由作者提供

一般来说,编写管道的数据工程师将通过查看生成的DAG来验证UPM推断的依赖项是否正确。

除了简化管道的开发之外,UPM和其他分析库还用于生成某些类型的复杂管道(例如用于增长核算或保留),这些管道很难手工创建。这些库使用用户提供的自定义生成遵循常见模式的管道。

一个简单的例子是生成摘要样式的表(将在以后的博客文章中详细讨论)

图片由作者提供

这将生成一个包含三个维度列(product、country和has_log_session)和两个聚合度量列表total_session_time_minutes和total_distinct_users_hll。最后一列使用Presto中的HyperLogLog类型https://engineering.fb.com/2018/12/13/data-infrastructure/hyperloglog/,用于近似计数。

管道监控是通过一个名为CDM(中央数据管理器)的基于web的工具完成的,该工具可以被视为Dataswarm UI。

屏幕截图

这个视图类似于Airflow的树状视图,但这是一个更广泛的工具的入口点,它允许我们:

快速识别失败的任务,并查找相应的日志

  • 导航到上游依赖项(例如,对于waitfor,它将导航到生成我们正在等待的上游表的管道)
  • 识别上游障碍(CDM将浏览递归的上游依赖,并自动找到管道堵塞的根本原因)
  • 如果分区没有根据配置的SLA着陆,则启用通知和升级
  • 建立和监控数据质量检查
  • 监控飞行任务和历史表现

本文提供了数据工程师最常用的工具和系统的概述,但在整个公司中有很多变化。一些数据工程师主要专注于开发管道和创建仪表板,而另一些则专注于日志记录、开发新的分析工具,或者完全专注于管理ML工作负载。

本文没有包括一些值得深入研究的重要工具和系统,这些工具和系统将在以后的博客文章中介绍:

  • 管理度量和实验的工具
  • 我们的实验测试平台
  • 用于管理实验暴露和推出的工具
  • 隐私的工具
  • 用于管理ML工作负载的专用工具
  • 用于理解度量运动的操作工具

我们的数据仓库和系统已经不断发展和变化,以满足公司的需求,因此,它们不断演变以支持新的需求。我们正在进行的工作包括扩展我们的隐私意识基础设施,降低查询成本和存储中的数据量,并使数据工程师更容易管理大型管道套件。总的来说,这些变化有助于减少数据工程师执行的重复性工作,使他们能够花更多的时间专注于产品需求。

感谢阅读!你还可以订阅我们的YouTube频道,观看大量大数据行业相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/

原文作者:Alex M @Analytics at Meta
翻译作者:Dou
美工编辑:过儿
校对审稿:Jason
原文链接:https://medium.com/@AnalyticsAtMeta/data-engineering-at-meta-high-level-overview-of-the-internal-tech-stack-a200460a44fe