开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情
引子4:Facebook使用FlightTracker获得RYW@Tao
第40篇,本文仍是引子,介绍了FlightTraceker的组成 PPT来自:www.usenix.org/conference/…
Tickets
票据封装了最近写的元数据。它们由每个数据仓库铸造,包含协调一致性所需的关键和版本信息。考虑一个更新单个 "SONG "对象以改变一个属性的写入。TAO可能会产生一个Ticket,包含该对象的ID和最新版本。
TaoWrites: [
{
id: 123,
version: 2,
type: SONG
}
]
为了使用这个票据,对这个对象的后续读取将沿着读取查询发送这个票据。我们称这种类型的查询为包含票据的读。
例如,考虑一个陈旧的TAO缓存副本,它只有这个对象的版本1。为了服务于这个读,该副本确定其缓存值是陈旧的,并从上游数据库中获取更新的值。我们把这个过程称为一致性缺失。它的功能与普通的缓存缺失一样,但只是为了确保一致性。随后对同一版本的Ticket-inclusive读取可以返回新的缓存值,也就是说,结果变得可缓存了。我们发现 "一致性缺失 "这个术语对系统监控和核算、一般交流以及建立我们团队和数据存储团队的工程师的心智模型都有帮助。
在可扩展性和数据存储方面,Ticket的内部表示可以利用任何可用的版本基元--只要版本是可比较的且不断增加。在生产中,我们通常用密钥信息、版本基元和它们的模式类型(如 "用户 "或 "歌曲")对Ticket进行编码。
我们的重读工作负载意味着Ticket需要很小。值得注意的是,表示方法的灵活性使我们能够在Ticket的大小和基于Ticket的读取效率之间做出权衡。例如,用每分片的序列号100对Ticket进行编码,允许我们将一个分片上的多个写合并成一个条目,使Ticket更加紧凑。在读取时,这是以较低的选择性为代价的:每个分片的Ticket在语义上代表了该分片上所有写的集合0...100
。因此,本地副本被认为是过时的可能性更大。
另个example:
Ticket对应用开发者隐藏了这些细节,并提供了一个不透明的标记接口,提供了一些基本功能,如合并(即写元数据的集合联合)、包含检查和序列化。最常见的是,应用程序在进行写操作时简单地合并Ticket。然后他们在随后的读取中包含这个合并的Ticket。这种灵活性使我们能够扩展Ticket以覆盖其他数据存储,如ZippyDB,并使现有系统如TAO在不改变API的情况下发展到新的基元。
下图是我从TAO系统中找到的一种读取模式,请注意图中的RYW路线:
FlightTracker服务
假设数据存储实现了包含Ticket的读取API,那么提供读-写的一致性就相当于在读取时提供 "适当的 "Ticket。由于我们希望将RYW边界扩展到终端用户,因此Ticket需要包含终端用户最近的写操作。这个Ticket可以被附加到所有后续的读取中,以确保用户观察到他们最近的写入。
会话内的并发性使得在单个网络请求中累积用户的写操作是不够的。FlightTracker通过提供外部的、针对每个用户的机票存储来解决这个问题。它跟踪每个用户的飞行中写入。社交图谱客户端库将最近写入的元数据与用户的ID一起发送给FlightTracker。在一个网络请求开始时,按用户ID从FlightTracker中获取一个合并的机票(并与该请求中的后续写入内容合并)。这就保证了在以前的网络请求中所进行的写入的可见性。因此,FlightTracker的功能就像一个简单的键值存储,以用户ID为键,以机票为值。
我们将FlightTracker部署为一个内存中的复制服务。由于我们的异步更新管道的最大延迟约为60秒,FlightTracker只需要存储最后60秒的写入量,从而极大地限制了工作集。根据经验,只要这些副本被放置在独立的故障域中,3的复制系数就能为小型工作集提供足够的冗余度。FlightTracker依赖于ShardManager (将用户ID空间划分为分片)进行智能放置和负载平衡。
一个简单的单轮法定人数协议驱动FlightTracker的复制。客户端库向所有复制体发送写入信息,如果大多数人响应,则确认成功。读取合并来自大多数副本的机票。值得注意的是,FlightTracker服务不需要强共识,甚至不需要两轮协议。我们可以以任何顺序合并机票,并且可以在不违反整体RYW一致性的情况下,在返回的机票中安全地包含额外的写元数据。 也就是R+W>N的简单仲裁系统,在后面的论文中有提到这一点,本文很好地帮助节省FT基本架构。
关于FlightTracker复制的细微描述和解释,请参见[FlightTracker论文](www.usenix.org/conference/…)第5.1节。