SCM 复制管理器
复制管理器(Replication Manager,RM)是运行在 Ozone 集群中 leader SCM 守护进程内的一个关键线程。它的职责是周期性地检查集群中每个容器的健康状况,并对副本复制状态不佳的容器采取相应的处理措施。这类操作通常包括安排创建该容器的新副本,但也可能包括关闭副本、删除空副本等。
架构
RM 的处理过程分为若干阶段——一个阶段用于检查容器并找出需要处理的容器,另一个阶段用于处理这些待处理的容器。
容器检查阶段
检查阶段以 5 分钟为间隔周期性运行。首先它会收集集群中所有容器的列表,然后让每个容器依次通过一系列规则,以判断其是否存在任何问题。这些规则的组织方式类似于"责任链"设计模式,即第一个"匹配"的规则会使链式检查立即结束。每种检查类型都由一个独立的 Java 类实现,并且这些检查按照既定的顺序依次处理:
containerCheckChain = new OpenContainerHandler(this);
containerCheckChain
.addNext(new ClosingContainerHandler(this, clock))
.addNext(new QuasiClosedContainerHandler(this))
.addNext(new MismatchedReplicasHandler(this))
.addNext(new EmptyContainerHandler(this))
.addNext(new DeletingContainerHandler(this))
.addNext(ecReplicationCheckHandler)
.addNext(ratisReplicationCheckHandler)
.addNext(new ClosedWithUnhealthyReplicasHandler(this))
.addNext(ecMisReplicationCheckHandler)
.addNext(new RatisUnhealthyReplicationCheckHandler())
.addNext(new VulnerableUnhealthyReplicasHandler(this));ReplicationManager 报告
复制管理器(Replication Manager)的检查阶段每次运行时,都会生成一份报告,可通过 container report 命令获取。该命令在管理员指南的复制管理器报告中有所描述。
容器状态说明
报告的第一部分“容器状态摘要”汇总了集群中所有容器的状态。随着容器被打开、写入块数据以及随时间推移数据被删除,容器会在这些状态之间流转。在任意时刻,一个容器应仅处于其中一种状态,且本部分中各状态的容器数量之和应等于集群中的容器总数。

以下各节将逐一说明每种状态。
Open(打开)
打开状态的容器可以接受写入集群的数据。
Closing(关闭中)
关闭中的容器正在执行关闭流程。当容器中的数据已足够多、可被视为写满时,或者写入管道出现问题(例如某个数据节点宕机)时,容器会转入关闭中状态。
Quasi-Closed(准关闭)
当某个数据节点尝试关闭副本,但由于 Ratis 管道不可用而无法干净地完成关闭时,容器会进入准关闭状态。例如,数据节点意外宕机就可能导致这种情况。复制管理器会通过识别具有最高块提交序列号(BCSID)的副本来尝试关闭该容器。由于 BCSID 较旧的副本已过期,在移除这些过期副本之前,会先基于已关闭的副本创建新的副本副本。
Closed(已关闭)
已关闭的容器成功从关闭中状态转为已关闭状态。这是容器流转的正常状态,集群中大多数容器应处于此状态。
Deleting(删除中)
容器关闭后,随着时间推移所有块都被删除直至为空,便会转入删除中状态。容器会保持此状态,直到其所有副本都已从数据节点上移除。
Deleted(已删除)
当“删除中”过程完成且所有副本都已移除后,容器将转入已删除状态并保持在该状态。
Recovering(恢复中)
恢复中是数据节点上的容器副本可能进入的一种临时状态,与 EC(纠删码)重构相关。报告中该状态的计数应始终为零,因为该状态不受复制管理器管理。
容器健康摘要
报告的下一部分列出了集群中处于各种健康状态的容器数量。请注意,报告并未给出“健康”容器的数量,只列出降级状态。在其他方面健康的集群中,复制管理器应设法修正上述列表中所列状态的容器,但 Missing(缺失)和 Unhealthy(不健康)状态除外,这两种状态是它无法修复的。
副本不足(Under Replicated)
副本不足的容器,其副本数少于期望的副本数。这可能是由于数据节点进入下线或维护模式状态转换所致,也可能是由于集群中磁盘或节点故障所致。不健康的副本同样会导致容器副本不足,因为这类副本存在必须修复的问题。关于不健康状态的更多详情,请参阅下文的「不健康」部分。副本复制管理器(Replication Manager)会调度命令,为副本不足的容器创建额外的副本。
副本放置错误(Mis-Replicated)
如果容器的副本数正确,但副本未分布在足够的机架上,无法满足容器放置策略的要求,则该容器属于副本放置错误。同样,副本复制管理器会通过为相关副本创建新的副本,然后删除多余副本,来设法将副本迁移到其他机架。
副本过多(Over Replicated)
副本过多的容器拥有过多的副本。这可能是由于修正副本放置错误所致,也可能是某个已下线或已宕机的主机在副本不足问题得到修复后重新加入集群所致。副本复制管理器会调度删除副本的命令,在保持容器放置策略中关于机架放置规则的前提下,删除多余的副本。
丢失(Missing)
如果容器没有足够的副本可供读取,则该容器处于丢失状态。对于 Ratis 容器,这意味着没有任何副本在线;对于 EC 容器,如果在线副本数少于「数据块数」,则标记为丢失。例如,对于 RS-6-3 容器,在线副本少于 6 个即视为丢失。对于丢失的容器,副本复制管理器无法采取任何修复措施。需要人工介入,将丢失的节点重新带回集群,或者采取措施从 SCM 中移除这些容器并从 OM 中移除相关的键,因为这些数据将无法访问。
不健康(Unhealthy)
如果容器未处于丢失状态,但健康的副本数量不足以完整读取该容器,则该容器是不健康的。
副本可能因各种原因被数据节点上的扫描进程标记为不健康。例如,扫描进程可以检测到容器中某个块的校验和无效,并将该副本标记为不健康。对于 Ratis 容器,如果其所有容器副本都不健康且没有可用的健康副本,则该容器将被标记为不健康。请注意,不健康容器中的大部分数据仍有可能被读取。对于 Ratis,每个副本可能存在不同的问题,影响每个副本中不同的块,例如读取时的校验和不匹配。Ozone 客户端会捕获读取错误,并尝试从另一个副本重新读取。不过,数据恢复能否成功取决于损坏的数量和程度,以及所有副本中是否损坏了相同的块。
不健康的 Ratis 容器
对于一个拥有 3 个副本的 Ratis 容器,如果状态为 Healthy、Healthy、Unhealthy,它仍然是完全可读的,因此也是可恢复的,此时会被标记为副本数不足(under replicated),因为不健康的副本需要被替换。如果一个 Ratis 容器的 3 个副本全部为 Unhealthy,则会被标记为不健康(unhealthy)。它不算缺失(missing),因为仍有副本存在;也不算副本数不足,因为它仍然拥有全部 3 个副本。如果一个 Ratis 容器只有 2 个副本处于不健康状态,那么它既不健康又副本数不足,会被同时标记为 Unhealthy 和 Under-Replicated。复制管理器(Replication Manager)会尝试为该不健康的容器额外创建一份副本,以解决副本数不足的问题,但由于没有良好的副本可供复制,它无法在没有人工干预的情况下修复其不健康状态。
不健康的 EC 容器
EC 容器的情况类似。只有当它不缺失(至少有 data number 个副本可用),但健康副本数不足 data number 个时,才会被标记为不健康。示例如下表所示:
| Index = 1 | Index = 2 | Index = 3 | Index = 4 | Index = 5 | 状态 |
|---|---|---|---|---|---|
| Healthy | Healthy | Healthy | Unhealthy | Unhealthy | Under-Rep |
| Healthy | Healthy | Healthy | Under-Rep | ||
| Healthy | Healthy | Unhealthy | Unhealthy | ||
| Healthy | Healthy | Missing | |||
| Healthy | Healthy + Unhealthy | Missing and Over Replicated | |||
| Healthy | Healthy + Unhealthy | Healthy | Under and Over Replicated |
请注意,一个 EC 容器可能同时处于 Unhealthy 和 Over Replicated 状态,因为同一个 index 可能存在两份副本,一份健康、一份不健康。
如果容器处于不健康状态,在没有人工干预的情况下,复制管理器将无法修复它,因为不健康的数据副本不能用于数据重建。不健康的容器可能只是某个单个块存在问题,因此仍能读取其中的大部分数据;但如果一个不健康的 EC 容器存在真正的损坏,则很可能至少有部分数据无法读取。
空(Empty)
当容器已关闭,并且其中存储的所有数据块都被删除后,该容器会被标记为空。检测到这种情况后,容器会从 CLOSED 转换为 DELETING 状态,因此容器应只在下一次复制管理器检查阶段之前短暂处于 Empty 状态。
打开状态下的不健康(Open Unhealthy)
当容器处于 open 状态时,预期其所有副本也应处于相同的 open 状态。如果发生问题导致某个副本脱离 open 状态,Replication Manager 会将该容器标记为 Open Unhealthy(打开但不健康)并触发关闭流程。通常,在下一次 Replication Manager 检查阶段之前,这样的容器就已经转入 Closing 或 Closed 状态。
Quasi-Closed Stuck(准关闭卡住)
这一点仅适用于 Ratis 容器。当容器处于准关闭状态时,Replication Manager 需要等待大多数副本(3 个中的 2 个)都达到准关闭状态,才能将容器转换为 closed。在此之前,容器会被标记为 quasi-closed Stuck(准关闭卡住)。
不健康容器样例
为了便于排查性能下降容器的问题,报告中包含每种状态下前 100 个容器 ID 的样例。通过这些 ID,可以判断是否是同一批容器始终处于卡住状态,也可以借助 ozone admin container info ID 命令获取容器的更多信息。
复制任务限流
为了防止集群因复制任务过多而过载,任意时刻集群上运行的复制任务数量必须受到限制。DataNode 上的负载会随时间变化,这会影响它们处理任务的速度。除了对并发工作进行限流之外,复制协调者(SCM)还必须避免在 DataNode 上排队过多任务。如果任务排在较慢的 DataNode 上,在任务超时之前,SCM 无法将其重新调度到其他地方。更好的做法是以较小的增量将工作调度给各个 DataNode,目标是让每个 DataNode 获得足以在一次心跳周期内保持忙碌的工作量。
DataNode 在响应其周期性心跳时会收到复制任务。DataNode 的心跳中包含一份报告,详细说明当前该 DataNode 上排队的各类命令的数量。位于 SCM「Datanode Command Queue」中的任何命令都会随心跳响应发送给 DataNode,而命令计数则存储在 SCM 的 NodeManager 中。NodeManager 中存储的命令计数,等于 DataNode 报告的计数与心跳响应中发送的命令数量之和。
Replication Manager 可以利用这些存储的命令计数,来限制某个 DataNode 上排队的命令数量。
Replication Manager 会调度以下 3 类命令,这些命令必须进行限流:
- 复制容器命令——用于修正 Ratis 的副本不足、Ratis 和 EC 的副本错配,并在退役和维护期间为 Ratis 与 EC 容器制作额外副本。
- 删除容器副本命令——用于解决副本过多的问题,以及删除处于异常状态的容器。
- EC 重建——这是开销最大的命令,用于恢复丢失的 EC 副本。
以下各节将探讨每种主要命令类型的限流用法。
复制容器命令
在旧版复制管理器中,复制容器命令会被发送到将要接收新副本的目标节点,命令中包含一份可供其下载的可用源节点列表。当副本不足的容器集中在少数几个源节点上时,就会导致大量目标节点同时运行命令、试图从数量有限的源节点下载,从而造成源节点过载。
现在,命令会发送到源节点,并由源节点将命令转发给新的目标节点。通常情况下,目标节点的分布相当分散;但在执行退役操作时,尤其是当正在退役的节点上存在 EC 容器时,源节点可能只集中在单个或少数几个节点上,因此这种方式效果更好。
为了平衡并限制每个数据节点上复制命令的负载,复制管理器会使用节点管理器中存储的当前命令计数。调度了过多命令的源节点会被过滤掉,剩余的源节点则按照排队命令数进行排序。命令将被发送给排队命令最少的数据节点。
如果所有源节点的排队命令都过多,则该容器无法复制,命令会被重新入队,稍后再试。
请注意,复制命令有两种类型——简单复制和 EC 重建。在数据节点上,它们共用同一个数据节点队列和工作线程池,因此设置一个统一的综合限制是合理的。由于 EC 重建命令的处理开销比复制命令更高,因此会被赋予一个权重,排队一条命令时按 1 × 权重计入限制。目前的默认权重为 3。
均衡器与低优先级命令
均衡器(Balancer)进程也会通过复制管理器 API 发送复制命令,以均衡整个集群中各节点的空间使用情况。均衡器基于迭代(iteration)的概念工作:它评估集群状态,判断哪些节点使用过度、哪些节点使用不足,然后调度大量的迁移命令,将数据从使用过度的节点移动到使用不足的节点。这些命令最初以复制容器命令的形式调度到数据节点上,在其完成后再转换为删除容器副本命令。
这可能会在 Datanode 队列上产生大量命令,并且在某些节点下线时,还可能影响更重要的容器复制工作。为此,复制容器命令可以带有两种优先级——普通(Normal)和低(Low)。Balancer 始终发送低优先级的复制容器命令,而 Replication Manager 始终发送普通优先级的命令。低优先级命令不计入 Datanode 心跳所上报的队列大小。如果 Datanode 队列中存在普通优先级的命令,则低优先级命令不会被处理。这样,即使 Balancer 排期了大量的工作,一旦需要执行关键的复制工作,后者也能获得优先处理。
Balancer 排期的命令还带有更长的超时时间,以便留出足够时间完成大批量的工作,同时也为可能拖慢其进度的更高优先级命令留出余地。
删除容器副本命令
删除容器相比复制容器是资源消耗更低的操作,但由于一个容器可能包含大量小的 Block 文件,在 Datanode 上执行仍可能需要一定时间,因此同样需要进行限流。
根据容器的放置方式、类型以及放置策略,为解决副本数过多的容器问题,可能需要向特定 Datanode 发送删除容器副本命令,也可能向任意持有该副本副本的节点发送。例如,对于 EC,副本数过多的容器意味着至少某个副本索引存在至少 2 个副本。在这种情况下,删除命令可以发送到任意一个副本,但容器的放置方式可能将其限制为某一个副本。
删除容器命令的限流方式与复制容器命令大致相同。当尝试执行删除命令时,会检查当前的命令计数,如果 Datanode 负载过高,则会尝试另一个副本,或者将该容器重新排队,稍后再尝试。
Balancer 与删除命令
与复制命令不同,删除容器副本命令没有优先级排序,原因有以下几点:
- 删除不如复制重要,因为延迟删除不会导致数据丢失。
- Balancer 的删除命令由复制命令完成所触发,而复制命令的完成速率自然地对删除起到了限流作用。
- 删除命令的资源消耗较小,因此 Datanode 应当能够快速处理大量此类命令。
EC 重建命令
EC 重建命令是在 Datanode 上排期的开销最大的命令。一条重建命令会恢复 1 到 EC 方案中校验(parity)数量个副本,并读取 EC 方案中数据(data)数量个副本。
对于一个 EC 6-3 容器,将使用 6 个 Datanode 作为读取数据的源节点,而 1 到 3 个目标 Datanode 将接收恢复的数据。其中一个目标 Datanode 还将充当协调者,从源节点读取数据,执行 EC 重建计算,并将恢复的数据写入新的本地容器,如果要恢复多个副本,则还会写入远程容器。
协调者节点会接收命令,Datanode 上排队的命令总数仍然可以像以前一样通过 Node Manager 中的命令计数队列进行限流。对于副本命令,命令必须发送给已有的源节点,因此能够接收该命令的节点是受限的。而对于 EC 重建,命令会发送给目标节点,目标节点是从集群中的空闲节点中大致随机选择的。
因此,跟踪已达到命令上限的节点并避免将它们选为目标节点是有意义的。这通过在最后一次调度的命令达到该节点的上限时更新副本管理器中的排除列表来实现。当 Datanode 心跳时,会有一个回调通过 replicationManager.DatanodeCommandCountUpdate() 通知副本管理器,从而将节点从排除列表中移除。目前,排除列表仅在为重建命令选择目标节点时使用,不用于副本命令。
EC 重建命令在 Datanode 上与副本命令共享相同的限制,但重建命令被赋予一个权重(当前默认为 3),因为它们对协调者节点来说运行成本更高。
EC 重建限流的局限性
对于 EC 重建,一条重建命令会涉及许多其他节点。命令协调者需要从多个源读取数据,并写入自身,如果要恢复多个副本,还可能写入其他节点。如果许多节点同时尝试进行 EC 重建,仅仅限制某个给定节点上排队的命令数量可能无法提供充分的限流效果。
对于副本复制,整个容器必须打包并以单个流发送到新的目标节点。而 EC 会按块读取容器,更像是客户端从集群中读取数据,因此它对主机产生的读取负载可能不如副本复制那样密集,并且会分散在更长的时间内,从而可以在不出现性能问题的情况下交织更多的请求。
EC 容器组也应该比 Ratis 容器更大。一个组中的总数据大小最多可达到 Ratis 容器的 10 倍(EC-10-4),因此在给定数据量的情况下,集群中的 EC 容器数量可能比 Ratis 容器更少,从而需要的重建命令也更少。
目前的计划是继续采用上述简单的限流方式,并观察其在实际中的效果。如前所述,还会设置一个全局复制限制,以限制在途操作的总数。
EC 与退役
当承载 Ratis 容器的节点被退役时,该容器的副本通常有 3 个可用来源:一个在正在退役的主机上,另外两个则位于集群中相对随机的其他节点上。这样,退役负载(以及退役速度)就能分摊到更多的节点上。
而对于 EC 容器,正在退役的主机很可能就是那个需要被复制的副本的唯一来源,因此退役过程会更慢。
正在退役的主机通常不会用于 Ratis 读取,除非没有其他可用节点;但它仍会用于 EC 读取,以避免在线重建。随着该节点上退役过程的推进以及新副本的生成,读取负载会随时间逐渐降低。此外,退役中的节点不会用于写入,因此其负载应低于集群中的其他节点。
由于正在退役的主机负载较低,可以提高排队在其上的命令数量,同时扩大用于处理这些命令的执行器线程池的大小。
当 Datanode 切换到退役状态时,会调大复制监督线程池的规模;如果该节点恢复到在役(In Service)状态,则线程池限制会回调到较低的水平。
同样,在调度命令时,SCM 可以向正在退役的主机分配更多命令,因为负载更低且线程池更大,它能更快地处理这些命令。
全局复制命令限制
除了上述 Datanode 的限制外,还可以配置一个全局复制限制,用于限制待创建容器的在途数量。较大的集群比小型集群能够承载更多的在途复制,因此该限制应当是集群中 Datanode 数量、每个 Datanode 可排队命令数量上限以及某个加权因子的函数。
例如,如果每个 Datanode 可以排队 20 条复制命令,集群中有 100 个节点,那么自然的上限就是 20 * 100。然而,这假设命令在所有 Datanode 之间均匀排队,而这不太可能。通过设置全局限制,我们希望所有 Datanode 不会同时被复制命令占满,因此可能希望将上限设为其一半,即加权因子为 0.5,例如 20 * 100 * 0.5 = 1k 个待处理的复制。
在一个极端情况下,这会导致集群中所有 Datanode 都有其最大任务量一半的命令在排队;但在实际中,一些 Datanode 可能达到其上限,而另一些则可能为零或不足一半。
如果各项限制定义得非常精确,使得数据节点在单次心跳内恰好在心跳周期结束时完成所有排队工作,那么将排队命令数减半,数据节点就只会忙碌半个心跳周期。由于所有数据节点的心跳时间各不相同,所有数据节点的忙碌期与空闲期叠加起来,就会形成一种负载分布,其中总有一些数据节点处于空闲状态,从而降低整个集群的负载。
数据节点有队列上限,但它使用线程池(默认 10 个线程)来处理队列。因此,即使队列中有 20 条命令,也只会并发执行 10 条。此外,如果队列中填满了 EC 重建命令,其权重系数为 3,那么上限就是 ceil(20 / 3),即 7,这样在命令开销较大时,并行执行的命令数就减少了。另一种降低或增加集群复制负载的方法是调整数据节点复制线程池的大小。理想情况下,数据节点线程池的规模应当使数据节点能够同时执行与“线程池大小”相当数量的复制任务,而对客户端工作负载的影响很小。虽然网络带宽可能成为限制因素,但磁盘数量更有可能是首个瓶颈,因此线程池大小最好依据节点上的磁盘数量来确定。
与使用命令数量来设置全局上限不同,可以改用 SCM 内部的 ContainerReplicaPendingOps 表。该表会持续统计集群中待创建的副本数量,并通过来自 SCM 的增量容器报告(Incremental Container Reports)以接近实时的方式进行更新。它还能处理可能创建多个副本的 EC 重建命令,因为它会记录每一个被添加的容器,从而可以统计实际添加的容器数量,而不仅仅是命令数量。
全局删除上限
容器副本的删除操作通常针对单个节点,而数据节点已经有专门处理它们的线程池,这限制了并发执行的数量。此外,删除容器不会产生网络开销。因此,删除命令没有全局命令上限。
相关配置参数
默认值以方括号形式列在参数名之后。
hdds.scm.replication.datanode.replication.limit- (20) 可以在某个 Datanode 上排队的复制命令总数。该上限由 number_of_replication_commands + reconstruction_weight * number_of_reconstruction_commands 组成。hdds.scm.replication.datanode.reconstruction.weight- (3) 在将重建命令数计入 Datanode.replication.limit 之前,对多个重建命令所乘的权重。hdds.scm.replication.datanode.delete.container.limit- (40) 可以在指定 Datanode 上排队的删除容器命令总数。hdds.scm.replication.inflight.limit.factor- (0.75) 集群的整体复制任务上限等于健康节点数乘以 Datanode.replication.limit。该系数(取值应在 0 到 1 之间)用于按比例缩减该上限,以减少集群上待创建副本的总数。设置为 0 表示禁用全局上限检查;设置为 1 则会使上限等于上述公式的结果,实际上等同于禁用该限制。不过,如果集群中有大量正在退役的节点,退役节点的上限会高于正常值,因此在极端情况下,设置为 1 仍可能提供一定的限制。hdds.datanode.replication.outofservice.limit.factor- (2.0) 当 Datanode 正在退役时,其复制线程池(hdds.datanode.replication.streams.limit (10))会乘以该系数,以便分配更多线程用于复制。在 SCM 端,对于任何非 IN_SERVICE 状态(即退役或维护中)的 Datanode,其上限也会乘以相同的系数。这样该节点便可以投入更多资源用于复制,因为它将不再用于写入,且读取优先级也会降低。hdds.scm.replication.event.timeout- (300 秒) SCM 允许某个在 Datanode 上调度的任务完成的时长。超过该时长后,Datanode 将丢弃该命令,SCM 则认为该命令已丢失,并在仍有需要时重新调度。
未来构想
限制每个节点的操作数
对于 EC 重建而言,一条重建命令涉及许多其他节点,因此仅在目标节点上进行限流可能并不足够。目标节点在整个集群中的分布很可能是相当随机的,如果集群中每个节点都收到几条重建命令,那么当它试图在其他节点上执行所有操作时,可能会使集群过载。
对于复制命令来说,如果源节点的分布相当随机,而由于某种原因只有少数目标节点,那么让所有源节点都向同一个目标进行复制并不是一件好事。
基于以上两点,我们是否应当尝试限制引用目标节点以外的节点的命令数量?例如,一条复制命令会发送给单个源节点,由它将容器复制到目标节点。我们可以向目标节点计 1,或许也向源节点计 1。一次 EC 重构会引用 EC 数据块数量个源节点和最多 EC 校验块数量个目标节点,我们可以向其中每个节点各计 1。
如果针对某个节点的计数超过了某个阈值,那么就应将该节点排除,不再将其作为目标节点或 EC 源节点使用。
欠复制处理线程目前以循环方式运行:它持续处理自己的队列,直到队列清空,然后进入休眠。任何失败的任务都会保存在一个列表中,并在本轮迭代完成后重新加入队列。
我们可以在一次迭代中保留这样一份“已使用节点”列表,然后将其重置。这样做并不完美,但目标是让数据节点在一到两个心跳周期内完成工作。如果我们将休眠间隔设置为 2 倍的心跳间隔,那么效果可能相当不错。
要维护一份持久化的节点使用计数集合并不容易,因为我们无法得知命令何时完成。
动态调整数据节点复制线程池
从理论上讲,SCM 可以向数据节点发送命令,让其调整线程池大小,从而扩缩可同时运行的复制任务数量。如果 SCM 发现集群中存在大量欠复制,它可以决定增大数据节点的线程池大小,让集群优先修复欠复制问题,而不是处理客户端工作负载。
基于磁盘数量的数据节点复制线程池
磁盘较多的数据节点理应能够比磁盘较少的数据节点同时处理更多的复制任务。集群中也可能存在不同规格的节点,磁盘数量多的数据节点与磁盘数量少的节点,其复制线程池大小在理想情况下应当不同。目前,复制线程池大小是一个静态值,但可以改成磁盘数量的简单函数,例如 2 × 磁盘数量,并设置一个最大值。
类似地,SCM 可以在这些较大的节点上排队更多命令,理想情况下 SCM 应为较大的节点调高队列上限,并在复制任务的任何全局限制中考虑这一点。目前我认为 SCM 并不知道数据节点的磁盘数量,但如果该信息包含在心跳中,SCM 就可以基于磁盘数量(以及复制线程池大小)来设置队列上限。
另一种方式是,数据节点在心跳中带上复制线程池大小,然后 SCM 据此施加复制限制。
评论
登录后参与评论
KnowForge