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