Pinterest大规模缓存集群的架构剖析_第1页
Pinterest大规模缓存集群的架构剖析_第2页
Pinterest大规模缓存集群的架构剖析_第3页
Pinterest大规模缓存集群的架构剖析_第4页
Pinterest大规模缓存集群的架构剖析_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Pinterest大规模缓存集群的架构剖析随着越来越多的用户到Pinterest寻求灵感,Pinterest核心基础设施系统的需求增长的比以往任何时候都快。我们的核心存储系统之一是位于许多微服务和数据库前面的分布式缓存层。它处于Pinterest基础架构技术栈的底部,负责吸收由用户增长驱动的绝大多数后端流量。Pinterest的分布式缓存集群建立在AWS的EC2实例上,由数千台机器组成,缓存了数百TB的数据,高峰时,每秒可处理1.5亿个请求。该缓存层通过降低整个后端技术栈的延迟,来优化顶层性能,并通过减少昂贵的后端所需的容量来提供显著的成本效率。本文中,我们将对支持Pinterest的大规模缓存集群的架构进行深入的技术研究。1应用数据缓存每个对Pinterest的API请求都会在内部根据技术栈分发到复杂的RPC树,并在完成其关键路径前会涉及数十个服务。这可能包括查询关键数据(例如Pinterest的图片和收藏板)的服务,推送相关图片的推荐系统和垃圾内容检测系统。在这些服务中,只要其输入数据可以被唯一键值表示,就可以将该离散的查询单元的结果缓存在临时存储系统中,以便将来重用。在Pinterest,分布式缓存层的最常见用途是通过后备语义(look-asidesemantics)来存储这类中间计算的结果。这使得缓存层能吸收一大部分流量。如果没有缓存层,这些流量会流向涉及复杂计算和昂贵存储的服务和数据库。凭借着毫秒级的尾延迟(taillatency),以及极低的单位请求基础架构成本,这个分布式缓存层提供了一个高性能低成本的后端扩展机制,以满足Pinterest不断增长的需求。简化版的Pinterest的API请求生命周期:经过主要API服务,其依赖项后端以及分布式缓存层。通过提供分布式缓存层即服务,应用开发人员可以专注于实现业务逻辑,而不必担心分布式数据的一致性、高可用性或者内存容量。缓存层用户使用通用的路由抽象层,以确保应用程序具有容错性和一致的数据视图。此外,缓存服务端集群可以独立于应用层横向扩展,从而透明地调整内存或吞吐量,以适应资源使用情况的变化。2分布式缓存的骨干:Memcached和McrouterMemcached和mcrouter构成了Pinterest分布式缓存基础架构的骨干,并且在Pinterest的存储基础架构中起着至关重要的作用。Memcached是由纯C语言编写的开源且高效的内存键值存储。Mcrouter是应用层的Memcached协议代理,位于Memcached集群的前面,并提供强大的高可用性和路由功能。Memcached是缓存解决方案中非常有吸引力的选择:得益于其异步事件驱动的体系结构和多线程处理模型,memcached非常高效且易于进行横向扩展以满足容量需求。Extstore通过实例的NVMe闪存磁盘上的二级温存储(secondarywarmstorage)层,帮助实现了惊人的存储效率。Memcached精心设计的简单体系结构提供了在其之上构建抽象层的灵活性,以及简单易行的水平可扩展性以满足日益增长的需求。一个Memcached进程本身只是一个简单的键值存储,根据设计,它对其它的Memceched进程的存在毫无了解,甚至没有Memcached集群的概念。Memcached在数十年的开发过程中已经经过准确性和性能的严格测试,并拥有非常活跃的开源社区(该社区还将多个Pinterest提交的补丁合并至上游。)。Memcached自带了对TLS终止功能的原生支持,从而使我们能通过TLS双向身份验证的流量(该过程还额外包括内部搭建的基于SPIFFE授权访问控制)来保护整个集群。Mcrouter在2014年由Facebook开源,在扩展其Memcached部署方面发挥了关键作用。Mcrouter也非常适合Pinterest的架构,原因如下:通过为应用开发人员提供与整个缓存集群进行交互的单个终端节点,Mcrouter充当了Memcached服务器集群的有效抽象。此外,将mcrouter用作整个系统的唯一接口可以确保Pinterest上所有服务和机器之间有通用及全局一致的流量行为。Mcrouter提供了解耦的控制平面和数据平面:Memcached服务器集群的整个拓扑结构被划分为多个“池”(逻辑集群),而管理客户端和服务器池之间交互的请求路由策略和行为均被独立管理。Mcrouter的配置API为复杂的路由提供了强大的基础,包括区域亲和性路由,用于实现数据冗余的复制,多层缓存层和影子流量。作为使用memcached的ASCII协议的应用层代理,mcrouter开放了针对智能协议的功能,例如请求处理(TTL修改、运行中压缩等)。Mcrouter原生地提供了丰富的可观察性功能,并且对客户端应用来说不需要任何成本。这为我们整个基础架构中的Memcached流量提供了详细的可见性。对我们而言,其中最重要的指标包括百分位请求延迟,按单个客户端和服务器维度划分的吞吐量,与键前缀和键模式有关的请求趋势以及用于检测服务器行为异常的错误率。从mcrouter到Memcached的请求路由总览。每个键前缀都与一个路由策略相关联,图中展示了两个例子。在实践中,mcrouter作为边车代理(proxysidecar)被部署在和服务同一机器的单独进程。如图2所示,应用程序(可以由任何语言编写)在回送时将Memcached协议请求发送给mcrouter,然后mcrouter作为代理将这些请求发送到数千个上游memcached服务器。这种架构能使我们在完全托管的缓存服务器集群中构建强大功能的同时,对客户端服务保持完全透明。尽管从Pinterest早期开始,memcached一直就是Pinterest基础架构的一部分,我们对其客户端的拓展策略在这些年来也在不断进化。具体来说,路由和服务发现在最开始是通过客户端库完成的(这其实很脆弱,而且它还与二进制部署紧密耦合)。然后,该方法被内部构建的一个路由代理取代(该路由代理没有提供用于高可用性的基础功能),最终被mcrouter取代。3计算和存储效率Memcached的效率很高:单个r5.2xlargeEC2实例每秒能支持超过10万个请求和数以万计的并发TCP连接,同时不会显着地增加客户端的延迟。这使Memcached成为Pinterest吞吐效率最高的生产服务。这部分归功于编写良好的C语言代码以及其体系结构。该体系结构利用了多个工作线程,每个工作线程独立地运行由”libevent“驱动的事件循环,来支持传入的连接。在Pinterest,Memcached的extstore在存储效率方面取得了巨大的成功,具体的用例包括可视搜索以及个性化搜索推荐引擎。extstore扩展了缓存数据容量,在DRAM之外增加了挂载在本地的NVMe闪存盘,从而将每个实例的可用存储容量从约55GB(r5.2xlarge)增加到将近1.7TB(i3.2xlarge),而实例成本只是略有增长。在实践中,extstore大大优化了数据用量受限的用例,尽管DRAM和SSD响应时间之间有几个数量级的差异,extstore却没有牺牲端到端延迟。extstore的内置调整工具使我们能找到一个平衡了磁盘I/O、磁盘到内存的重新缓存速率、压缩频率和压缩程度以及客户端尾部响应时间的最佳平衡点。4高可用性Pinterest的所有基础架构系统都是高可用的,我们的缓存系统也不例外。通过利用mcrouter提供的丰富的路由功能,我们的memcached集群有着一系列的容错功能:针对部分失控或完全宕机的服务器的自动故障转移。网络本身就是不可靠且有损耗的。我们整个缓存架构假定这是不可改变的事实,在服务器不可用或速度缓慢时也可以保持可用性。幸运的是,缓存数据在本质上是瞬态的,这放宽了对数据持久性的要求,而持久性存储(例如数据库)对数据持久性的要求很高。在Pinterest中,mcrouter会自动地在请求响应缓慢时,或者某个服务器宕机时故障转移到全局共享集群,并且mcrouter还会通过主动的运行状况检查将服务器加入服务池中。通过自动故障转移以及一系列的单个服务器故障的代理层检测,运维人员可以在最短的生产停机时间内识别并更换行为异常的服务器。通过透明的跨区域复制实现数据冗余。我们的关键用例是跨不同的AWS可用区(AZ)进行多集群复制的。这样就可以在完全丢失可用区的情况下实现零停机时间:所有请求都将自动重定向到位于另一个可用区中的运行状况良好的副本节点(replica),在该副本节点中有完整的数据冗余副本。与实际生产流量隔离的影子测试。mcrouter中的流量路由功能使我们可以进行各种弹性测试,包括集群到集群的暗流量以及在实际生产请求中人为加入的延迟和停机时间的测试,而不会影响生产。搜索后端架构师公众号回复“架构整洁”,送你一份惊喜礼包。5负载均衡和数据分片分布式系统的关键功能之一是水平可伸缩性,这是一种可以横向扩展而不是纵向扩展以适应额外的流量增长的能力。在Pinterest,我们绝大多数的缓存工作量都是受吞吐量限制的,这需要集群中实例的数量与请求的数量大致呈线性比例关系。然而,memcached本身是一个非常简单的键值存储,它本身并不会知道集群中的其他节点。那么每秒数亿个请求是如果通过网络发送到正确的服务器上的呢?Mcrouter通过对每个请求的缓存键运用哈希算法,来将请求确定性地发送到池中的某一个主机。这对于在服务器之间平均分配流量非常有帮助,但是memcached有一个独特的要求,即它的集群需要任意可伸缩性,也就是说运维人员要能够自由地根据不断变化的流量需求,来调整集群容量,同时最大程度地减少客户端的影响。一致性哈希确保了在合格分片的总数增加或减少时,大多数键空间分区也可以映射到同一服务器。高度集中和可预测的命中率影响,允许系统在扩展时对客户端透明,从而防止容量的小范围变化导致集群命中率出现灾难性下降。一致性哈希算法保证了当单一节点加入现有集群时,大多数键值空间所分配的服务器不变客户端路由层将单个键值前缀映射到一个或多个这样的一致哈希池,这些一致哈希池位于某个路由策略之后,包括跨可用区复制集群的可用区亲和性偏好路由,针对位于基于闪存的容量集群后方的基于内存集群的L1L2路由(具有穿透)等。这样可以隔离流量,从而按客户端的用例情况来分配容量,并且可以确保来自Pinterest集群中任何客户端机器的一致缓存路由行为。6优劣权衡和我们的考虑所有足够复杂的基础架构系统都具有一个共同特点:充满了(往往非常细微的)优劣权衡。在构建和扩展我们的缓存系统的过程中,我们权衡了许多方案的成本和收益。如下是最重要的几点:中间代理层会产生大量的计算和I/O开销,特别是对于具有严格的延迟SLO并且注重性能的系统而言。但是,mcrouter所提供的高可用性抽象,灵活的路由行为以及许多其他功能远远比性能损耗更重要。全局共享的代理配置会给更改部署带来风险,因为在部署时,所有控制平面更改都会应用到Pinterest的含有数万台机器的整个集群中。然而,这也确保了全局一致的memcached集群拓扑和与之相关的路由策略,无论客户端通过何种方式在Pinterest内何处进行部署。我们管理维护着约一百个不同的Memcached集群,其中,许多集群具有不同的租户(tenancy)特征(专用与共享)、硬件实例类型和路由策略。虽然这给团队带来了相当大的运维负担,但它也允许每个用例达到有效的性能和可用性隔离,同时还能通过选择最适合某个特定工作负载使用情况的参数和实例类型来达到效率优化。在大多数情况下,一致性哈希方案在上游服务器池之间进行负载分配的效果很好,即使在键空间由类似前缀的键簇组成的情况下也是如此。但是,这不能解决热键问题——特定键集的请求量的异常增加仍然会产生因服务器集群中的热分片所

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论