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

2020 年 3 月 28 日

金融巨头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


2020 年 3 月 28 日 08:004763
用户头像

发布了 323 篇内容, 共 140.6 次阅读, 收获喜欢 661 次。

关注

评论

发布
暂无评论
发现更多内容

小伙伴想学Jenkins自动构建发布项目,我:安排上了!!

冰河

项目管理 jenkins 灰度发布 自动构建 及时发布

spring-boot-route(六)整合JApiDocs生成接口文档

Java旅途

Java Spring Boot

作者谈《阿里巴巴Java开发手册(规约)》背后的故事

Java架构师迁哥

LeetCode题解:49. 字母异位词分组,数组计数+哈希表,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

理想的程序员

极客思享

金秋十月重磅技术文——网络编程大揭秘

Java架构师迁哥

编程 程序员

架构师训练营 Week4 系统架构 - 学习总结 架构演进

源码分析怎么做?

tison

源码分析

Architecture Phase1 Week4:Summarize

phylony-lu

极客大学架构师训练营

架构师训练营第三周心得

CmHuang

区块链--凌驾于政治之上的存在

CECBC区块链专委会

区块链 信息技术

Chrome浏览器架构

曲迪

chrome 前端 浏览器 专栏

架构师训练营第 1 期 - 第 3 周 - 学习总结

wgl

极客大学架构师训练营

Linux搭建C++开发调试环境

MySQL从删库到跑路

c++ Linux gdb 编译

云服务器网站打开速度过慢,如何进行自检

德胜网络-阳

一个草根的日常杂碎(10月5日)

刘新吾

随笔杂谈 生活记录 社会百态

架构师训练营 - 学习笔记 - 第三周

徐时良

极客大学架构师训练营

第二节课后作业

happy

区块链带来第四次技术革命 融入生产大幅提高企业收入

CECBC区块链专委会

区块链 数字资产 技术革命

如何开一场高效的会议?

boshi

高效工作 开会

架构师训练营 - 命题作业 - 第三周

徐时良

极客大学架构师训练营

Web Storage API的介绍和使用

程序那些事

web tech web storage web storage api storage api

阿里P8大牛爆肝的《Java核心技术总结》+《面试题总结》简直赞爆了

Java架构之路

Java 程序员 面试 编程语言 进阶

spring-boot-route(五)整合Swagger生成接口文档

Java旅途

Java springboot swagger

架构师训练营第四周学习总结

邓昀垚

极客大学架构师训练营

Architecture Phase1 Week4:HomeWork

phylony-lu

极客大学架构师训练营

第三周-代码重构

Galaxy数据平台

【知识分享】区块链常用术语

CECBC区块链专委会

区块链 货币 网络节点

Serverless Frist 的渐进式应用开发框架 Malagu

木香丘

开源 Serverless 云原生 Malagu Framework

架构师训练营第 1 期 - 第 3 周 - 作业

wgl

极客大学架构师训练营

架构师训练营 Week4 - 课后作业

缓存 自动化 异步 集群 冗余

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