你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
Azure Service Fabric 中 Reliable Collections 的相关指导原则和建议
本部分提供有关使用可靠状态管理器和 Reliable Collections 的指导原则。 目的是帮助用户避免常见错误。
可靠集合指导原则
这些指导原则被归纳整理成简单的建议,冠以务必、请考虑、避免和切勿等提示语。
- 切勿修改读取操作(例如
TryPeekAsync
或TryGetValueAsync
)返回的自定义类型的对象。 Reliable Collections 与 Concurrent Collections 一样,返回对这些对象的引用,而非副本。 - 在修改返回的自定义类型的对象之前,务必对其进行深层复制。 由于结构和内置类型均按值传递,因此无需对其进行深层复制,除非它们包含要修改的引用类型字段或属性。
- 不要对超时值使用
TimeSpan.MaxValue
。 应使用超时值来检测死锁。 - 切勿在已提交、中止或释放一个事务之后使用该事务。
- 切勿在对其创建的事务范围之外使用枚举。
- 切勿在另一个事务的
using
语句内创建事务,因为它可能会导致死锁。 - 不要通过
IReliableStateManager.GetOrAddAsync
创建可靠状态,请在同一事务中使用可靠状态。 这会导致 InvalidOperationException。 - 务必确保
IComparable<TKey>
实现正确。 系统依赖IComparable<TKey>
进行检查点和行的合并。 - 意图更新某项而读取该项时,切勿更新锁以防止出现某类死锁。
- 请考虑将每个分区的可靠集合数保持在 1000 以下。 建议在可靠集合中包含较多项,而不是使用较多可靠集合且在每个集合中包含较少项。
- 请考虑保留 80 KB 以下的项(例如 Reliable Dictionary 的 TKey + TValue):越小越好。 这会减少大型对象堆的使用量,并降低磁盘和网络 IO 的要求。 通常情况下,还会减少在只更新一小部分值时复制的重复数据。 在 Reliable Dictionary 中实现此效果的常用方法是将一行划分为多行。
- 请考虑使用备份和还原功能进行灾难恢复。
- 避免在同一事务中混合使用单个实体操作和多个实体操作(例如
GetCountAsync
、CreateEnumerableAsync
),因为它们的隔离级别不同。 - 务必处理 InvalidOperationException。 系统可能出于各种原因中止用户事务。 例如,当可靠状态管理器将其角色从“主要”更改为其他角色时,或者当长时间运行的事务阻止截断事务日志时。 在这类情况下,用户可能会收到 InvalidOperationException,指示其事务已终止。 假设用户未请求终止事务,那么,处理此异常的最佳方式是释放事务,并检查是否发出了取消令牌(或者是否更改了副本的角色),如果没有,则创建新的事务并重试。
- 不要在事务中应用并行或并发操作。 一个事务中仅支持一个用户线程操作。 否则,会导致内存泄漏和锁定问题。
- 在提交完成后,请考虑尽快释放事务(尤其是在使用 ConcurrentQueue 时)。
- 请勿在事务中执行任何阻止代码。
- 将字符串用作可靠字典的键时,排序顺序使用默认字符串比较器 CurrentCulture。 请注意,CurrentCulture 排序顺序不同于按顺序的字符串比较器。
- 不要处置或取消提交事务。 不支持此操作,它可能导致主机进程崩溃。
- 在读取多个字典或向多个字典写入内容时,请确保所有并发事务中针对不同字典的操作顺序保持相同,以避免发生死锁情况。
需谨记以下几点:
- 所有 Reliable Collection API 的默认超时值均为 4 秒。 大多数用户应使用默认超时值。
- 所有 Reliable Collections API 中的默认取消标记均为
CancellationToken.None
。 - 可靠字典的键类型参数 (TKey) 必须正确实现
GetHashCode()
和Equals()
。 键必须不可变。 - 若要实现 Reliable Collections 的高可用性,每个服务应至少有一个目标,并且最小副本集大小必须为 3。
- 针对辅助副本的读取操作可能会读取未提交仲裁的版本。 这意味着从单个辅助副本读取的数据版本可能被错误处理。 从主副本读取的数据始终是可靠的,绝不会被错误处理。
- 在一个可靠集合中,由你的应用程序持久保存的数据的安全/隐私是由你决定的,并且受存储管理提供的保护措施制约;即,操作系统磁盘加密可用于保护你的静态数据。
ReliableDictionary
枚举使用按键排序的排序数据结构。 为了使枚举高效,提交将会被添加到临时哈希表中,然后被移动到检查点后的主排序数据结构中。 如果需要验证检查是否存在键,“添加”/“更新”/“删除”操作的最佳运行时为 O(1),最差运行时为 O(log n)。 Gets 可能是 O(1) 或 O(log n),具体取决于你是从最近的提交还是从旧的提交中进行读取。
易失可靠集合的其他指导原则
决定使用易失可靠集合时,请考虑以下事项:
ReliableDictionary
具有易失性支持ReliableQueue
具有易失性支持ReliableConcurrentQueue
不具有易失性支持- 持久化服务无法变为易失性服务。 将
HasPersistedState
标志改为false
需要从头开始重新创建整个服务 - 易失性服务无法变为持久化服务。 将
HasPersistedState
标志改为true
需要从头开始重新创建整个服务 HasPersistedState
是服务级别的配置。这意味着所有集合都可归为持久化集合和易失性集合中的一种。 不能将易失性集合和持久化集合混合- 易失性分区的仲裁丢失会导致数据完全丢失
- 备份和还原不可用于易失性服务