CQRS+EventSourcing可扩展性

6
我正在尝试在我的新项目中使用CQRS和EventSourcing。我遵循了几年前Greg Young建议的方式(Mark Nijhof实现-http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/)。但是,我对此解决方案的可扩展性存在一些问题。
这篇由Mark Nijhof撰写的文章中提到了一些要点。但现在的问题在于Denormalizer部分,它负责更新报告数据库。我想将这一部分变成异步模式,这样在发布事件到总线后,我就可以立即返回控制权。我们建议将Denormalizer实现为一个独立的Web服务(WCF),该服务将处理传入的事件并按批次进行命令更新报告数据库。它似乎可能会成为瓶颈,因此我们还想在此处添加一些可扩展性-集群解决方案。但在集群情况下,我们无法控制报告数据库更新的顺序(或者我们应该实现一些奇怪的、容易出错的逻辑来检查报告DB中的对象版本)。另一个问题是解决方案的可维护性:如果失败,我们将丢失Denormalizer中的更新,因为我们不会将它们持久化到任何地方。现在我正在寻找解决这个问题(Denormalizer的可扩展性)的方法,欢迎任何想法!
1个回答

4
首先,您肯定希望将去规范化器托管到单独的进程中。从那里,您可以让域发布在域中发生的事件到您的消息基础设施中。一个简单的策略来帮助加速去规范化是按照消息/事件类型拆分内容。换句话说,您可以为每种消息类型创建一个单独的队列,然后让去规范化器(使用消息总线)订阅相应的事件。这样做的好处是您不必担心消息一次排队等候--所有事情都开始并行运行。您可能会在监听多个类型的表上遇到一些争用的地方。即使如此,您现在已经将负载分散在了许多端点之间。
只要您使用某种消息基础设施,您就不会在尝试去规范化时丢失事件消息。相反,在一定数量的失败重试之后,该消息将被视为“有毒”并移动到错误队列中。只需监视错误队列以查找问题。一旦消息位于错误队列中,您就可以检查日志以查看其原因,解决问题,然后将其移回。
还有一个考虑因素是Mark Nijhof的示例有些陈旧。还有许多CQRS框架可供选择,以及DDD/CQRS Google Group中的大量建议。

能否为每个视图模型单独设置队列,而不是按事件设置队列? - Chris Moutray
当然可以。总线基础设施(如NServiceBus)将订阅适当的事件,并告诉发布者它想要特定视图模型适用的消息的副本。 - Jonathan Oliver
谢谢你的回答,Jonathan。嗯,我也考虑过为反规范化器设计一种事件分离策略,例如使用多个队列在单独的线程中。我想这里唯一的规则就是保持每个特定聚合根的事件序列。但问题在于我不知道如何在这种情况下使用集群,或者是否可以使用它,因为集群可能会打破事件序列。 - Voice
首先将事物作为单独的进程启动,然后在您对系统感到满意后合并去规范化器端点。我最近写了一篇博客,介绍如何应用消息来按顺序处理读模型,即使它们不按顺序到达:http://blog.jonathanoliver.com/2011/04/cqrs-out-of-sequence-messages-and-read.html - Jonathan Oliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接