在本期节目中,我与 Momento 的联合创始人 Khawaja Shams 讨论了基于单元的架构,以及它如何使 Momento 能够扩展到每秒数百万次事务 (TPS),同时在其多租户系统中保持健康的爆炸半径。 节目链接: Momento Khawaja 的 XKhawaja 的领英 相信无服务器社区 主题曲: 凯文·麦克劳德的《快乐星期一》 链接:https://incompetech.filmmusic.io/song/3495-cheery-monday 许可证:http://creativecommons.org/licenses/by/4.</context> <raw_text>0 嗨,欢迎回到《无服务器的真实世界》节目的结尾,这是一个我与现实世界的实践者交谈并了解他们现场故事的播客。今天,我们再次邀请到了来自 Memento 的 Dekwaja Shams。嘿,伙计。欢迎回来。嘿,Jan。很高兴再次见到你。
是的,我们之前聊过 Memento,我一直非常喜欢你们正在做的工作。最近,我在领英上看到你的一位工程师发布了一篇文章,谈到你们的一位客户突然决定发出,我想说,每秒一百万个请求。而且影响很小很小。我认为你谈到的是架构响应时间的纳秒级差异。是的。
这次谈话中出现了一些有趣的东西,那就是关于蜂窝架构,我知道你们之前在 AWS 上做过的事情。所以,在我们开始之前,也许可以多告诉我们一些关于 Memento 和你自己的信息,以及你如何从 AWS 到 Memento 的。是的,我很乐意。我的名字是 Kawaja。我职业生涯的开始是为火星探测器上的摄像头构建软件。我……
我性子急,所以我转向了软件开发。软件比硬件更能带来即时的满足感。我为火星探测器构建了图像处理管道。我又一次性子急了,因为我不想等待服务器。所以在 2008 年、2009 年左右,我将我的整个管道迁移到了 AWS,使用了许多原始的无服务器服务,例如 S3、SQS,来真正支持这些图像处理峰值。
我加入了亚马逊,负责 DynamoDB 团队,然后在 AWS Elemental 工作,负责媒体服务的生产和工程。
今天,我是 Momento 的联合创始人。我们汲取了我们在构建高性能、关键任务、高规模应用程序方面的经验教训,让我们的客户能够轻松完成所有这些工作,而无需担心底层基础设施的细节,尤其是在缓存和消息传递方面。
是的,我真的很喜欢你们在主题方面所做的事情。这些主题使得构建实时通信系统变得容易得多,例如为您的网站后台进程构建某种推送模型,以告知前端某些操作已完成。
或者更有趣的事情,例如实时聊天或游戏,您需要在这些游戏中实时更新信息。主题非常适合这些用例,而且使用起来也很简单。我知道 AppSync 发布了一个新的事件 API,试图让那些想要拥有这种功能的人更容易上手。
不错的托管 WebSocket 消息传递,无需使用 GraphQL。但我认为,与 Memento 主题相比,它仍然缺乏一些细粒度的访问控制。而且,我认为就易用性而言,你们在主题方面做得非常好。
谢谢。我认为开发者体验对我们来说至关重要,这包括人们上手的速度,以及当事情变得庞大和尖锐时,他们需要处理的干扰少。我们的主要价值主张是让客户快速上手并持续发展,因为他们的事件会取得成功。我们不断寻找分散客户注意力的来源
客户。而 WebSockets,与 WebSockets 作斗争往往是任何试图为最终应用程序构建实时通知的人都会遇到的常见情况。我们认为这是一个绝佳的机会,可以通过简化人们向其前端应用程序添加消息传递的速度来为世界增加价值。
说到干扰,考虑正常运行时间和冗余等等也是一个很大的问题,尤其是在您开始为数百万个并发用户构建高吞吐量系统时。这是你们在扩展和弹性架构方面真正擅长的事情之一。
而这很大一部分是我今天想谈论的内容,那就是蜂窝架构,我越来越多地阅读到关于蜂窝架构的内容,而且我认为像 Mark Brooker 这样的人在多租户和 AWS 方面谈论了很多关于蜂窝架构的内容。我知道你在 AWS 工作期间参与了很多这样的讨论。
是的,所以也许可以告诉我们一些关于 Memento 发生的事情以及你们如何使用蜂窝架构来限制那个吵闹的客户造成的爆炸半径。是的,我认为让我们倒退一段时间,谈谈亚马逊为什么全力以赴地采用蜂窝架构。当
AWS 最初推出时,弗吉尼亚地区非常受欢迎。我的意思是,它是第一个区域,也是控制台的默认区域。因此,许多客户最终都默认将他们的服务部署到弗吉尼亚地区。James Hamilton 总是谈论默认设置的力量。我总是对人们选择默认设置的程度感到惊讶。是的。
随着时间的推移,弗吉尼亚地区变得越来越大。您基本上会了解所有扩展限制。如果您是 AWS 内部的服务提供商,那么您的架构软件的所有限制,所有内容都将在弗吉尼亚地区首先暴露出来,因为它最大。而且
你知道,如果你看看 AWS 发生的一些最大的中断,大多数都发生在,至少在历史上,大多数都发生在弗吉尼亚地区。而其中很多仅仅是由于规模造成的。您可以进行各种分阶段和,你知道,限制您的部署等等。但是当事情到达弗吉尼亚时,它们从未在如此规模下进行过测试。而且
对于 AWS 来说,Mark Brooker 的一个原则是不断工作。如果你仔细观察,客户密度最高的地区与其他所有地区最不一样。
因此,当该地区出现问题时,您会影响更多的人,但这也是测试最少的地区。因此,AWS 的优秀员工提出了这个概念,好吧,我们可以将区域和区域内的服务蜂窝化。这意味着您将区域划分为小的单元,对吧?
这样,您的单元开始看起来彼此更相似。你知道,IAB 或者弗吉尼亚可能有很多单元,其大小更接近第二大区域等等。
但它也为设计架构的人员提供了更多工程约束。因此,大约在 2015 年左右,在 AWS 收购 Elemental 之后,我们正在推出大量媒体服务,AWS 内部的一项法令是从头开始构建蜂窝架构的所有服务。所以我得以体验构建这些服务,这真是令人难以置信,仅仅考虑减少爆炸半径就能在提高整体可用性和改进服务设计方面取得多大的进步。
是的,我记得在过去,不仅仅是 US East 1 本身,还有 US East 1A。特定的 AZ 比其他 AZ 大得多,同样是因为它是默认设置。不知何故,我认为 Corey Queen 曾经开玩笑说,如果你想运行混沌实验,只需将你的工作负载部署到 US East 1 即可。是的。
因为本质上,它会这样做,因为与其他区域相比,所有故障都将发生在那里。我记得,大约七八年以前,他们开始改组不同的 AZ,这样你的 US East 1 就不是我的 US East 1 了。这样,他们能够,我想,再次将客户转移到不同的 AZ,这样他们就不会都集中在 US East 1A 上,这再次是每个人的默认 AZ。
因此,在这种情况下,经常出现的一个问题是蜂窝架构与微服务有何不同?我想根据你的描述,蜂窝架构基本上是获取你的一个微服务,但部署它的不同
副本,然后你将不同的客户放入这些单元中,这样当一个客户正在做一些疯狂的事情时,他们可能是一个吵闹的邻居,但他们将成为 10 个其他客户的吵闹邻居,而不是同一区域中的所有其他客户。这就是你将客户划分为不同的分组,而不是将你的应用程序划分为不同的服务(就像微服务一样)的想法吗?
我认为这是一种思考方式。我认为你用微服务击中了要害。通常,当你想到微服务时,存在一些异质性,对吧?存在各种各样的微服务。蜂窝化是为了获取相同的服务,然后将其分解成许多单元。而且
这里的主要价值主张是减少单元出现故障时发生的情况的爆炸半径。单元出现故障的原因有很多。可能是糟糕的客户或客户度过了糟糕的一天。可能是因为你进行了一次糟糕的部署。所有这一切,再次回到减少爆炸半径,然后为团队提供工程约束,这就是你期望你的单元达到的大小。
这就是人们蜂窝化的原因。这里的想法是您可以蜂窝化并将客户放入特定的单元中。出于许多原因,这是一个好主意。它可以帮助您更好地进行容量规划等等。但是,如果您真的全力以赴地采用蜂窝架构,您可以达到将最大的客户放入他们自己的专用单元中的阶段。
如果您从一开始就这样做,这实际上会在许多方面帮助您。这就是 Momento 进行蜂窝架构的方式与典型的 AWS 团队进行蜂窝架构的方式之间的一个区别。AWS 团队在一个给定的单元中会有很多客户,他们的工作是提高每个单元的利用率。Momento 的做法是,对于我们最大的客户,我们为他们提供他们自己的专用单元,
我们自己和 AWS 的单元都是多租户的,多租户可以帮助您提高实现等等。在我们的案例中,我们的客户通过利用其自身组织内的多租户来受益于提高的实现,并且我们可以根据特定客户的情况进行权衡,例如如何运行特定的单元。
因此,拥有这种蜂窝架构允许您在不同的客户之间拥有自由度,如果您真的全力以赴的话。从根本上说,每个蜂窝架构的底部是如何快速部署客户?
根据客户的需求进行单元部署。拥有一个真正良好的 CodeStack 基础设施可以使您灵活地为每个客户部署一个单元,而无需花费工程师数周时间为每个区域或任何其他内容构建一个单元。
对。这是我认为 AWS 经常谈到的多租户策略之一,即每个租户基本上都会获得同一应用程序的副本。那里一直存在的一个权衡是,好的,现在您必须投入更多工作到自动化中,并确保当您推出代码更新时,
它将快速部署到所有客户。好的,当一个租户、一个单元未能更新时,您该怎么办?那时你该怎么办?这些都是一些,我想,你们遇到的一些现实世界的问题,例如部署时间非常长,因为有很多不同的
当可能出现一些问题时,您该怎么办?您不知道这是否与新的代码更改有关。您会继续吗?您会回滚吗?你们遇到过哪些现实世界的问题?是的,我认为亚马逊也遇到了这个问题。我们在更小的规模上遇到了这个问题。当亚马逊在早期只有少数几个区域时,而且
我们在如何设计部署、如何进行分阶段等等方面做出的权衡,当您有五个区域时有效的权衡在您有五打区域时不起作用。我们现在正在遇到一些这样的问题,因为,你知道,如果你正在放置……
一天的烘焙跨越您的每个阶段,现在您的阶段要么变得非常非常宽,要么需要几周时间才能部署软件,才能进行前向部署。因此,蜂窝化会增加单元数量,但实际上会大大减慢您的部署速度。
这是一个大问题。这里的挑战是,如果您过度纠正并说,好的,我现在一次只部署到 50 个单元,那么
您也破坏了减少爆炸半径的目的,对吧?所以你又回到了同样的问题。因此,您必须非常非常注意蜂窝架构的部署策略。我们开始对 AWS 租户提出一些质疑的另一个方面是,随着我们发展我们的旧蜂窝立场,AWS 将每个单元放在其自己的帐户中。这是内部最佳实践。这是一个非常好的实践。但是,你知道,
如果我必须登录或如果我必须跟踪我的资源跨越许多帐户,那么随着您开始达到,你知道,接近 100 个单元,这将变得非常具有挑战性,例如现在您必须找到帐户,您必须确保您在正确的帐户中。
您正在执行的任何诊断,跨车队的容量管理,这将变得越来越具有挑战性。因此,我现在可以从我的浏览器在控制台中登录多个帐户的新功能对我们非常有用。但即便如此,
处理帐户数量确实很困难。因此,我们现在开始质疑,我们是否真的希望每个单元都在其自己的 AWS 帐户中,或者我们是否希望在部署更改单元方面做得更好,但要坚持在,你知道,沿途拥有更少的 AWS 帐户?
是的,我也听说过 AWS 内部最佳实践,即安全团队只信任帐户边界作为他们完全信任的唯一边界。这是必须将所有内容部署到其自身帐户的唯一原因吗?它回到了爆炸半径。因此,想象一下,如果帐户被劫持或如果帐户被删除……
出于任何原因,或者有人进行了一次糟糕的部署,他们重置了帐户的密码或删除了帐户中的所有 Dynamo 表,对吧?就像任何东西一样,希望您有多个,因为 FTD 的爆炸半径非常糟糕,例如单表设计。但无论如何,关键在于
它是一个非常好的隔离边界,用于减少爆炸半径。一次糟糕的部署不会弄乱其他任何东西。现在,帐户边界充当命名空间。因此,在我的每个单元中,我可以拥有一个名为
控制平面元数据或任何其他内容的 Dynamo 表,这完全没问题。而如果您将每个单元、多个单元保留在同一个帐户边界中,那么您必须将其名称与之关联。然后您的访问控制会变得有点棘手,因为现在您必须为每个部署创建 IAM 策略,以便特定帐户只能访问其资源等等。因此,事情会
如果每个人共享同一个帐户,那么强制执行和减少爆炸半径会变得更具挑战性。这就是权衡变得更加令人兴奋和有趣的地方。好的。而且,即使你们正在进行多区域应用程序,每个区域都必须位于不同的帐户中,这是真的吗?所以它不仅仅是多区域,而且也是多区域和多帐户?
是的。每个区域都应该有多个单元,每个单元都应该有其自己的帐户。这在今天的 Momento 中也是如此。例如,我们在许多区域中拥有许多 AWS 帐户。
我们遇到的另一个现实世界的问题是限制。我们创建一个全新的帐户。然后今天,我实际上非常自豪于我们的基础设施即代码功能。我们可以在一小时内启动单元,但将其投入生产需要更长的时间。为什么?因为我们正在等待门票来提高我们对新帐户的限制。
哦,是的,还记得那些日子吗?每次您打开一个新帐户时,都会有一堆狐猴。您对 EC2 和 VPC 以及所有其他内容都有速率限制。我总是想知道的另一件事是蜂窝架构,我的意思是,对于 AWS 来说,当给定服务从未真正完全关闭时,考虑 SLA 和可用性已经非常困难,因为它始终在其他区域可用。是吗?
但是当您在同一区域内有多个单元时,您如何开始推断 SLA 和正常运行时间,尤其是在违反 SLA 时涉及金钱退款和信用额度时?您必须在单元级别还是客户级别执行此操作?或者这只是您在此类服务级别或区域级别进行衡量的指标?
我们必须在客户级别衡量 SLA。我以艰难的方式了解了这一点。我过去经常做得很糟糕。我记得我出现在 Dynamo 的年度规划会上,我们非常自豪地说,嘿,去年,我们已经达到了 100%,就像我们达到了 100% 的车队范围 SLA 一样。
EBS 团队在房间里,我认为是 David Richardson 举手说,胡说八道,那不是真的。我们知道我们受到了你们的影响。这对我来说真是大开眼界,因为他完全正确。Dynamo 团队发生的事情是街区范围的错误率
很好。它们始终低于我们在内部采用的 99.99% 的 SLA。但是,从客户的角度来看,如果单个分区出现故障,即使它是该区域中数十万个分区之一,该客户也会受到重大影响。因此,虽然作为 Dynamo 团队,我们可以说,“是的,我们赢了。车队范围的错误率非常低。”
该客户显然没有被我的团队拥有的内部 SLA 代表。因此,我们很快转向基于每个客户和每个表来衡量 SLA。这是我们在 Memento 中一直坚持的教训。因此,您需要根据每个客户的基础来衡量您的可用性和错误率。您需要根据他们的经验而不是您的车队范围经验,为他们商定的 SLA 提供金钱补偿
好的。因此,既然我们已经对蜂窝架构进行了介绍,我想谈谈你们与那个疯狂客户发生的特定事件。
我不会称他们为疯狂。疯狂的规模。是的,疯狂的规模。我的意思是,这是多租户架构的力量。看,如果您在 Dynamo OnDemand 和 S3 上部署您的服务,并且每秒发出数百万个请求,那么它很可能会工作。但是,如果您自己编造了一个基于 EC2 的框架,并且面临着意外的峰值,
您很可能会完蛋。因此,这些多租户无服务器服务,它们在处理规模方面要强大得多。为什么?因为您可以执行的任何峰值,我们可能都见过,对吧?因此,如果您今天出现并开始在一个 Dynamo 表上运行 1000 万 TPS,您将不是第一个。整个系统已经过多次架构设计和测试。
反复地为它。这就是这些大型多租户系统的关键价值主张。在我们的案例中,一位客户度过了美好的一天。他们是一家游戏公司。他们度过了美好的一天,他们的流量从 10,000 TPS 上升到超过 100 万 TPS。有趣的是 Prateek,他看到了这一点,他值班,他刚刚醒来,他
他意识到,好的,但是当他在早上醒来时,一夜之间发生了这个巨大的峰值,我们甚至没有……
注意到它。这很好。我的意思是,对于像我们这样的公司来说,这是一个很大的变化,因为过去,每当客户出现峰值时,我们都希望知道他们何时预期这些峰值。而且,你知道,我们努力工作。我们会确保一切准备就绪,我们已经进行了负载测试等等。现在它正达到这样的程度,哦,酷,你做得很好。
几百万 TPS,我们吸收了它,我们甚至没有注意到。有时,对吧,当我们启动服务时,如果使用量超过某个阈值,我们的警报就会响起,只是为了让我们注意,即使没有问题,只是为了让我们……因为如果客户的峰值如此之高,那么这可能是他们非常关键的时刻,我们不想让他们失望。但这确实是一个令人欢迎的变化。现在,我们所有人中偏执的操作员
也不会让它过去,对吧?例如,好的,您超过了 100 万 TPS。车队表现如何?我们遇到了哪些极端情况?我们观察到,嘿,我们的 P99.9 延迟确实增加了 200 微秒。因此,我们开始深入研究,好吧,为什么?这不像我们受容量限制,但为什么?
这些延迟会上升。而且,你知道,这开始了关于深入研究指标并提出五个为什么的对话,直到你找到性能问题的根本原因,即使没有主要的可见客户影响,因为这就是你持续改进服务的方式。
对。在这种情况下,使用您的架构,我的意思是,使用一个单元,该单元的范围有多远?我的意思是,对于微服务,您有,你知道,每个服务都有自己的部署、自己的集群等等,自己的数据库,但是仍然存在不同服务之间的通信。
因此,如果您正在获取您的服务之一并部署该服务的不同单元,您仍然必须与其他服务进行通信。服务之间仍然存在这些相互依赖关系。那么您如何,我想,协调这一点呢?单元是否必须与另一侧的特定单元进行通信?或者这仅仅取决于路由或基于其他服务将拥有的客户 ID?
你知道,不同集群的销售商网络,它们将根据客户 ID 或其他内容进行路由到正确的位置。是的。因此,今天,Memento 单元是自包含的。因此,作为参考,您可以将我们视为缓存集群。我们有一个,你知道,这是一个两层架构。有一个路由集群和一个存储集群。而且
单元不会,今天没有跨单元通信。当我们构建跨区域复制等内容时,我们可能会拥有它。但就目前而言,一个单元是完全独立的,只能与内部的资源进行通信
单元本身,因此请求进来,路由集群终止请求,然后根据身份验证后将请求发送到存储节点,对客户进行身份验证,查找他们可以访问的缓存的元数据,授权他们的请求,然后……然后将其发送到特定……方向……
但是,当您开始考虑扩展自己时,你知道,我们是一家水平缓存、水平扩展公司。垂直扩展对您可以扩展其水平方面的程度有很大影响。我们为我们的工程师提出了一个非常具体的工程要求,那就是能够处理,你知道,
你知道,单元中的 100 个路由器,并且能够处理至少 100 个分区,每个分区将有一些副本。这就是我们开始的方式。今天,我们的,并且只有 16 个核心,我们的路由集群每秒处理几万个 QPS 以上。所以,
100 个节点可以获得 2000 万 QPS,假设负载均衡完美。因此,单个单元上大约 2000 万 TPS 是我们所遵循的工程约束。我们的存储节点也是如此。它是 200,000。这是一个我们已经走了很长的路程的数字。当我们在 Java 世界中运行时,每个节点的数字是 20K。我们为此使用了四个 XL。现在我们,你知道……
使用 2x 单元并执行数十万 TPS。但这个想法很简单。现在,我们对单元的大小(从物理节点的角度来看)施加了工程约束,然后我们非常努力地驱动每个节点可以做什么,以便我们可以处理更大的水平扩展。客户出现并想要超过 2000 万 TPS,我们很可能会告诉他们将它们拆分为多个单元
对,明白了。好的,当你说 QPS 时,那是每秒查询数,基本上是路由层的 TPS。好的,在这种情况下,我忘记了我正在使用哪个服务。我认为它是 Timestream 服务,作为 SDK 的用户,您必须选择要连接的单元。当您说客户想要执行 2000 万 TPX 时,他们必须做出有意识的决定时,这就是您的意思吗?
哪个请求转到哪个单元。这就是你的意思吗?
是的,我的意思是,我们还没有遇到超过 2000 万 QPS 的客户。因此,如果有人出现或 TPS,例如如果有人出现并想要执行 1 亿,我们很可能会让他们分开。在我们的世界中,蜂窝信息也烘焙到请求令牌中。因此,我们为您提供的 JWT 包含所有这些信息。因此,每个单元都有其自己的。再次,它是完全自动化的。
完全隔离,完全独立。因此,您今天的令牌也不适用于这些单元。因此,您将为每个单元拥有不同的令牌,这就是您决定转到哪个单元的方式。好的,明白了。
我的意思是,因此,请记住,当涉及到蜂窝架构时,您会遇到所有这些额外的复杂性,您会在哪里说,我想,当有人应该考虑时,阈值是什么,好的,当我们构建服务时,我们应该使用蜂窝架构构建它,而不是仅仅,你知道,试图将每个人都挤压到一个集群中,本质上。我认为……
我们很幸运,因为我们在早期就开始进行单元化了。我遵循的一个生活原则就是,你明天总是会更忙。所以总是会有这样的诱惑:让我把这件事做完,然后再回头处理单元化的问题。所以,如果你有多个客户,并且你打算在多个区域部署,你
即使你将最初的服务建模为单个单元,这也很值得,因为这会在你的设置中养成良好的习惯,拥有正确的基础设施即代码,拥有正确的部署设置。所有这些在开始时投资都是非常有帮助的,而且更容易投资。这让你保持专注。当你从单个单元过渡到第二个单元时,你就会开始做出决策
你知道,你的部署会发生变化,而且,你知道,你也会有你的暂存环境等等。在我们的例子中,我们的开发环境就是一个单元。所以 Momento 的每个开发人员都可以访问他们自己的单元,他们只需运行他们的 CDK 脚本即可创建。我们的暂存环境也是一个单元。我们的负载测试环境也是一个单元。
每个区域都有多个单元,这对我们来说是一个巨大的生产力提升。而在 Dynamo,至少在我还在 Dynamo 团队的时候,我们过去常常有专门的区域或部署,开发人员会签出
然后说,“嘿,大家好,我要去处理这个集群了,其他人不要碰它。”而我们在 Memento 对单元化的投资已经得到了回报,每个开发人员都可以随时启动他们自己的单元。
是的,很有趣,因为你谈论的基本上就是我一直向我的学生传授的关于短暂环境的内容。我不称它们为单元,但本质上是,同样,它只是你可以在自己的堆栈中启动的整个应用程序的副本,但你可以有多个堆栈。
因此,你将在他们自己的帐户中拥有你的主要开发测试暂存生产环境。但在你的开发帐户中,你只需启动应用程序的副本,你的服务用于单个开发人员或功能或 CICD 管道运行,以便在管道开始时,你创建新的
临时环境,你针对该环境运行所有测试。完成后,你将其拆除,这样你就不用担心用测试数据污染你的主要开发环境,每个开发人员和每个功能都有自己的环境或单元。所以感觉或多或少是一样的想法,所以如果你有你的基础设施即代码,对吧,这样你就可以,你知道,
确保你始终将阶段名称或环境名称或单元名称作为资源名称的一部分,以便你始终可以判断,好吧,即使我有相同 down DB 表的多个副本,它们也属于不同的单元,以便我可以……
然后在其中,我仍然可以进行多租户,以便我可以遵循使用租户 ID 作为哈希键并进行租户级 IAM 权限等的相同实践,以便我仍然可以使用这些技术。但是然后我可以创建我的应用程序的不同副本作为不同的单元,以便当我需要时,我可以然后
将所有这些整合在一起,创建不同的单元并按单元进行扩展,而不是仅仅创建越来越大的 down-db 表、认知用户池等等。这是一种非常有趣的思考方式。我还没有真正将两者联系起来,尽管现在你提到了,它基本上是一样的东西。绝对是一样的东西。我只是分享一个不同的视角。你称它们为短暂环境。我认为这是这些环境的一个属性。另一个属性是它们是隔离的环境。
对吧?它们是隔离单元,而单元是一个隔离单元。当然,短暂性很好,因为它只是暂时的,但是,你也可以拥有相同的,比如如果你的学生有一个短暂的环境,但他们想永远保留它,那将是一个单元。对。是的,正是因为隔离。本质上,它是一个永久性环境,但它使用的是构建短暂环境的相同技术和技巧。
没错。如果你构建了这个短暂的环境,那么你的负载测试就会更容易,你再现问题的能力就会更容易,你的开发能力也会更容易。这是一件非常值得的事情。我不断回到这一点,就像,你进行单元化的原因是减少爆炸半径。而你做好单元化的方式是投资基础设施即代码。
是的,同样,对于无服务器,按使用付费的定价模式也是如此,其中一个好处,我认为至少对我来说,这种做法之所以在无服务器中变得越来越普遍的原因之一是,无论你拥有 10 个相同应用程序的副本还是一个副本,你都只为你的使用付费。如果你正在进行 100 个请求,那么这 100 个请求是在一个环境中还是在 10 个环境中进行的,这并不重要。成本相同。
对于相同应用程序的不同冗余副本的额外正常运行时间没有成本。
绝对正确。基于消费的环境对我们非常有效。事实上,当客户迁移到我们这里时,他们节省资金的最佳方式之一就是他们不必在其暂存环境和开发环境中都拥有完全预配的资源。他们只需在实际运行测试时才为这些资源付费。
好的。是的,这对我来说是一个开阔视野的时刻,就思考单元架构而言。我想在这种情况下,你们已经处理了一些相当大的负载了。除了“好吧,你应该始终从单元架构开始,以便至少在你需要开始推出第二个单元和第三个单元等等时做好准备”之外,你们还学到了哪些经验教训?
是的,我认为要尽早进行投资。朝着单元架构投资的最佳方式是投资你的基础设施即代码管道。
和你的可观察性管道,因为你拥有的单元越多,可观察性实践就越重要,而且它会在以后得到回报。另一部分,作为我们的现实世界经验,很多都与性能调整和环境扩展有关。我们学到了很多关于如何省钱以及如何提高效率的知识。而且
有时关注这一点实际上会提高你的性能和你能够处理的规模。我们正在学习各种各样的东西
不同的 EC2 实例类型的流程更好。就像我们遇到的客户非常依赖网络,但他们不消耗任何 RAM。他们只是有一些键,他们只想在他们的海量数据中尽可能快地击中它们。所以,你知道,对于那些,比如有一个 C7 GN 实例。如果你使用它而不是 R7,你
你会浪费所有这些额外的 RAM,因为它们有更多的网络,c7gn 的 RAM 只有四分之一,但网络比 r7g 多得多,所以要非常仔细地考虑实例类型,然后如果你有基础设施即代码,就像我认为我们做的那样,我们做到了,你知道,我们并不完美,但我们进行了大量投资
不同的单元根据这些单元的特性运行不同的实例类型。因此,我们在某些区域将我们的路由集群作为 C7GN 运行,在其他区域将 C7Gs 运行,这完全没问题。好的。除了为每个单元选择正确的 EC2 实例之外,你还学到了哪些具体的优化方法,也包括路由器层?
是的,我们在减少从路由到存储的额外跳跃的成本方面做了很多工作。我们花了很多时间,我们用 Rust 重写了我们的整个服务。在那里学到的最大教训之一是,当我们从 Java 迁移到 Rust 时,
我们处理负载的能力不相上下。我们可能增加了 5%。但随着时间的推移,当你开始在单个节点上处理数十万次每秒的事务时,这就是核心固定和流路由等技术实际上可以帮助你使盒子越来越热的地方。
其他技术,包括放置组,如 AWS 放置组,被严重低估了。它最初是一个高性能计算结构,但基本上,如果你希望节点紧密地组合在一起并在彼此之间具有低延迟,你可以将它们放在集群放置组中,这有意义地,你知道,它会将你的延迟降低到两个节点之间的几十微秒,这听起来……
微不足道,但当你试图在极少量的连接上在两个节点之间驱动大量吞吐量时,它确实会发挥作用,对吧?因为往返延迟实际上会减少你可以在单个连接上执行的 TPS 数量。所以放置组、核心固定、
并且在我们将整个堆栈从 Java 重写为 Rust 之后,流路由很有帮助。
好的。我听说过核心固定。所以这主要与尝试最大化你的缓存亲和力有关,这样本质上同一个用户再次访问你。你转到同一个核心,你很可能已经获得了一些数据在 L1 和 L2 缓存中了。所以这就是核心固定的想法。我以前没有听说过流路由。那是什么?是的。所以核心固定更多的是为了确保……所以看,我们有……
假设你有一个 8 核 Graviton 实例。我们将做的是为我们的线程运行其中的六个核心,然后我们会说,“嘿,线程,不要离开这里。”但真正重要的是还要说,“嘿,内核,你的网络只发生在这两个核心上。”
因为当你开始在同一个节点上处理过多的数据包时,数据包中断实际上会破坏任何东西,比如它会导致正在为你执行有用工作的核心发生上下文切换。
所以真正的核心固定不仅仅是固定你的线程,还包括内核,特别是网络中断,RAQs 也要固定到特定的核心。流路由只是意味着,嘿,就像你可以说,“嘿,
这个核心将继续处理来自同一个用户的请求。”你可以根据端口和 IP 地址(例如,对于源)来执行此操作。这样你就不会一遍又一遍地将你的东西交给同一个用户的不同线程,因为他们来回发送更多数据。
这在线程只是互相窃取工作等等的不同架构中变得越来越重要。但是流路由要困难得多。如果你想优化,首先选择正确的 EC2 实例,查看放置组,然后进行核心固定。你可以在同一天内从头学习并部署核心固定。
但只有当你真的让你的机器很热的时候才有用。如果你真的每秒进行 10 万次以上的事务,核心固定会有很大帮助。对。我实际上把我们两个搞混了。我当时认为是核心固定实际上是流路由。而核心固定是我认为早期和运行时用户所做的工作,因为他们只运行与 CPU 中的核心数量一样多的并发线程,这正是为了最大限度地减少 CPU 时间用于上下文切换过程的百分比。
没错。我认为一些 Java 框架通常也这样做,这正是出于同样的原因,试图最大限度地减少上下文切换的数量。好的,这真的很酷。那么关于……
Rust 本身,因为你谈到的技术同样也适用于 Java 和其他语言。如果你像你说的那样,仅仅从 Java 切换到 Rust 没有获得那么多的收益,那么 Rust 的具体有什么特别之处呢?我知道 Evan 谈到 Rust 的高性能,所有这些。但在你的经验中,从 Java 切换到 Rust 的最大收获是什么?
你可以在 Rust 中编写非常慢的代码。这就是现实。因此,不要指望仅仅通过用 Rust 重写你的应用程序,特别是对于复杂的应用程序,突然之间一切都会变得快得多。看,我们的团队充满了 Java 专家。而且,你知道,我们已经花费了我们的一生来调整 GDM 以使其能够做任何他们能够做的事情。
我们在公司中间从头学习 Rust,对吧?所以我们,有很多我们不知道的技术。而且,你知道,像,
Rust 库中也存在问题,例如,我们在 Rust 中的 HTTP 库中积极讨论的问题,在某些情况下,它实际上可能比 Java 慢。所以……
归根结底,你不会得到……性能没有简单的答案。你仍然必须分析你的应用程序。你仍然必须找到争用点。你仍然必须处理多线程优化等等。所以这不是一个简单的答案。你必须不断调整……
从经过良好调整的 Java 环境迁移到 Rust,你可能不会立即获得很好的结果,因为你可能还不了解 Rust 中的所有技巧和窍门。这是一段值得的旅程。它只是需要实际的投资才能改进。
是的,我希望更多的人能谈论这个问题。我认为很多人谈论 ROS 的方式就好像它是银弹,是你可以洒在你的应用程序上的魔法粉尘,突然之间它就会快 10 倍一样。我的意思是,当然,如果你只是做一个 hello world 类型的应用程序,就像,是的,它很快。但是,你知道,当应用程序更复杂时,事情就会变得复杂。
是的,绝对正确。绝对正确。是的,我认为这就是我所有的问题。在你走之前还有什么想补充的吗?任何事情,我想,Memento 还有什么新的事情发生吗?我知道你们之前谈到过 Object。进展如何?
进展非常好。我们一直在研究我们最喜欢的服务 S3,并在其之上添加缓存。我们发现各种新的用例,尤其是在 AI 领域,关于需要在新鲜时非常快但需要长期持久化的临时数据。而 S3 非常适合这种情况。
低成本的持久性,具有非常非常高的吞吐量。然后 S3 加上 Momento 就像最佳搭配一样,你知道,这是一个非常好的搭配。所以我们对此感到兴奋。我们喜欢与那些有深度性能优化需求的客户交谈。无论是否与 Momento 有关,我们仍然想与人们交谈,因为我们
然后我们向他们学习,然后我们允许我们的客户从中受益。所以如果有人想深入了解分布式系统性能问题,我很乐意抽出时间向你学习。
是的。在这种情况下,如果有人想联系你并与你交谈,最好的方式是什么?是在 X 还是 Twitter 还是 LinkedIn 还是其他地方?是的,我正要说是 Twitter,但是是的,你可以在 Twitter 上找到我,KSSHAMS 或 LinkedIn。我认为我的私信在两者上都是开放的。给我发个便条就行了。然后 Momento 在 gomomento.com。所以去吧。
你也可以在 Believe in Serverless Discord 上找到我。所以 believeinserverless.com,只需加入 Discord 社区即可。这是一个非常活跃的环境,拥有超过一千名成员,他们互相帮助成长。在那里我学到了很多东西,我很乐意在那里结识更多的人。
是的,我会在下面的描述中添加链接。我必须说 Believe in Serverless 社区很棒。我真的很喜欢跳进去,偶尔跳到一个主题上,谈论人们遇到的问题,因为有一些非常……
有才华的工程师,经验丰富的开发人员正在贡献并互相帮助。很棒。如果你想学习无服务器,但又想享受谈论人们可能遇到的更复杂、更复杂的问题的乐趣,这是一个非常好的地方。绝对正确。而且没有狂热者。每个人都互相支持。所以即使你对你的 Kubernetes 集群有疑问,也请提出来。我们会帮助你的。
好的。好的。是的。感谢你再次加入我们。我希望在接下来的几个月里,也许在西雅图见到你。是的,下次我会和你们聊天的。保重。谢谢,Sean。
这就是另一集 Real World Serverless 的全部内容。要访问节目笔记,请访问 realworldserverless.com。如果你想学习如何构建可用于生产的无服务器应用程序,请查看我在 productionreadyserverless.com 上即将推出的课程。下次见。