我正在设计一个多租户Azure Service Fabric应用程序,我们将在Azure Append-Only blob中存储事件数据。
会有两种斑点; 合并blob (每个租户一个);和实例blobs (租户拥有的每个“对象”一个 - 每个租户将有100K +)
每个实例blob 会有一个编写器。此编写器跟踪最后写入的blob位置,从而可以确保(使用条件写入)自上次成功写入以来没有其他编写器写入blob。这是我们将用于为每个实例提供强一致性的重要方面。
但是,对实例blob的所有写入 必须 最终(但是要尽快)到达单个(每个租户)< em> merge blob 。
在正常操作下,我希望这些合并写入在~100 ms内发生。
我的问题是关于我们如何最好地实现这种保证的双写功能:
实现必须保证写入实例blob 的数据最终也会被写入相应的合并blob 完全一次。
必须避免以下不一致之处:
数据已成功写入实例blob ,但从未写入相应的合并blob 。
数据不止一次写入 merge blob 。
答案 0 :(得分:0)
对我来说最简单的方法是使用事件:服务总线或事件中心或任何其他提供程序来保证事件将至少存储在某个地方并且可以到达。此外,它还可以批量写入事件到Blob存储。此外,我认为它将显着降低Service Fabric的压力,并允许在所需的时间处理事件
因此,您可以拥有大量的无状态服务,或者只是Web Workers,它们将从队列中获取新消息并批量发送给Statefull服务。
假设它将是一个合并服务。您需要对这些服务进行分区,并且发送按一个分区分组的一批事件的最佳方法是制作此类无状态服务或Web Worker。
您可以为每个对象创建一个单独的Statefull Actor。但在你的位置,我会尝试创建100k演员或任何其他真正的工作量,看看它会有多贵。如果它太贵而你买不起这样的机器,那么一切都可以在另一个分区的无状态服务中处理。
好的,现在我们有了下一个方案:有些东西会将日志放入ESB中,这些东西会从ESB中批量生成,或者非常频繁地处理事务和处理错误。之后,某些事件会从队列中产生一系列事件,它会将其发送到特定的Merge服务,该服务将数据存储在其状态中并调用特定的actor来执行相同的操作。
一旦actor将其数据写入其状态并且服务执行相同的操作,则ESB中的此类事件可以标记为已处理并从队列中删除。然后,您只需要将Merge服务和actor中的存储数据偶尔写入Blob存储。
如果actor无法存储事件,则操作不完整,Merge服务也不应存储数据。如果演员或合并服务无法访问Blob存储,则将来可以访问它,并且日志将在状态保存时存储,或者至少可以手动从actor /服务中检索日志。
如果无法访问合并服务,我会将此类事件存储在poison message queue中以供稍后处理,或者尝试将日志直接写入Blob存储但是虽然有可能在此刻写入但是有点危险一种存储空间非常低。
答案 1 :(得分:0)