英国金融时报是世界上最大的商业新闻机构之一,已有 130 多年历史,以其高质量的新闻报道而闻名。
要想长时间保持领先地位,就必须能够适应世界的变化。过去 10 年,为了利用技术提供的机遇,金融时报经历了一次数字化转型。
本文将深入介绍这一转型的幕后故事:金融时报数据平台的创建和演化。该数据平台提供读者与 FT 互动的信息,让我们能够决定如何继续为读者提供他们想要和需要的东西。
第一代:2008–2014 早期
起初,数据平台专注于根据读者已经阅读的内容做推荐。
当时,我们的大多数读者仍在阅读纸质版《金融时报》,因此,一个存储和 24 小时的延迟就足够了。该架构干净、简单,金融时报的员工能够在上面执行查询,分析用户兴趣。
但随后发生了一些事情。
第二代:2014–2016 提取、转换、加载(ETL)框架的到来
我们的第二代平台面临两个新的挑战:首先,需要使我们的涉众能够大规模地分析数据,提出新的问题;其次是数据量的增加。
为了实现这些目标,我们在 2014 年构建了自己的 ETL 框架。这使得我们的团队能够以自动化和可扩展的方式创建新的作业和模型,并包含如下特性:
ETL 框架的发布产生了巨大的积极影响,但它本身并不能解决因为数据量和用户数增加而带来的所有问题。
实际上,从性能的角度来看,添加这个新组件实际上会带来更多的问题,因为数据平台的消费者数量增加了,现在包括商业智能(BI)团队、数据科学团队和其他团队。SQL Server 实例开始成为数据平台的瓶颈,也成为所有涉众的瓶颈。现在是做出改变的时候了,我们设法为这个特定的问题找到了最好的解决办法。
考虑到金融时报已经在使用 Amazon Web Services(AWS)提供的一些服务,我们开始评估 Amazon Redshift,将其作为一种快速、简单、划算的数据仓库,用于存储越来越多的数据。Amazon Redshift 是为云端在线分析处理(OLAP)而设计的,这正是我们一直在找的东西。使用这种方法,我们能够大幅优化查询性能,而不需要团队付出任何额外的努力来支持新的存储服务。
第三代:2016–2018 金融时报大数据时代来临
将 Amazon Redshift 作为数据仓库解决方案,将 ETL 框架作为部署提取、转换、加载作业的工具,所有 FT 团队都看到了拥有一个数据平台的好处。然而,当我们在一家引领市场的大公司工作时,比如在金融时报从事商业新闻发行时,我们不能满足于现有的成就。这就是为什么我们开始思考如何进一步改进这个架构。
我们的下一个目标是减少数据延迟。我们每天摄入一次数据,因此延迟时间长达 24 小时。减少延迟意味着 FT 可以更快地对数据趋势做出反应。
为了减少延迟,我们在 2015 年开始研究一种名为下一代数据分析(NGDA)的新方法,并在 2016 年初被金融时报的所有团队采用。
首先,我们开发了自己的跟踪库,负责将读者的每一次互动发送到数据平台。现有的架构需要一个 CSV 文件列表作为输入,这些文件由 ETL 框架运行的作业每天传输一次,因此,逐个发送事件意味着我们需要更改现有的架构以支持新的事件驱动方法。
然后,我们创建了一个 API 服务,负责接收读者的交互。但是,我们仍然需要一种方法,以尽可能低的延迟将这些数据传输到数据仓库,并将这些数据公开给多个下游消费系统。在我们将所有服务迁移到云(更具体地说是迁移到 AWS)上时,我们了解了 Amazon 提供的能够满足我们事件处理需求的托管服务。
在分析了各种备选方案之后,我们重新设计了系统,将的所有原始事件发送到简单通知服务(SNS)。这样一来,组织中的许多团队都可以订阅 SNS 主题,并根据实时数据解锁新的业务用例。
尽管如此,仅仅是在 SNS 中有这些原始数据还不够——我们还需要将数据放入数据仓库以支持所有现有的工作流。我们决定使用一个简单队列服务(SQS)队列,因为它让我们可以在所有事件到达系统时立即将它们持久化。
但是在将数据移动到数据仓库之前,我们还有一个来自业务的需求——使用由内部服务、外部服务或简单内存转换所提供的额外数据来丰富原始事件。为了在延迟最小的情况下满足这些需求,我们创建了一个服务,负责在一个循环中异步处理所有事件,使得丰富步骤可以大规模地进行。事件经过充分的丰富之后,数据就会立即被发送到 AWS 当时提供的唯一托管事件存储 Kinesis 中。使用这种架构,我们能够在延迟数毫秒的情况下将丰富后的事件持久化,对我们的涉众来说,这是一个让他们惊喜的消息。
一旦数据进入 Kinesis Stream,我们就使用另一个 AWS 托管服务 Kinesis Firehose 消费经过丰富的事件流,并根据两个主要条件中的一个把它们以 CSV 文件的形式输出到一个 S3 bucket——一个预定义的已经过去的时间(很少发生)或文件大小达到 100MB。这种新的事件驱动方法根据一天的时间段在几分钟内生成包含丰富后事件的 CSV 文件,因此,我们的数据湖延迟被减少到 1-5 分钟。
但是,业务团队还有一个更重要的需求。他们要求数据仓库中的数据是干净的。使用 Kinesis Firehose 方法,我们不能保证只有一个事件实例,因为:
为了删除所有重复的事件,我们另外创建了一个 Amazon Redshift 集群,负责摄入每个新进来的 CSV 文件并进行去重。这涉及到一个权衡:实现一个保证惟一性的流程,将数据进入数据仓库的延迟提高到大约 4 个小时,但可以使我们的业务团队更轻松地生成洞察。
第四代:2019 重建平台让团队专注于增加业务价值
第三代平台运行起来很复杂。我们的团队把大部分时间都花在了支持大量的独立服务上,工程成本增加了,从事有趣而又有影响力的工作的时间少了很多。
我们希望利用新技术来降低这种复杂性,同时也为涉众提供更加令人兴奋的功能:我们希望将数据平台转换为 PaaS(平台即服务)。
根据最初的标准,平台应该提供:
构建多租户、自助服务平台非常具有挑战性,因为它需要每一项服务都同时提供这些支持。尽管如此,努力实现这一方法对未来的发展极为有利,主要的好处如下:
我们选择用来提供这种解耦的方式是重配置而轻实现,涉众团队能够基于其内部团队的结构、角色和权限,使用一个管理 Web 界面设置自己的管理规则。
一个软件系统就像一座房子。你需要从地基开始建,而不是从屋顶开始。在工程中,地基就是基础设施。没有稳定的基础设施,就不可能有一个生产就绪的稳定的系统。这就是为什么我们从基础设施开始,从短期和长期两个方面讨论未来的最佳方法。
我们现有的数据平台已经部署到 AWS ECS 中。虽然 AWS ECS 是一个非常棒的容器编排器,但我们还是决定切换到Kubernetes,因为 EKS 提供了许多我们为提供多租户支持所需要的功能,比如租户之间的安全隔离、每个租户的硬件限制等等。除此之外,还有许多开箱即用的 Kubernetes Operators,比如spark-k8-operator、prometheus-operator等等。AWS 提供托管的 Kubernetes 集群(EKS)已经有一段时间了,不管是从短期来看,还是从长期来看,它都是数据平台基础设施的不二选择。为了拥有一个提供自助服务的多租户数据平台,我们不得不对每个服务和 Kubernetes 集群本身提几个要求:
我们的 ETL 框架非常稳定,并且已经运行了多年,但为了充分利用我们采用的云原生技术,我们需要一个新的框架来支持:
自从我们构建了 ETL 框架之后,人们对 ETL 的期望一直在变化。我们希望能够支持:
另一个大的变化是功能齐全的 ETL 框架现在已经有了,不再需要从头开始构建。
考虑到所有这些需求,我们评估了市场上存在的不同选项,如 Luigi、Oozie、Azkaban、AWS Steps、Cadence 和 Apache Airflow。
最适合我们需求的是Apache Airflow。
尽管它很棒,但仍有一些局限——比如只有一个调度程序和缺少多租户原生支持。虽然根据基准测试、估计负载以及该特性将在 Apache Airflow 2.0 中发布的预期,第一个问题我们不是特别关心,但第二个问题会影响我们的整个架构,所以我们决定在 Apache Airflow 之上构建自己的多租户支持。
我们考虑过使用一个 Apache Airflow 托管服务(有多个供应商),但最终,考虑到多租户、语言无关的作业和监控等需求,我们还是决定继续使用自托管的解决方案。所有这些都无法通过托管解决方案实现,所以就有了扩展需求,这对我们来说很重要。
把 Apache Airflow 集成到平台中之后,我们就开始在其上发布新的工作流,以保证其功能。当我们认识到它符合所有标准时,下一步就很明显了,目前我们正在将所有现有的 ETL 作业迁移到 Apache Airflow 中。除此之外,我们已经将它作为一个自助服务产品发布给公司的所有涉众,我们的消费者现在已经包括 BI 团队、数据科学团队,等等。
第五代:2020 实时数据的时间到了
第四代平台有很大的进步。但是,仍有一些改进目标。
对于很大一部分数据,我们的延迟仍然是 4 个小时左右。
在大多数情况下,4 个小时的延迟是去重过程所导致的——这个过程对我们的涉众及其需求来说非常重要。例如,金融时报不能基于低质量的数据做出任何业务发展决策。这就是为什么我们必须确保数据仓库能为这些用例提供干净的数据。
然而,随着产品、业务和技术的发展,新的用例出现了。 它们可以使用实时数据来产生影响,即使有小比例的低质量数据也没关系。一个很好的例子是,在和移动应用程序中,根据读者的兴趣对推送给用户的内容进行排序。对于这个用例来说,存在事件重复也影响不大,因为用户体验总会比不考虑用户兴趣就向所有用户推送相同的内容要好得多。
我们已经有了一个稳定的流处理架构,但它相当复杂。我们开始考虑对其进行优化,从 SNS、SQS 和 Kinesis 迁移到使用Apache Kafka作为事件存储的新架构。事件存储托管服务是我们的首选项,我们决定试一下 Amazon MSK,因为很长一段时间以来,它似乎就已经很稳定了。
在 Apache Kafka 主题中摄入数据是向业务提供实时数据的一个很好的开端。然而,涉众仍然无法访问 Apache Kafka 集群中的数据。因此,我们的下一个目标是创建一个流处理平台,让他们部署基于实时数据的模型。我们需要一些与架构其他部分相匹配的东西——支持多租户、自助服务、多语言以及可部署到 Kubernetes。
考虑到这些需求,Apache Spark似乎非常适合我们,它是最常用的分析引擎,也是世界上最大的开源社区之一。
为了将 Apache Spark 流作业部署到 Kubernetes,我们决定使用 spark-on-k8s-operator 。
此外,我们的 top="6708.21875">
另一个我们需要进行优化的方面是,将数据验证移到管道中尽可能早的步骤里。我们有对进入数据平台的数据进行验证的服务,但是这些验证是在管道的不同步骤执行的。这会导致问题,因为管道有时会因为传入的数据不正确而中断。这就是为什么我们想通过提供以下特性来做出改进:
考虑到所有这些需求,我们找到了一种使用Apache Avro来实现这些需求的好方法。它让我们可以为 Apache Kafka 中的每个主题定义一个数据契约,从而确保集群中的数据质量。
这种方法还解决了另外一个问题——验证步骤可以移到管道中的第一步。借助 Apache Avro 模式,在使用 Apache Spark 流作业时就可以防止我们将不正确的事件转移到其他用作 Dead Letter Queues 的 Kafka 主题中,从而防止管道中进入有问题的数据。
Apache Avro 的另一个重要特性是序列化和反序列化,这使得它能够对保存在 Apache Kafka 事件存储中的数据进行压缩。
从 CSV 迁移到数据湖存储中的 parquet 文件,是可以满足我们大多数需求的最佳初始选项。但是,我们仍然缺少一些可以使我们的工作更轻松的特性,包括 ACID 事务、模式约束以及在 parquet 文件中更新事件。
在分析了市场上现有的所有替代方案(包括、和)之后,我们决定开始使用支持 Apache Spark 3.x 的 Delta Lake。它满足了我们所有的主要需求,非常适合我们的架构。
虚拟化层
在金融时报,我们公司的团队使用了不同类型的存储,包括 Amazon Redshift、谷歌 BigQuery、Amazon S3、Apache Kafka、VoltDB 等。然而,涉众常常需要跨多个数据存储分析数据,以便做出数据驱动的决策。为了满足这个需求,他们使用 Apache Airflow 在不同的数据存储之间移动数据。
然而,这种方法远不是最佳的。使用批处理方法会给增加额外的数据延迟,在某些情况下,使用低延迟数据做出决策对于业务用例至关重要。此外,部署批处理作业需要更多的技术背景,这可能会限制一些涉众。了解了这些具体信息,我们就更清楚,涉众为了向读者提供更多的价值需要什么了,它需要支持:
我们希望能够部署到 Kubernetes 上,以适应我们的平台架构。
在分析了市场上的不同选项之后,我们决定从入手,因为它让企业可以大规模地分析 PB 级的数据,而且能够连接来自许多数据源的数据,包括金融时报使用的所有数据源。
未来规划
在金融时报,我们从不满足于自己已经取得的成果,这也是该公司 130 多年来一直处于行业领先地位的原因之一。这也是为什么我们已经规划好如何进一步演进这个架构。
查看英文原文:
Financial Times>