用于松散耦合分布式系统的Chubby锁服务 (6)

2022-07-06 15:00:05 浏览数 (1)

3 Mechanisms for scaling

Chubby的客户端是单独的进程,所以Chubby必须处理比人们想象中更多的客户端;我们已经看到有90,000个客户端直接与Chubby的主服务器通信,远远超过了所涉及的机器数量。因为每个单元只有一个主服务器,而且它的机器和客户端的机器是一样的,客户端可以以很大的幅度压倒主服务器。因此,最有效的扩展技术是将与主服务器的通信次数减少一个较大的系数。假设主服务器没有严重的性能缺陷,主服务器的请求处理的微小改进也没有什么效果。我们使用了几种方法:

  • 我们可以创建任意数量的Chubby单元;客户端几乎总是使用附近的单元(通过DNS找到)以避免对远程机器的依赖。我们的典型部署是在一个有几千台机器的数据中心使用一个Chubby单元。
  • 当主服务器处于heavy load时,可能会将租赁时间从默认的12秒增加到60秒左右,因此它需要处理更少的KeepAlive RPC。KeepAlives是迄今为止最主要的请求类型(见4.1),未能及时处理它们是过载服务器的典型故障模式;客户端对其他调用的延迟变化基本不敏感)。
  • Chubby客户端对文件数据、元数据、没有文件和开放句柄进行缓存,以减少他们对服务器的调用次数。
  • 我们使用协议转换服务器,将Chubby协议转换为不太复杂的协议,如DNS和其他协议。我们在下面讨论其中的一些。在这里,我们描述了两个熟悉的机制,代理和分区,我们希望这些机制能让Chubby进一步扩展。我们还没有在生产中使用它们,但它们被设计出来了,而且可能很快就会被使用。我们目前没有必要考虑超过5倍的扩展:首先,人们希望放在数据中心的机器的数量是有限的,或者说是依赖于一个服务的单一实例。其次,因为我们使用类似的机器来做Chubby的客户端和服务器,增加每台机器的客户端数量的硬件改进也会增加每台服务器的容量。

3.1 Proxies

Chubby的协议可以通过可信的进程来代理(两边使用相同的协议),将其他客户端的请求传递给Chubby单元。代理可以通过处理KeepAlive和读取请求来减少服务器的负载;它不能减少写入流量,因为写入流量会通过代理的缓存。但是,即使有积极的客户端缓存,写流量占Chubby正常工作负荷的比例也远低于百分之一(见§4.1),所以代理允许客户端数量的显著增加。如果一个代理处理Nproxy客户端,KeepAlive流量就会减少Nproxy系数,这可能是1万个或更多。代理缓存最多可以减少读取流量的平均量--大约10倍(§4.1)。但是,由于目前读取占Chubby负载的10%以下,KeepAlive流量的节省是迄今为止更重要的效果。

代理人为写和首次读增加了一个额外的RPC。我们可以预期代理会使单元格暂时不可用的频率至少是以前的两倍,因为每个代理的客户端都依赖于两台可能失败的机器:它的代理和Chubby主控。

警觉的读者会注意到,第2.9节中描述的故障转移策略,对代理来说并不理想。我们在第4.4节讨论这个问题。

3.2 Partitioning

正如第2.3节中提到的,Chubby的接口是为了使单元格的名字空间可以在服务器之间进行划分。虽然我们还不需要,但代码可以按目录划分名称空间。如果启用,一个Chubby单元将由N个分区组成,每个分区都有一组副本和一个主服务器。目录D中的每个节点 D/C 将被存储在分区 P(D/C) = hash(D) mod N 上。注意,D的元数据可能被存储在不同的分区 P(D) = hash(D0) mod N 上,其中 D0 是D的父节点。

分区的目的是为了使大型的Chubby单元在分区之间几乎没有通信。尽管Chubby缺乏硬链接、目录修改时间和跨目录重命名操作,但有一些操作仍然需要跨分区通信:

  • ACL本身就是文件,所以一个分区可以使用另一个分区进行权限检查。然而,ACL文件很容易被缓存;只有Open()和Delete()调用需要ACL检查;而且大多数客户端读取公开访问的文件,不需要ACL。
  • 当一个目录被删除时,可能需要一个跨分区调用以确保该目录是空的。由于每个分区都独立于其他分区处理大多数调用,我们预计这种通信对性能或可用性的影响不大。

除非分区的数量N很大,否则人们会期望每个客户端都会联系大部分的分区。因此,分区减少了任何给定分区上的读写流量的N倍,但不一定会减少KeepAlive流量。如果Chubby需要处理更多的客户,我们的策略包括代理和分区的组合。

0 人点赞