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 个事件仍然需要处理,但整个事情停止了)
在上图中,您可以看到特定副本的详细信息。此副本与其他辅助副本之间的唯一区别在于以下值:
- 读取状态
- 写入状态
- 当前服务操作
- 队列内存大小(在复制队列中)
- 第一个序列号(在复制队列中)
- 上次复制操作接收时间 Utc
- 上次复制操作接收时间 Utc
- 上次确认发送时间 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 之前的最后一个日志总是
- 交易前
- 预出队
- 出队
如前所述,这是在最新的 SDK (18-7-2016) 上完成的,据称该 SDK 对类似问题进行了错误修复。该问题也发生在较旧的 SDK 上,并且在当时更为频繁。但即使在新版本上,每个 运行.
仍然可以重现
此警告意味着当服务的主要副本在重新配置期间更改角色时,您的服务不会退出 RunAsync(请查看上一个屏幕截图中的运行状况警告)。确保在每个可能的代码路径中都遵守该取消标记。这也适用于通信侦听器 - 确保它们响应 CloseAsync()。
根据您所说的,以下是最有可能发生的情况:
- 我们在新节点上构建了一个新副本(可能用于负载平衡)。此时,在重新配置完成之前,您暂时拥有 4 个副本。
- 我们尝试将主副本交换到这个新副本。
- 您当前的主要角色被告知更改角色,这意味着取消 RunAsync 并关闭通信侦听器。
- 您当前的主要角色未完成其角色更改 - RunAsync 未退出或您的通信侦听器未关闭。
- 重新配置被卡住,等待当前主要角色完成更改。
- 发出健康警告。
重新配置完成后,您的副本集大小将减少到您的目标 3。
我们不会终止您的慢速副本,因为我们不知道您的应用程序是否正常 - 可能需要很长时间才能安全地处理有价值的数据 - 我们不知道。 Service Fabric 对安全性非常偏执,不会做任何可能导致您的服务丢失数据的事情。
遗憾的是,Service Fabric Explorer 没有显示重新配置状态,它显示的是预期的最终结果。但是,如果您在 PowerShell 中 运行 Get-ServiceFabricPartition,它将向您显示分区的重新配置状态。
这种事我见多了,一直在用头撞砖墙。
但是请查看最新版本 - 5.1.163 和 2.1.163 - 这似乎已经解决了我的问题。
在应用程序负载测试期间(使用动态负载报告服务)整个应用程序停止工作,因为有状态分区的一个副本发出警告。
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 个事件仍然需要处理,但整个事情停止了)
在上图中,您可以看到特定副本的详细信息。此副本与其他辅助副本之间的唯一区别在于以下值:
- 读取状态
- 写入状态
- 当前服务操作
- 队列内存大小(在复制队列中)
- 第一个序列号(在复制队列中)
- 上次复制操作接收时间 Utc
- 上次复制操作接收时间 Utc
- 上次确认发送时间 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 之前的最后一个日志总是
- 交易前
- 预出队
- 出队
如前所述,这是在最新的 SDK (18-7-2016) 上完成的,据称该 SDK 对类似问题进行了错误修复。该问题也发生在较旧的 SDK 上,并且在当时更为频繁。但即使在新版本上,每个 运行.
仍然可以重现此警告意味着当服务的主要副本在重新配置期间更改角色时,您的服务不会退出 RunAsync(请查看上一个屏幕截图中的运行状况警告)。确保在每个可能的代码路径中都遵守该取消标记。这也适用于通信侦听器 - 确保它们响应 CloseAsync()。
根据您所说的,以下是最有可能发生的情况:
- 我们在新节点上构建了一个新副本(可能用于负载平衡)。此时,在重新配置完成之前,您暂时拥有 4 个副本。
- 我们尝试将主副本交换到这个新副本。
- 您当前的主要角色被告知更改角色,这意味着取消 RunAsync 并关闭通信侦听器。
- 您当前的主要角色未完成其角色更改 - RunAsync 未退出或您的通信侦听器未关闭。
- 重新配置被卡住,等待当前主要角色完成更改。
- 发出健康警告。
重新配置完成后,您的副本集大小将减少到您的目标 3。
我们不会终止您的慢速副本,因为我们不知道您的应用程序是否正常 - 可能需要很长时间才能安全地处理有价值的数据 - 我们不知道。 Service Fabric 对安全性非常偏执,不会做任何可能导致您的服务丢失数据的事情。
遗憾的是,Service Fabric Explorer 没有显示重新配置状态,它显示的是预期的最终结果。但是,如果您在 PowerShell 中 运行 Get-ServiceFabricPartition,它将向您显示分区的重新配置状态。
这种事我见多了,一直在用头撞砖墙。
但是请查看最新版本 - 5.1.163 和 2.1.163 - 这似乎已经解决了我的问题。