引子3:Facebook使用FlightTracker获得RYW@Tao

39 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情

引子3:Facebook使用FlightTracker获得RYW@Tao

第39篇,本文仍是引子,讨论RYW是较为合适的一个选择,有人可能会问,为什么FB选择RYW作为默认值,而不是选择更强大的一致性?或者是什么让FlightTracker变得新颖有趣。在深入探讨这些细节之前,本文讨论了一些推理和理念。并把Tao的论文翻出来做了补充,请注意,你应该先读本文引子再读论文(如果你的对TAO系统不熟,也应该再读下Tao架构) PPT来自:www.usenix.org/conference/… 以及我们内部自己的分享。

为什么把 "RYW"作为默认一致性?

RYW的一致性对于应用程序开发人员和终端用户来说都是一种直观的默认值。不保证应用程序能看到自己的写入的数据存储是难以开发的。同样,不保证用户能看到自己的写入内容也很难用于交互式应用。因此,Fb希望将RYW的边界扩展到_终端用户。无论终端用户选择哪种设备与Facebook互动。不管一个用户触发了多少网络请求。无论网络请求从哪个数据存储中查询社交图。

更强的一致性模型大大简化了开发和使用,但也限制了实现。对于Fb的读优化工作负载来说,即使本地复制几秒钟就变得陈旧(stale),也要有能力在本地提供大多数查询(因为流量很贵)。相比之下,RYW允许Fb通过添加有限的写("你的 "写)的新鲜版本来利用陈旧的副本。由于应用程序习惯于并发写入,Fb也总是可以选择返回数据的较新版本,即提供或前或后的语义。这两个属性结合起来给Fb的实现带来了极大的灵活性。

因此,Fb的目标不是为每个应用程序和所有社交图数据提供最强的一致性。相反,Fb开发团队的目标是提供一个合理的默认值和选项,以便为选定的应用程序获得额外的一致性保证。

流行的例子包括线性化(对于所有从陈旧的副本中丢失的写内容,在提供读取服务之前需要是可见的)或因果一致性(对于大多数写内容需要是可见的)。

image.png 为什么管理一致性对社交网络工作负载来说是一个挑战?

读取优化的环境

为读优化系统提供一致性保证,同时保持低延迟和良好的缓存能力,归根结底是要实现呆滞性检查,以评估缓存或副本是否能以其本地数据服务于读查询。这种呆滞性检查必须是:

(1) 本地化,在大多数情况下避免网络通信。即避免跨region

(2) 高度细化的检查,所以很少有查询因检查的假阳性(即读取时因为check检查发现违反RYW),而产生额外的工作。

(3) 有利于增量修复,使额外的工作能够找到新鲜的数据,以重用于后续的查询。重要的是,即使在使用同步quorum写入的系统中,单次复制的读取也需要本地的呆滞性检查。*正如Fb将看到的,这对于像TAO这样的缓存来说可以直接实现,然而对于全局二级索引来说就复杂得多。

And (3) conducive to incremental repair, enabling the extra work to find fresh data to be reused for subsequent queries. Importantly, even in systems using synchronous quorum writes, single-replica reads need local staleness checks.* As we will see, this can be straightforward to implement for caches like TAO, yet far more complicated for global secondary indexes.

例如,Raft的Follower或Paxos的acceptors如果不是提交法定人数的一部分,他们可能不知道领导者所提交的写。逻辑和物理时间戳,如Hybrid逻辑时钟或Spanner的TrueTime,提供了一个简单和可扩展的方法来确定滞后性--如果时间戳高于所需的读取,那么本地数据就足够新鲜了。不幸的是,这两种方法都不是细化的,也不利于增量修复。例如,如果本地存储比期望的读取时间戳晚了10秒,它就不能为任何查询提供服务,直到它处理完所有丢失的写入数据。

数据存储的异质性

多年来,Fb的社交图生态系统扩展到不同的数据存储,例如,Fb的索引系统,或ZippyDB的写优化子图。根据设计,这些数据存储拥有不同的优势并利用不同的内部协议。松散的耦合(如果有的话),它们通常依靠异步复制来获得可用性和延迟优势。Fb优先考虑保留这些优势,同时在这些数据存储中提供统一的一致性,特别是由于松散耦合也促进了组织的可扩展性和灵活性。

异步复制有利于获得可用性和延迟的优势。而松散地耦合各种组件也提高了可扩展性。

会话内的并发性

具体到RYW,Fb希望实现以用户为中心的保证,这意味着Fb在几个层面上经历会话内并发。一个单一的网络请求并行地发出TAO读写。单个浏览器或移动应用程序可以同时发出许多网络请求的飞行。一个用户甚至可能从多个设备同时访问Facebook。

FlightTracker观察到,应用程序开发人员并不期望并发的网络请求能够相互通信。一个常见的心理模型是,并发请求的执行顺序是随机的,而且可能是相互交错的。因此,只有当一个请求在另一个请求开始之前完成时,才能保证一个请求到下一个请求的可见性。这一观察结果导致Fb对RYW保证做了如下放松,为处理会话内的并发提供了急需的灵活性。

对社会图的读取会观察到同一终端用户在同一网络请求中或在先前完成的网络请求中所进行的所有写入。为了应对上述挑战,FlightTracker将一致性问题分解为:

(1)收集需要以Ticket形式出现的写

(2)在一个专门的服务中存储每个用户最近的写元数据

(3)为各个数据存储实现包含Ticket的读取。