Service Fabric 无法重新配置副本

Service Fabric failed to reconfigure replica

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

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

我也觉得奇怪的是,副本状态显示:准备就绪,不再重新配置。正如 read/write 状态所说,它仍在重新配置 我正在 运行 使用最新的 SDK(2.1.163,2016 年 7 月 18 日发布)。我以为错误修复在那里,但尽管它变得更难重现,但它仍然发生了。有谁知道可能导致此问题的原因或如何解决此问题?

编辑:故障分区的屏幕截图


编辑:调试结果,基于 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秒,取消令牌来自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

精确位置可能会有所不同,但 CancellationTokenFired 之前的最后一个日志总是

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

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

仍然可以重现

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

根据您所说的,以下是最有可能发生的情况:

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

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

我们不会终止您的慢速副本,因为我们不知道您的应用程序是否正常 - 可能需要很长时间才能安全地处理有价值的数据 - 我们不知道。 Service Fabric 对安全性非常偏执,不会做任何可能导致您的服务丢失数据的事情。

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

这种事我见多了,一直在用头撞砖墙。

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