首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

金融巨头Capital One的无服务器实践

你是否想过,在月底结账时,你才发现自己的账户有错误交易?也许你遇到过这种事,并且印象深刻。数字化革命让你可以随时随地获取自己的信息。无疑,我们离未来世界不远了。在这个世界,相关信息可以在有需要时出现,你无需去寻找。

Capital One正致力于使我们做的几乎所有事实时化。通过改进云计算和大数据工程工具,它不断为解决方案增加实时特性。我们的团队一直专注于为客户带来与其相关的、实时的个性化洞察。我们试图找出客户消费行为中非常特殊的交易,例如餐厅消费高得离谱、重复账单的增加、全新免费试用的开始和多次重复交易等等。

经过多年发展,Spark框架逐渐发展成大规模实时流和批处理需求的首选技术。但是,伴随强大计算能力而来的是更高的操作和维护成本,我们开始体会到为满足实时流需求而运营Spark基础设施带来的痛苦。

所有,我们团队接受挑战,找到一个更简单、维护少且高度可伸缩的模式,并且围绕其设计一个无服务器流解决方案。

为何Apache Spark并非所有实时流用例中的"银弹"?

据Databricks的博客,Apache Spark是处理大规模批处理和流数据的最快开源引擎之一。这点显而易见。既然Spark性能如此出色,为什么我们还要考虑使用其他的东西?

图片来自Databricks blog

然而,让我们根据应用程序的需求评估下,比如:

  • 应用程序每秒加载记录是多少?如果它每秒低于几千,那Spark可能多余;
  • 为实现高弹性,应用程序所需的驱动程序和工作容器的最小数量是多少?如果在云上,请考虑将其分布到多个可用区和区域;
  • 安装像Zookeeper这样的资源管理器来维护Spark集群需要多少容器?;
  • 你是否考虑过云或数据中心的区域故障?如果是,那你可能已经体验过让Spark集群跨区域可用的架构复杂性;
  • 你的工作负载每天是否是固定的?如果是就太棒了,这对你的生意有好处。但是,大多数实时系统在每天、每周和每年都有周期性的工作负载,所以一定要考虑在非高峰时间系统的利用率;
  • Spark作业在任何时候都可能失败。你考虑过作业的错误处理、监控和自动恢复吗?要实现这一点,需要很大的开发工作量;

不要忘记开发成本,这是所有成本中最大的一部分。考虑工程师在开发Spark基础设施时所需的所有特殊技能,比如像Scala或Python这样的编程语言、安装和管理Spark基础设施的脚本知识以及Spark缓存等。

尽管Apache Spark有着令人印象深刻的效果,但是如果你关心Apache Spark的运营开销,那么无服务器流解决方案可能是更好的选择。事实上,大多数实时流用例的加载速度都低于每秒1000个事务。

不必因为小的工作负载而去应对Spark基础设施的复杂性。相反,使用无服务器流解决方案来简化你的代码,可以极大降低成本和复杂性。

一个架构良好的流解决方案包含哪些?

在实现几个与流相关的用例后,我认为理想的流解决方案应满足以下需求:

伸缩

在现代应用程序架构中,自动伸缩被视为基本的设计考虑因素之一。在云计算时代,你可以根据需求获得无限的计算能力,因此不需要因为峰值负载进行扩展并支付额外费用。

虽然你能规划好主要的周期性工作负载,但是,在传统的基于服务器的基础设施中,你很难在一分钟内对其进行优化。理想情况下,应用程序应该能在请求出现较大峰值时自动修复以及自动伸缩。

限流

通常,流应用程序被设计成每秒接收成千上万个请求,并最终降到一个更易于管理的范围。当出现意料之外的峰值时,流应用程序可以横向扩展,但是下游的阻塞调用(API、DB等)可能无法扩展。

因此,限流成为任何流应用程序的基本需求之一。记住——你系统的好坏取决于最薄弱的环节。

容错

应用程序总是与其他资源(如API、数据库等)相连接。相关系统难免出现故障,但同时,我们也希望保护应用程序不受这些问题的影响。

在流应用程序中,容错是关键需求之一,因为你不希望在后端系统宕机时丢失数据。

重用

与重新创建解决方案相比,我们常常更关注重用。重用的程度取决于组件的模块化和大小,而微服务是重用的最佳示例。通过使流解决方案的构建块更小且可配置,我们可以加强跨多个应用程序的组件重用。

监控

想象一下,数百万条消息/事件流经你的应用程序,你能跟踪每一条消息并了解该消息究竟发生了什么。当你构建面向客户的关键应用程序时,这一点变得更加重要,并且需要查明特定的客户事件究竟发生了什么。

因此,对于同步或异步系统来说,监控都非常重要。

我们是如何构建无服务器流架构的?

那么,我们如何构建我们的解决方案?

我们的无服务器流架构是基于事件驱动的微服务架构建模的,其中每个微服务使用消息总线彼此连接。

本质上,事件驱动的架构提供了我们需要的流解决方案的所有功能。基于云服务商提供的托管服务实现事件驱动架构,就可以构建无服务器的流解决方案。

对于上述模式,如果你将托管服务(如AWS Lambda)作为微服务,AWS Kinesis作为消息总线,就可以使用无服务器技术栈实现事件驱动的架构。

我们将整个架构分为三层——源、接收(Sink )和处理。

  • :在这一层中,微服务只负责从源获取数据。可以将其视为事件进入流应用程序的入口。例如:从Kafka集群读取事件。
  • 处理:该层负责处理从源层获得的事件。你还可以将其视为一个能拥有具体应用程序逻辑的层。例如:过滤事件或调用API来针对事件做出决策。你可以有一个或多个处理层来映射、缩减或增加你的消息。
  • 接收:这是应用程序的最后一层,在这里对事件进行最后操作。例如:将事件存储到数据存储中,或者通过API调用触发其他进程。

下面是从消息驱动架构到AWS服务的映射。

在上图中,你可能会觉得有很多重复动作,特别是从Lambda到从Kinesis写/读的动作。你可以发挥创造力,针对重复的功能构建某种类型的库。

在Capital One,我们正是这样做的。我们构建了内部SDK来抽象重复任务。SDK有以下特点:

  • 从消息总线读写:从消息总线(Kinesis或将来的其他服务)读写事件。
  • 异常处理和重试:主要有两种重试,阻塞和非阻塞。当后端应用程序失败时,你可以阻塞错误重试,直到它恢复。当你只希望特定事件重试而对其他事件没有任何影响时,使用非阻塞重试。
  • 秘密管理:当你不希望在无服务器函数中存储凭据时,将需要此功能。你可以选择企业秘密管理工具,并将它们集成为你的库的一部分。
  • 监控:我们创建了自定义的消息信封,其中包含帮助我们跟踪每条消息的元数据。SDK可以替开发人员承担这些工作,在每个微服务进入/退出时插入/删除信封。
  • 日志记录:为实现跨所有微服务的统一体验,你可以在SDK中构建日志记录模式。
  • 消息去重:我们知道,大多数分布式快速数据系统保证至少一次传递。当你想要过滤掉重复的消息时,可以考虑将其抽象为库的一部分。你能使用哈希或其他方法来实现具有亚毫秒延迟的消息去重。

它如何满足我们的流解决方案需求

正如我们前面所讨论的,任何无服务器流解决方案都需要解决伸缩、节流、重用、容错和监控等问题。这是如何实现的呢?

伸缩

这种架构模式与天生可伸缩的云和服务相结合,让这一切成为可能。

  • 该模式使用Lambdas实现微服务,并通过Kinesis进行连接。我们只需要扩展具有高TPS的Lambdas,随着消息被过滤掉,相应地调整规模配置。
  • 按照设计,无服务器函数是可自动伸缩的。例如:如果你使用Lambdas和Kinesis,你可以扩展Kinesis,如果你的消息吞吐量从2MB/秒增加到4MB/秒,这也将扩展与Kinesis相关的Lambda函数。

限流

限流的基本功能是,如果你的输入请求速率远远高于下游所能支持的速率,则需要保存你的请求。在这里,消息总线持久化特性能帮助我们,因为你只能选择一次可以处理的消息数量,并保存其他消息。

例如:如果你使用Kinesis作为消息总线,则能指定你在函数中处理的批次大小。

重用

如果我们可以构建source微服务和sink微服务,让它们不具有任何业务功能,并且是基于配置的,那么就可以多个团队都使用它们来消费事件。

例如:如果你能构建源函数来消费来自Kafka的事件,这些事件可以对主题名称、代理地址等进行配置,那么任何团队都可以根据需要使用该函数并将其部署到他们的栈中,而无需更改任何代码。

以上可以帮助我们实现代码级的重用。另一种重用是流本身的重用。如果你为自己架构选择的消息总线是基于发布/订阅的总线,那么你能有多个订阅者来访问相同事件。例如:你可以将事件fan out到两个微服务,而无需单独编写额外代码。

容错

同样,消息总线在这里也可以对我们提供帮助。考虑一下,如果你的后端服务出现错误,你可以将所有/失败的消息保存到消息总线中,然后重试,直到后端调用开始成功。

监控

作为SDK的一部分,记录元数据有效负载能帮助我们实现跨不同功能的日志一致性。你还可以构建一个可重用的函数,该函数能将你的日志转发到首选的监控解决方案。

这听起来就像说无服务器流解决方案是银弹,我不需要Spark

并非如此。Apache Spark是一个分布式计算平台,在大规模分布式数据处理负载上表现出色。当涉及高容量计算和批处理时,数据和计算功能可以采用分布式,并且能并行执行,Spark仍然是首选工具。典型例子包括机器学习用例的重量级计算需求,涉及几百个文件的Map/Reduce范式,或者处理PB级数据的长时间运行的进程等等。Spark也能作为实时流领域的首选工具,但前提是流量非常大,每秒执行数十万个事务。

在Capital One,我们使用多种多样的大数据工程工具。在我的团队中,我使用了无服务器流来处理大容量的用例,比如根据每秒数千个事件的客户交易生成有意义的警报,以及处理每秒数十个事件的小容量用例,比如补卡。我还使用Spark来处理大型交易文件,使用机器学习模型生成客户的消费档案。这完全取决于具体的需要。

英文原文:

Scaling to Billions of Requests-The Serverless Way at Capital One

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/5ydIS3A81M4MdFC5GJTy
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券