Service Fabric无法重新配置副本

P. *_*erg 4 azure-service-fabric

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

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
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述 在此输入图像描述

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

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

我也觉得奇怪的是副本状态说:准备就绪而不是重新配置.由于读/写状态表明它仍在重新配置,我正在运行最新的SDK(2.1.163,发布于18-07-2016).我认为错误修正在那里,但尽管它变得更难以重现它仍然发生.有谁知道可能导致这个或如何解决这个问题?

编辑:失败分区的屏幕截图 在此输入图像描述


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

在Vaclav的响应后,我开始记录RunAsync中的所有内容,以确定实际导致问题的原因.因此,如果请求取消,代码的哪一部分不会退出.正如瓦茨拉夫指出,当要求取消时,该方法并没有停止.然而,似乎它被卡住的代码部分是本机Service Fabric.

using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
  await tx.CommitAsync();
}
Run Code Online (Sandbox Code Playgroud)

队列是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
Run Code Online (Sandbox Code Playgroud)

在每一行我都记录了cancelationrequest的值,并且当取消请求被触发时,后台任务将记录.结果我们得到了这样的例子:

pre transaction: False
predequeue: False
dequeued: False
CancelationTokenFired: True
Run Code Online (Sandbox Code Playgroud)

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

  1. 预交易
  2. predequeue
  3. 取出的

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

Vac*_*cek 6

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

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

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

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

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

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