揭秘!Netflix百万用户的键值数据形象层及其设计理念

在 Netflix,咱们为数百万用户提供无缝、高品质的流媒体体验的才干取决于弱小的环球后端基础设备。该基础设备的外围是咱们经常使用多个在线散布式数据库,例如Apache Cassandra,这是一种以高可用性和可裁减性而知名的 NoSQL 数据库。Cassandra 是 Netflix 内各种用例的支柱,从用户注册和存储观看历史记载到支持实时剖析和直播。

随着新键值数据库的引入和服务一切者推出新用例,咱们遇到了许少数据存储误用方面的应战。首先,开发人员很难在这种跨多个商店的复杂环球部署中推断分歧性、耐用性和性能。其次,开发人员必定始终从新学习新的数据建模通常和经常出现但关键的数据访问形式。这些应战包括尾部提早和幂等性、治理具备多行的“宽”分区、处置单个大型“胖”列以及照应分页缓慢。此外,与多个本机数据库 API 的严密耦合(这些 API 始终开展,有时会引入向后不兼容的更改)造成整个组织都在启开工程上班以保养和提升咱们的微服务的数据访问。

为了克制这些应战,咱们开发了一种基于数据网关平台的全体方法。这种方法促进了几种基础形象服务的创立,其中最成熟的是咱们的键值 (KV) 数据形象层 (DAL)。这种形象简化了数据访问,增强了咱们基础设备的牢靠性,并使咱们能够以起码的开发人员上班量支持 Netflix 要求的宽泛用例。

在这篇文章中,咱们深化讨论了 Netflix 的 KV 形象的上班原理、指点其设计的架构准则、咱们在裁减不同用例时面临的应战,以及使咱们能够成功 Netflix 环球运营所需的性能和牢靠性的技术翻新。

键值服务

引入 KV 数据形象服务是为了处置咱们在散布式数据库中面临的数据访问形式的继续应战。咱们的指标是构建一个多性能且高效的数据存储处置方案,可以处置各种各样的用例,从最便捷的哈希图到更复杂的数据结构,同时确保高可用性、可调分歧性和低提早。

数据模型

KV 形象的外围是两级映射架构。第一级是散列字符串ID(主键),第二级是字节键值对的有序映射。此模型支持便捷和复杂的数据模型,在灵敏性和效率之间取得平衡。

Records关于结构化或按期间顺序陈列的复杂数据模型Events,这种两级方法可以有效地处置分层结构,从而准许一同检索关系数据。关于更便捷的用例,它还示意平面键值Maps(例如id → {"" → value})或命名Sets(例如id → {key → ""})。这种顺应性使 KV 形象可用于数百种不同的用例,使其成为在 Netflix 等大型基础设备中治理便捷和复杂数据模型的多性能处置方案。

KV 数据可以在上档次上启动可视化,如下图所示,其中显示了三条记载。

message Item BytesBytesMetadata metadatachunk

数据库有关的形象

KV 形象旨在暗藏底层数据库的成功细节,为运行程序开发人员提供分歧的接口,而不论该用例的最佳存储系统是什么。只管 Cassandra 就是一个例子,但该形象适用于多种数据存储,如EVCache、DynamoDB、RocksDB等……

例如,当经常使用 Cassandra 成功时,形象应用了 Cassandra 的分区和聚类性能。记载ID充任分区键,名目键充任聚类列:

Cassandra 中此结构对应的数据定义言语 (DDL) 是:

     ns idvalue_metadata   id  CLUSTERING    

命名空间:逻辑和物感性能

命名空间定义了数据的存储位置和存储形式,在形象底层存储系统的同时提供逻辑和物理分别。它还充任访问形式(例如分歧性或提早指标)的中央性能。每个命名空间可以经常使用不同的后端:Cassandra、EVCache 或多个后端的组合。这种灵敏性使咱们的数据平台能够依据性能、耐用性和分歧性需求将不同的用例路由到最适合的存储系统。开发人员只要提供他们的数据疑问,而不是数据库处置方案!

在此示例性能中,ngsegment命名空间由 Cassandra 集群和 EVCache 缓存层支持,从而成功高度耐用的耐久存储和低提早点读取。

:{:: {::::: : {: : }}}{:: {::}: {: s}}

KV 形象的关键 API

为了支持不同的用例,KV 形象提供了四个基本的 CRUD API:

PutItems— 将一个或多个名目写入记载

该PutItemsAPI是一个upsert操作,它可以在两级map结构中拔出新数据或许更新现有数据。

message PutItemRequest IdempotencyToken idempotency_tokenstringnamespacestringidListItemitems

如您所见,恳求包括命名空间、记载 ID、一个或多个名目以及幂等性令牌,以确珍重试相反的写入是安保的。可以经过暂存块然后经常使用适当的元数据(例如块数)提交它们来写入分块数据。

**GetItems **—从记载中读取一个或多个名目

该GetItemsAPI 提供了一种结构化且自顺应的方法,可经常使用 ID、谓词和选用机制来失掉数据。这种方法既能满足检索少量数据的需求,又能满足严厉的性能和牢靠性服务级别指标 (SLO)。

message GetItemsRequest StringnamespaceStringidPredicatepredicateSelectionselectionMapString Struct signals

其中GetItemsRequest包括几个关键参数:

该GetItemResponse信息蕴含婚配的数据:

message GetItemResponse ListItemitemsOptionalString next_page_token

DeleteItems — 从记载中删除一个或多个名目

该DeleteItemsAPI 提供了灵敏的数据删除选项,包括记载级、名目级和范畴删除——同时支持幂等性。

message DeleteItemsRequest IdempotencyToken idempotency_tokenStringnamespaceStringidPredicatepredicate

就像在 API 中一样GetItems,Predicate准许一次性处置一个或多个名目:

某些存储引擎(任何推延真正删除的存储)如 Cassandra 因墓碑和紧缩开支而难以处置少量删除。键值提升记载和范畴删除,以便为操作生成单个墓碑 — 您可以在关于删除和墓碑中了解有关墓碑的更多信息。

名目级删除会创立许多墓碑,但 KV 经过基于TTL 的颤抖删除暗藏了存储引擎的复杂性。名目元数据不会立刻删除,而是更新为已过时,并经常使用随机颤抖的 TTL 来错开删除。此技术可保养读取分页包全。只管这不能齐全处置疑问,但它可以增加负载峰值并有助于在紧缩赶上时坚持分歧的性能。这些战略有助于坚持系统性能、增加读取开支并经过最大限制地增加删除的影响来满足 SLO。

复杂的 Mutate 和 Scan API

除了对单个记载启动便捷的 CRUD 之外,KV 还支持经过MutateItems和ScanItemsAPI 启动复杂的多名目和多记载变卦和扫描。PutItems还支持经过火块协定在单个记载中对大型 blob 数据启动原子写入Item。这些复杂的 API 须要细心思考以确保可预测的线性低提早,咱们将在的文章中分享有关其成功的具体信息。

牢靠且可预测的性能设计理念

幂等性可以处置尾部提早疑问

为了确保数据完整性PutItems,DeleteItemsAPI 经常使用幂等性令牌,它可以惟一地标识每个可变操作,并保障操作按逻辑顺序口头,即使由于提早要素而启动对冲或重试也是如此。这在 Cassandra 等最后写入获胜的数据库中尤其关键,由于确保恳求的正确顺序和反双数据删除至关关键。

在 Key-Value 形象中,幂等性 token 蕴含生成期间戳和随机 nonce token。后端存储引擎或许须要其中一个或两个来删除重复的突变。

message IdempotencyToken  generation_timeStringtoken

在 Netflix,客户端生成的干燥令牌因其牢靠性而遭到青眼,尤其是在网络提早或许影响主机端令牌生成的环境中。这将客户端提供的干燥generation_time期间戳与 128 位随机 UUID相联合token。只管基于时钟的令牌生成或许会遭到时钟偏向的影响,但咱们在 EC2 Nitro 实例上的测试标明偏向很小(不到 1 毫秒)。在某些须要更强排序的状况下,可以经常使用 Zookeeper 等工具生成区域惟一令牌,或许可以经常使用买卖 ID 等全局惟一令牌。

下图展现了咱们在 Cassandra 集群上观察到的时钟偏向,标明该技术在可间接访问高品质时钟的现代云虚构机上是安保的。为了进一步坚持安保性,KV 主机拒绝带有较大偏移的令牌的写入,这既可以防止易受这些攻打的存储引擎出现静默写入摈弃(写入的期间戳远在过去)和无法变的末日石(写入的期间戳远在未来)。

经过火块处置大数据

键值对还旨在高效处置大型数据块,这是传统键值对存储的经常出现应战。数据库通常面临每个键或分区可存储的数据量限制。为了处置这些限制,KV 经常使用透明分块来高效治理大数据。

关于小于 1 MiB 的名目,数据间接存储在主后备存储(例如 Cassandra)中,以确保极速高效的访问。然而,关于较大的名目,只要 id 、key和元数据存储在主存储中,而实践数据被分红较小的块并独自存储在块存储中。此块存储也可以是 Cassandra,但具备针对处置大值提升的不同分区方案。幂等性令牌将一切这些写入绑定到一个原子操作中。

经过将大型名目拆分红块,咱们确保提早与数据大小成线性比例,从而使系统既可预测又高效。未来的博客文章将更具体地形容分块架构,包括其复杂性和提升战略。

客户端紧缩

KV 形象应用客户端有效负载紧缩来提升性能,尤其是关于大数据传输。只管许少数据库都提供主机端紧缩,但在客户端处置紧缩可以增加低廉的主机 CPU 经常使用率、网络带宽和磁盘 I/O。在咱们的一个部署中,这有助于支持 Netflix 的搜查,启用客户端紧缩可将有效负载大小增加 75%,从而清楚提高老本效率。

更默认的分页

咱们选用以字节为单位的有效负载大小作为每个照应页面的限制,而不是名目数量,由于这使咱们能够提供可预测的操作 SLO。例如,咱们可以在 2 MiB 页面读取上提供个位数毫秒的 SLO。相反,经常使用每页名目数作为限制会造成无法预测的提早,由于名目大小存在很大差异。假设每页 10 个名目的恳求是 1 KiB 而不是 1 MiB,则提早或许会有很大差异。

经常使用字节作为限制会带来应战,由于很少有后备存储支持基于字节的分页;大少数数据存储经常使用结果数(例如 DynamoDB 和 Cassandra 按名目数或行数启动限制)。为了处置这个疑问,咱们对后备存储的初始查问经常使用静态限制,经常使用此限制启动查问,然后处置结果。假设须要更少数据来满足字节限制,则将口头其余查问,直到满足限制,摈弃多余的结果并生成页面令牌。

这种静态限制或许会造成效率低下,结果中的一个大项或许会造成咱们摈弃许多结果,而小项或许须要屡次迭代才干填满一页,从而造成读取加大。为了缓解这些疑问,咱们成功了自顺应分页,可依据观察到的数据灵活调整限制。

自顺应分页

当收回初始恳求时,将在存储引擎中口头查问并检索结果。当生产者处置这些结果时,系统会跟踪生产的名目数量和经常使用的总大小。这些数据有助于计算近似的名目大小,该大小存储在页面令牌中。关于后续的页面恳求,这些存储的信息准许主机对底层存储运行适当的限制,从而增加不用要的上班并最大限制地增加读取加大。

只管此方法关于后续页面恳求有效,但关于初始恳求会出现什么状况?除了将名目大小信息存储在页面令牌中之外,主机还会预算给定命名空间的平均名目大小并将其缓存在本地。此缓存预算值可协助主机为初始恳求在后备存储上设置更提升的限制,从而提高效率。主机会依据最近的查问形式或其余要素始终调整此限制以坚持其准确性。关于后续页面,主机会同时经常使用缓存数据和页面令牌中的信息来微调限制。

除了自顺应分页之外,假设主机检测四处置恳求有或许超出恳求的提早 SLO,则还有一种机制可以提早发送照应。

例如,假定客户端提交的GetItems恳求每页限制为 2 MiB,最大端到端提早限制为 500 毫秒。在处置此恳求时,主机会从后备存储中检索数据。此特定记载蕴含数千个小名目,因此搜集整页数据通常须要的期间超越 500 毫秒的 SLO。假设出现这种状况,客户端将收到 SLO 违规失误,造成恳求失败,即使没有任何异常。为了防止这种状况,主机会在失掉数据时跟踪已用期间。假设它确定继续检索更少数据或许会违犯 SLO,则主机将中止处置进一步的结果并前往带有分页令牌的照应。

这种方法可确保恳求在 SLO 内得四处置,即使未满足整个页面大小,也能为客户端提供可预测的进展。此外,假设客户端是具备适当截止期限的 gRPC 主机,则客户端足够默认,不会收回进一步的恳求,从而增加无用的上班。

假设您想了解更多信息,Netflix 如何确保高牢靠性的在线形态系对抗文将更具体地讨论这些技术以及许多其余技术。

信号

KV 经常使用带内信息传递(咱们称之为信令),准许灵活性能客户端,并使其能够将其性能传达给主机。这确保了性能设置和调整参数可以在客户端和主机之间无缝替换。假设没有信令,客户端将须要静态性能(每次更改都须要从新部署),或许,假设经常使用灵活性能,则须要与客户端团队启动协调。

关于主机端信号,当客户端初始化时,它会向主机发送握手。主机会以信号(例如指标或最大提早 SLO)启动照应,从而准许客户端灵活调整超时和对冲战略。然后会在后盾活期启动握手以坚持性能最新。关于客户端通讯信号,客户端会随每个恳求一同传达其性能,例如它能否可以处置紧缩、分块和其余性能。

Netflix 的 KV 经常使用状况

KV 形象支持 Netflix 的几个关键用例,包括:

未来的增强性能

展望未来,咱们方案经过以下形式增强 KV 形象:

论断

Netflix 的键值服务是一种灵敏、经济高效的处置方案,支持从低流量到高流量场景的各种数据形式和用例,包括关键的 Netflix 流媒体用例。便捷而弱小的设计使其能够处置各种数据模型,如 HashMap、汇合、事情存储、列表和图形。它从咱们的开发人员那里形象了底层数据库的复杂性,使咱们的运行程序工程师能够专一于处置业务疑问,而不是成为每个存储引擎及其散布式分歧性模型的专家。随着 Netflix 始终在在线数据存储方面启动翻新,KV 形象依然是高效、牢靠地大规模治理数据的外围组件,为未来的增长奠定了松软的基础。

您可能还会对下面的文章感兴趣: