Service Fabric无法重新配置副本

时间:2016-07-21 14:52:51

标签: 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

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

enter image description here enter image description here

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

  1. 阅读状态
  2. 写入状态
  3. 当前服务运营
  4. 队列内存大小(在复制队列中)
  5. 第一个序列号(在复制队列中)
  6. 上次复制操作收到的时间Utc
  7. 上次复制操作收到的时间Utc
  8. 上次确认已发送时间Utc
  9. 我也觉得奇怪的是副本状态说:准备就绪而不是重新配置。由于读/写状态表明它仍在重新配置 我正在运行最新的SDK(2.1.163,发布于2016年7月18日)。我认为错误修正在那里,但尽管它变得更难以重现它仍然发生。有谁知道可能导致这种情况的原因或如何解决这个问题?

    编辑:失败分区的屏幕截图 enter image description here

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:6)

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

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

  1. 我们在新节点上构建了一个新副本(可能用于负载平衡)。此时,暂时,您有4个副本,直到重新配置完成。
  2. 我们尝试将原色交换到这个新副本。
  3. 告知您当前的主要角色更改角色,这意味着取消RunAsync并关闭通信侦听器。
  4. 您当前的主要人员尚未完成其角色更改 - RunAsync不会退出或您的通讯听众没有关闭。
  5. 重新配置等待当前主要人员完成更改角色。
  6. 发布健康警告。
  7. 重新配置完成后,您的副本集大小将减少到目标值3。

    我们不会因为我们不知道你的应用程序会好起来而杀了你的慢复制品 - 也许它需要很长时间来安全处理有价值的数据 - 我们不会知道。 Service Fabric对安全性非常偏执,并且不会做任何可能导致您的服务丢失数据的事情。

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

答案 1 :(得分:0)

我已经看过很多了,并且已经把头撞在砖墙上一段时间了。

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