传统方式下日处理十亿笔事务的系统可能需要数百台虚拟机,PayPal只用8台虚拟机就做到了这一切,CPU占用率高达90%时依然可以提供快速响应,这种PayPal以往从未达到的事务处理密度,实现过程所需时间只是传统方法的1/10,在降低成本的同时无须为计算基础架构扩容即可帮助该组织顺利应对增长。这是怎么做到的?
PayPal已将系统迁移至基于Akka的Actor模式。在Squbs:PayPal采用全新的反应式方法构建应用程序这篇文章中,PayPal介绍了整个过程的来龙去脉。目前他们已将Squbs开源并发布至GitHub。
当项目需要采取一种做实事的方法时,有状态的服务模式依然没能获得足够重视。若要进一步了解有状态服务,建议阅读当下继续构建可扩展有状态服务的理由,这篇文章是根据Caitie McCaffrey的讲话撰写的。如果这篇文章还不能让你信服,还有使用Akka的竞品Erlang实现极高吞吐率的WhatsApp:Facebook斥资190亿美元所购买的WhatsApp体系结构。
推荐上述文章的原因在于,PayPal这篇文章对体系结构的介绍不详尽,而是用了较多篇幅介绍导致他们选择Akka的原因,以及迁移至Akka所获得的收益。但这篇文章依然为“不走寻常路”的做法提供了宝贵的激励和示范。
为服务使用大量虚拟机,这种做法有什么问题?
- 使用吞吐率非常低,极小规模的虚拟机运行服务。基于Actor的反应式系统最大的亮点在于可以更高效地利用计算资源,这样即可大幅缩小系统规模,避免传统做法下“简单粗暴”的自动伸缩。
- 会对网络和路由基础架构造成极大压力。由于服务趋向于更高程度的互联,请求可能需要经历大量网络跃点,这会增加延迟并降低用户体验。
- 越大越贵。包含数百个虚拟机的服务在管理、监控,以及无效缓存(Ineffective caching)等方面存在极高的固有成本。
- 越小越敏捷。将服务部署到数百台虚拟机,这个过程将花费大量时间。
- 更充分地利用每台虚拟机上更多CPU。由于CPU无法进一步提速,基础架构需要能更高效地利用每台虚拟机上装备的更多CPU。
- 需要通过易于维护和快速构建,并且松散耦合的NanoService构建微服务。谁都不想面对包含大量层面的复杂体系,你需要对不同服务的作用获得更高能见度,而无须深入到层层叠叠的代码中。
考虑到上述因素,PayPal希望搭建一套具备下列特征的系统:
- 可缩放,不仅要能横向缩放至数百个节点,还要能纵向缩放至更多处理器,借此实现每天处理数十亿请求的目标。
- 低延迟,可以通过极为细化的粒度进行控制。
- 面对故障具备弹性。
- 可灵活调整服务边界。
- 通过编程模型和企业文化促进可缩放能力和简易性,以及更简洁的故障和错误处理机制。
毫无疑问PayPal希望使用更“瘦”的堆栈,他们不想自己的堆栈包含大量不同层面的技术和活动部件。通常来说,Akka和基于状态的系统很适合这一需求,这种方式可将包含大块组件的堆栈“分解”为某种单一技术。PayPal选择Akka而非Erlang的原因在于他们对Java有更丰富的经验,而Akka就是在Java的基础上运行的。对很多人来说,从零开始学习Erlang并不现实。
借助Akka他们可以:
- 编写更易于解释的代码
- 编写更易于测试的代码
- 相比使用JVM的传统模式,更自然地处理错误和故障场景
- 编写更快速、更具弹性、更简单的代码,以更流畅的方式处理错误,减少Bug数量
于是PayPal立刻以Akka为基础编写了自己的框架,这个框架名为Squbs,使用该名称是为了与“Cubes”保持押韵。借此可为名为“Cube”的NanoService的构建创建模块化技术层。Cube是相互对称的,不同Cube之间的依赖性也是对称且松散的,只暴露出Akka已经提供的消息接口。
该文还介绍了程序员在采用Akka代码时,此类代码非线性的本质可能造成的困难,因此你可能还需要雇佣接受过Akka/Scala相关培训的人员。
由于大部分服务的用途较为类似:接收请求,调用并读写数据库,调用其他服务,调用规则引擎,从缓存中获取数据,写入缓存… 因此可以通过类似Orchestrator Pattern和Perpetual Stream等模式对服务进行抽象。
Squbs已成为PayPal构建基于Akka的反应式应用程序的标准做法。如果你的团队尚未考虑过有状态系统,也许这种做法值得一试,毕竟这种做法在PayPal、Facebook、Uber,以及微软都取得了不错的效果。
作者:Todd Hoff,阅读英文原文:How PayPal Scaled To Billions Of Transactions Daily Using Just 8VMs