【问题标题】:Service Fabric failed to reconfigure replicaService Fabric 无法重新配置副本
【发布时间】:2016-11-25 05:48:28
【问题描述】:

在应用程序的负载测试期间(使用动态负载报告服务),整个应用程序停止工作,因为有状态分区的一个副本发出警告。

Warning System.RAP IStatefulServiceReplica.ChangeRole(S)Duration Thu, 21 Jul 2016  3:36:03 GMT Infinity 131135817636324745 false false Start Time (UTC): 2016-07-21 13:35:43.632

这发生在副本的负载平衡之后,这发生在分区的第 4 个副本上,尽管我们只针对 3。所以即使 SF 只是杀死它,应用程序也应该没问题(因为主节点和其他 2 个辅助节点都已启动)。然而,整个事情都卡住了。 (从日志中我可以看到至少 10k 事件仍需要处理,但整个事情都停止了)

在上面的图片中,您可以看到特定副本的详细信息。此副本与其他辅助副本的唯一区别在于以下值:

  1. 读取状态
  2. 写入状态
  3. 当前服务操作
  4. 队列内存大小(在复制队列中)
  5. 第一个序列号(在复制队列中)
  6. 上次接收复制操作的时间 Utc
  7. 上次接收复制操作的时间 Utc
  8. 上次确认发送时间 Utc

我还觉得奇怪的是副本状态显示:已准备好,不再重新配置。正如读/写状态所说,它仍在重新配置 我正在运行最新的 SDK(2.1.163,2016 年 7 月 18 日发布)。我认为错误修复就在那里,但即使重现变得更加困难,它仍然会发生。有谁知道这可能是什么原因或如何解决这个问题?

edit:失败分区的屏幕截图


编辑:调试结果,基于 Vaclav (22-7-2016) 的回答

在 Vaclav 做出响应后,我开始在 RunAsync 中记录所有内容,以确定实际导致问题的原因。那么如果请求取消,代码的哪一部分没有退出。正如 Vaclav 指出的那样,当请求取消时,该方法并没有停止。但是,似乎卡住的代码部分是本机 Service Fabric。

using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
  await tx.CommitAsync();
}

队列是 ReliableQueue,超时设置为默认 4 秒,cancelationtoken 来自 RunAsync。在每行之间添加日志记录后,我们得到了以下日志记录模式

//pre transaction
using(ITransaction tx = StateManager.CreateTransaction())
{
  //pre dequeue
  await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
  //dequeued
  await tx.CommitAsync();
  //committed
}
//post transaction

在每一行我都记录了取消请求的值,当取消请求被触发时,后台任务会记录下来。结果我们得到了例如:

pre transaction: False
predequeue: False
dequeued: False
CancelationTokenFired: True

确切位置可能会有所不同,但 CancelationTokenFired 之前的最后一个日志始终是

  1. 交易前
  2. 提前出队
  3. 出队

如前所述,这是在最新的 SDK (18-7-2016) 上完成的,据称该 SDK 对类似问题进行了错误修复。该问题也出现在较旧的 SDK 上,并且在当时更为频繁。但即使在新版本上,每次运行仍可重现。

【问题讨论】:

  • 我不会将取消令牌用于任何可靠的收集操作。尝试不更改超时或添加取消令牌。
  • @Nick 这就是我们之前所拥有的,但这也不起作用。无论如何,你怎么称呼它也无关紧要:)
  • 这是在适当的集群上还是在本地开发集群上?我可能会在我的 localhost 开发集群上看到类似的东西。
  • @NickRandell 这是在本地开发集群上。
  • 有趣 - 我想知道这个区域是否仍然存在错误,尤其是在本地集群上。自 163 更新以来,我的 azure 集群似乎一直运行良好,但我在本地集群上仍然存在这些问题。我还在 MSDN 服务结构论坛上问过一个关于此的问题。 social.msdn.microsoft.com/Forums/en-US/…

标签: azure-service-fabric


【解决方案1】:

此警告表示当您的服务的主要副本在重新配置期间更改角色时,您的服务未退出 RunAsync(请查看上一个屏幕截图中的运行状况警告)。确保在每个可能的代码路径中都尊重该取消令牌。这也适用于通信侦听器 - 确保它们响应 CloseAsync()。

鉴于你所说的,这就是最有可能发生的事情:

  1. 我们在新节点上构建了一个新副本(可能用于负载平衡)。此时,在重新配置完成之前,您暂时有 4 个副本。
  2. 我们尝试将主节点交换到这个新副本。
  3. 您当前的主节点被告知更改角色,这意味着取消 RunAsync 并关闭通信侦听器。
  4. 您当前的主节点未完成其角色更改 - RunAsync 未退出或您的通信侦听器未关闭。
  5. 重新配置卡住等待当前主节点完成角色更改。
  6. 发出健康警告。

一旦重新配置完成,您的副本集大小将减少回您的目标 3。

我们不会杀死您的慢速副本,因为我们不知道您的应用程序会不会好起来 - 也许需要很长时间才能安全地处理有价值的数据 - 我们不知道。 Service Fabric 非常注重安全性,不会做任何可能导致您的服务丢失数据的事情。

很遗憾,Service Fabric Explorer 没有显示重新配置状态,它显示的是预期的最终结果。但是,如果您在 PowerShell 中运行 Get-ServiceFabricPartition,它将显示分区的重新配置状态。

【讨论】:

  • 我已经测试过了,确实 RunAsync 没有正确关闭,但不是我们的计算需要更长的时间。 SF 的一部分只是卡住了。有关所有信息,请参阅我的帖子上的编辑。我希望你能帮助我。
  • 我们也能够重现这一点。问题是我们在关闭状态管理器之前等待你的 RunAsync 完成,所以如果你恰好在那个时候调用了 CommitAsync,它会不断地旋转尝试提交。在我们发布更新之前,您可以将所有 RunAsync 代码包装在一个任务中并从 RunAsync 运行它,但不要在 RunAsync 中等待该任务。这个想法是允许 RunAsync 完成而无需等待您的代码。当修复可用时,我会更新这个答案。
【解决方案2】:

我经常看到这种情况,并且已经用头撞砖墙有一段时间了。

但是查看最新版本 - 5.1.163 和 2.1.163 - 这似乎已经为我解决了这些问题。

【讨论】:

  • 正如我在帖子中所说的,我已经在那个版本上,它变得更好了一点,但在最新版本上它仍然是一个问题。每次测试都会发生一次
  • 我的错 - 我没有看到那里的版本
猜你喜欢
  • 2018-08-30
  • 2020-05-06
  • 2016-12-16
  • 2016-09-28
  • 2018-11-06
  • 2021-02-01
  • 2017-08-05
  • 2020-07-05
  • 1970-01-01
相关资源
最近更新 更多