文件多副本

Slack Docker Pulls

多副本概述

Alluxio Worker 节点上缓存的一份文件数据和元数据称为该文件的一个副本。 文件多副本功能通过在不同 Worker 上创建多个副本,来使客户端可以从多个Worker 节点访问同一个文件。 因此,当缓存的数据集被大量客户端并发访问时,多副本可提高 I/O 性能。

如果未启用多副本功能,则同一时刻一个文件在集群中只有一个副本。 这意味着客户端对文件元数据和数据的所有访问都将由存储这个副本的单个 Worker 提供服务。 在大量客户端需要同时访问该文件的情况下,该 Worker 的服务能力可能会成为瓶颈。

创建多个副本

文件的副本可以因为缓存未命中而被动创建,也可以通过分布式加载功能手动创建。

手动创建副本

Alluxio 可以将文件 分布式加载(Distributed Load) 进 Alluxio 的缓存. 副本数量可在提交加载任务时指定:

bin/alluxio job load --path s3://bucket/file --replicas 3 --submit

在上面的示例中,位于 s3://bucket/file 的文件产生 3 个副本加载进 Alluxio,这些副本将存在于 3 个不同的 Worker 上。

请注意,为 --replicas 选项设置的副本数量不应超过 alluxio.user.file.replication.min 的配置值。

被动创建副本

当客户端从 Alluxio 读取文件时,如果该文件未被任何 Worker 缓存,则会被加载到 Alluxio 中。 如果启用了多副本功能,客户端将尝试从不同 Worker 加载文件,从而导致在多个 Worker 上被动产生多个副本。 会因此创建的副本数量可由配置项 alluxio.user.file.replication.min 指定。 在 conf/alluxio-site.properties 中将该属性设置为大于 1 但小于集群中 Worker 数量的值。

并发读取多个副本

如果 alluxio.user.file.replication.min 设置为大于 1 的值,且有多个副本存在,客户端将能够读取多个副本。 如果副本是通过 distributed load 主动创建的,则副本数量应设置为与 distributed load 作业使用的值相同。

在读取时,客户端选择哪一个副本由副本选择策略控制。 副本选择策略会从所有候选 Worker 的列表中,决定客户端应联系哪个 Worker 来读取文件。 Alluxio 提供两种副本选择策略:

  • 全局固定(Global fixed): 所有客户选择 Worker 的顺序与候选 Worker 列表中的顺序相同。
  • 客户端固定(Client fixed): 每个客户端看到的候选 worker 都是一样的,但顺序可能不同。因此,不同的客户端会选择不同的 Worker 来读取文件。

如果策略选出的 Worker 不可用,客户端将使用候选列表中的下一个 Worker, 直到列表中的所有Worker都被尝试为止。

要设置副本选择策略,请将配置 alluxio.user.replica.selection.policy 设为 GLOBAL_FIXEDCLIENT_FIXED

多副本的局限

文件多副本功能有一些局限性:

可变数据的一致性问题

多副本在数据不会发生变化的场景中最有效,因为副本之间不会出现不一致。 如果 UFS 中的数据会随着时间的推移而变化,那么在不同时间从 UFS 加载的副本可能对应着文件的不同版本。 因此,如果对于同一文件,两个客户端选择了两个不同副本,就可能出现数据不一致的问题。

要避免文件可变时可能出现的不一致,可以采取以下措施:

  • 手动刷新副本的文件元数据,并使现有缓存副本失效。

这可以通过在调用 分布式加载(Distributed Load) 工具时,加上 -metadataOnly 选项来实现:

bin/alluxio job load --path s3://bucket/file --replicas 3 --metadataOnly --submit

以上的命令将启动一个分布式作业,加载文件 s3://bucket/file 的元数据。 如果该文件有任何现存副本,且 Alluxio 检测到 UFS 中的文件已更改,则现有副本将失效。 随后访问该文件时,Alluxio 将从 UFS 中加载最新数据。

  • 为文件设置一个具有适当缓存控制策略的 Cache Filter规则。

例如,如果一个文件预计平均每 10 分钟更新一次,则可使用 10 分钟的 maxAge 策略:

{
  "apiVersion": 1,
  "data": {
	"defaultType": "maxAge",
	"defaultMaxAge": "10min"
  },
  "metadata": {
	"defaultType": "maxAge",
	"defaultMaxAge": "10min"
  }
}

当副本的最长有效期为 10 分钟时,它将在 10 分钟后失效并被 Worker 从 UFS 重新加载。 每次 UFS 中的文件发生变化后,至少要等待 10 分钟,以便使任何现有的副本失效。

不主动维持副本数量

alluxio.user.file.replication.min 指定的目标副本数量仅作为副本选择算法的输入参数。 在任何给定时刻,集群中实际存在的副本数量可能小于、等于或大于配置的值。 Alluxio 不会主动监控副本数量并尝试维持目标副本数量。

由于多种原因,实际副本数量可能少于目标副本数量。 例如,如果某个文件在某个时刻被缓存在某些 Worker 上,但由于缓存容量不足而被从某些 Worker 上驱逐、 那么它的实际副本数量就会低于要求的数量。 另一种情况是,在副本是因为缓存未命中而被动创建的情况下,客户端发现某个文件已被某个 Worker 缓存、 那么文件将直接从缓存中提供,而不会创建新的副本。 文件的副本数量将保持不变,直到有客户端尝试从某个未缓存该文件的 Worker 处读取文件,导致该 Worker 创建一个副本为止。

当集群中的 Worker 构成发生变化时,实际副本数量可能会大于目标数量。 加入或退出集群的 Worker 可能会改变副本选择算法的结果, 这样,之前缓存了副本的 Worker 就可能不会被选中,从而导致该副本不会被客户端使用。 该副本会一直停留在 Worker 的缓存中,直到因缓存容量不足而被 Worker 驱逐。