注意

本文档适用于 Ceph 开发版本。

MDS 缓存配置

元数据服务器在所有MDS和CephFS客户端之间协调一个分布式缓存。该缓存用于提高元数据访问延迟并允许客户端安全地(一致地)修改元数据状态(例如,通过chmod)。MDS发出capabilities目录条目租约来指示客户端可以缓存的状态以及客户端可以执行的操作(例如,向文件写入)。f58532: MDS和客户端都试图执行缓存大小。指定MDS缓存大小的机制在下文中描述。请注意,MDS缓存大小不是硬限制。MDS始终允许客户端查找新的元数据,该元数据被加载到缓存中。这是一个基本策略,因为它可以避免客户端请求中的死锁(某些请求可能在能力被释放之前依赖于持有的能力)。

The MDS and clients both try to enforce a cache size. The mechanism for specifying the MDS cache size is described below. Note that the MDS cache size is not a hard limit. The MDS always allows clients to lookup new metadata which is loaded into the cache. This is an essential policy as it avoids deadlock in client requests (some requests may rely on held capabilities before capabilities are released).

当MDS缓存太大时,MDS将召回客户端状态,因此缓存项变为未固定并可以丢弃。MDS只能在没有客户端引用要丢弃的元数据时丢弃缓存状态。下面还描述了如何根据您的工作负载需求配置MDS召回设置。如果MDS召回的内部限制无法跟上客户端工作负载,则这是必要的。

MDS缓存大小

您可以通过字节计数限制元数据服务器(MDS)缓存的大小。这是通过mds_cache_memory_limit配置完成的:

mds_cache_memory_limit

这设置了MDS缓存的目标最大内存使用量,并且是限制MDS内存使用的主要可调参数。MDS将尝试保持在默认限制(95%;1 - mds_cache_reservation)的预留量之下,通过修剪其缓存中的未使用元数据和召回客户端缓存中的缓存项。由于客户端召回缓慢,MDS可能会超过此限制。mds_health_cache_threshold(150%)设置了MDS发出集群健康警告时的缓存满阈值。

type:

size

default:

4Gi

此外,您可以使用mds_cache_reservation参数为MDS操作指定缓存预留:

mds_cache_reservation

为MDS缓存保留的缓存预留(内存或inode)。一旦MDS开始动用其预留,它将召回客户端状态,直到其缓存大小缩小以恢复预留。

type:

float

default:

0.05

缓存预留按内存百分比限制,默认设置为5%。此参数的目的是让MDS为其缓存保留额外的内存,供新的元数据操作使用。因此,MDS通常应在其内存限制以下运行,因为它将从客户端召回旧状态,以丢弃其缓存中的未使用元数据。

如果MDS无法将其缓存保持在目标大小以下,MDS将向监视器发送健康警报,指示缓存太大。这受mds_health_cache_threshold配置控制,默认为最大缓存大小150%:

mds_health_cache_threshold

缓存大小生成健康警告的阈值

type:

float

default:

1.5

由于缓存限制不是硬限制,CephFS客户端、MDS或行为不当的应用中的潜在错误可能导致MDS超出其缓存大小。健康警告旨在帮助操作员检测这种情况并进行必要的调整或调查有问题的客户端。

MDS缓存修剪

有两个配置用于限制MDS中缓存修剪速率:

mds_cache_trim_threshold

可修剪的dentries数量阈值

type:

size

default:

256Ki

mds_cache_trim_decay_rate

修剪MDS缓存限制的衰减率

type:

float

default:

1.0

限制的目的是防止MDS花费过多时间修剪其缓存。这可能限制其处理客户端请求或执行其他维护工作的能力。

修剪配置控制一个内部衰减计数器。任何时候从缓存中修剪元数据,计数器都会递增。阈值设置计数器的最大大小,而衰减率指示计数器的指数半衰期。如果MDS持续从其缓存中删除项,它将达到每秒-ln(0.5)/rate*threshold项的稳定状态。

Note

增加配置设置的值mds_cache_trim_decay_rate会导致MDS花费更少的时间修剪缓存。要增加缓存修剪速率,请设置较低的值。

默认值比较保守,可能需要针对具有大缓存大小的生产MDS进行调整。

MDS召回

MDS限制其召回客户端状态(能力/租约),以防止自己处理客户端释放消息的工作量过大。这通过以下配置控制:

在给定召回事件中从单个客户端召回的最大能力数:

mds_recall_max_caps

单次召回中从客户端会话召回的最大能力数

type:

size

default:

30000B

会话衰减计数器的阈值和衰减率:

mds_recall_max_decay_threshold

召回能力会话限制的衰减阈值

type:

size

default:

128Ki

mds_recall_max_decay_rate

召回能力会话限制的衰减率

type:

float

default:

1.5

会话衰减计数器控制单个会话的召回速率。计数器的行为与上述缓存修剪相同。每次召回能力都会递增计数器。

还有一个全局衰减计数器,用于对所有会话召回进行限制:

mds_recall_global_max_decay_threshold

全局召回能力限制的衰减阈值

type:

size

default:

128Ki

其衰减率与mds_recall_max_decay_rate相同。任何会话召回的能力都会递增此计数器。

如果客户端缓慢释放状态,将报告“未能响应缓存压力”或MDS_HEALTH_CLIENT_RECALL警告。每个会话的释放速率由另一个由以下配置参数配置的衰减计数器监控:

mds_recall_warning_threshold

慢会话能力召回警告的衰减阈值

type:

size

default:

256Ki

mds_recall_warning_decay_rate

慢会话能力召回警告的衰减率

type:

float

default:

60.0

每次释放能力时,计数器都会递增。如果客户端没有足够快地释放能力,并且存在缓存压力,计数器将指示客户端缓慢释放状态。

在某些情况下,许多“召回能力”请求可以非常快地发送,以至于生成健康警告:“客户端未能响应缓存压力”。如果客户端没有足够快地释放能力,MDS将在一秒后重复“召回能力”请求。这意味着MDS将一次又一次地发送“召回能力”。会话的“召回能力”总数将不断增长,并最终超过“mon警告限制”。

MDS能力获取限制

在大型目录层次结构上的一个简单的“查找”命令会导致客户端比释放的速度更快地接收能力。MDS将尝试让客户端将其能力降低到mds_max_caps_per_client限制

readdir能力获取衰减计数器的阈值和衰减率:

mds_session_cap_acquisition_throttle

能力获取衰减计数器限制的阈值

type:

uint

default:

100000

mds_session_cap_acquisition_decay_rate

readdir获取能力的会话能力获取计数器的半衰期。这用于限制来自客户端的readdir请求。

type:

float

default:

30.0

能力获取衰减计数器控制通过readdir获取能力的速率。衰减计数器的行为与缓存修剪或能力召回相同。每次readdir调用都会根据结果中的文件数量递增计数器。

mds_session_max_caps_throttle_ratio

客户端必须超过

type:

float

default:

1.1

mds_cap_acquisition_throttle_retry_request_timeout

由于能力获取限制而重试客户端请求的超时时间(秒)

type:

float

default:

0.5

如果客户端每会话获取的能力数量大于mds_session_max_caps_throttle_ratio并且能力获取衰减计数器大于mds_session_cap_acquisition_throttle, the readdir is throttled. The readdir request is retried after mds_cap_acquisition_throttle_retry_request_timeout seconds.

会话活跃性

MDS还跟踪会话是否处于空闲状态。如果客户端会话未使用其能力或保持安静,MDS将开始从会话中召回状态,即使它没有缓存压力。这有助于MDS避免在集群工作负载繁忙且缓存压力迫使MDS召回状态时进行未来的工作。预期未使用其能力的客户端不太可能在不久的将来使用这些能力。

确定给定会话是否空闲受以下配置变量控制:

mds_session_cache_liveness_magnitude

这是内部活跃性衰减计数器与会话持有的能力数量之间的2的幂次方差异。当出现此差异时,MDS将会将会话视为空闲并开始召回能力。

type:

size

default:

10B

参见:

mds_session_cache_liveness_decay_rate

mds_session_cache_liveness_decay_rate

这决定了会话需要保持空闲多长时间,MDS才会开始预先召回能力。默认的5分钟会导致1小时后衰减计数器减半10次,即1/1024。默认的10(1^10或1024)的幅度是如此选择,以便MDS认为之前繁忙的会话(大约)在1小时后处于空闲状态。

type:

float

default:

5 minutes

参见:

mds_session_cache_liveness_magnitude

配置mds_session_cache_liveness_decay_rate指示跟踪客户端使用能力的衰减计数器的半衰期。每次客户端操作或获取能力时,MDS都会递增计数器。这是一种粗略但有效的方法来监控客户端缓存的利用率。

The mds_session_cache_liveness_magnitude是活跃性衰减计数器与会话未完成能力数量之间的2的幂次方差异。因此,如果客户端有1*2^20(1M) 未完成能力,并且只使用1*2^(20-mds_session_cache_liveness_magnitude)(1K

能力限制

MDS还试图防止单个客户端获取太多能力。这有助于防止在某些情况下恢复时间过长。通常不需要客户端拥有如此大的缓存。该限制通过以下方式配置:

mds_max_caps_per_client

客户端可以持有的最大能力数

type:

uint

default:

1Mi

不建议将此值设置为超过5M,但对于某些工作负载可能有所帮助。

处理“客户端未能响应缓存压力”消息

每秒(或由mds_cache_trim_interval配置参数设置的间隔),MDS都会运行“缓存修剪”过程。该过程的步骤之一是“召回客户端状态”。在此步骤中,MDS检查每个客户端(会话),以确定是否需要召回能力。如果以下任何一项为真,则MDS需要召回能力:

  1. 缓存已满(已超过mds_cache_memory_limit has been exceeded) and needs some inodes to be released

  2. 客户端超过mds_max_caps_per_client (1M by default)

  3. 客户端不活跃

要确定客户端(会话)是否不活跃,会检查会话的cache_liveness参数,并将其与值:

(num_caps >> mds_session_cache_liveness_magnitude)

其中mds_session_cache_liveness_magnitude is a config param (10 by default). If cache_liveness is smaller than this calculated value, the session is considered inactive and the MDS sends a “recall caps” request for all cached caps (the actual recall value is num_caps - mds_min_caps_per_client(100)).

Under certain circumstances, many “recall caps” requests can be sent so quickly that the health warning is generated: “clients failing to respond to cache pressure”. If the client does not release the caps fast enough, the MDS repeats the “recall caps” request one second later. This means that the MDS will send “recall caps” again and again. The “total” counter of “recall caps” for the session will grow and grow, and will eventually exceed the “mon warning limit”.

有一个由mds_recall_max_decay_threshold parameter (126K by default), is available for reducing the rate of “recall caps” counter growth, but sometimes it is not enough to slow the “recall caps” counter’s growth rate. If altering the mds_recall_max_decay_threshold value does not sufficiently reduce the rate of the “recall caps” counter’s growth, decrease mds_recall_max_caps incrementally until the “clients failing to respond to cache pressure” messages no longer appear in the logs.

示例场景

这里有一个示例。客户端有20k个缓存的。在某个时刻,服务器决定客户端不活跃(因为会话的cache_liveness value is low). It starts to ask the client to release caps down to mds_min_caps_per_client value (100 by default). Every second, it sends recall_caps asking to release caps_num - mds_min_caps_per_client caps (but not more than mds_recall_max_caps, which is 30k by default). A client is starting to release, but is releasing with a rate of (for example) only 100 caps per second.

因此,在时间的第一个秒中,mds发送recall_caps = 20k - 100,第二秒recall_caps = (20k - 100) - 100,第三秒recall_caps = (20k - 200) - 100,依此类推。并且每次发送recall_caps时,它都会更新会话的recall_caps值,该值计算为过去一分钟内发送的recall_caps数量。即计数器迅速增长,最终超过mds_recall_warning_threshold but only if a client does not “respond” for a long time, and as your experiments show it is not the case.

由 Ceph 基金会带给您

Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.