【问题标题】:AWS Event-Sourcing implementationAWS 事件溯源实施
【发布时间】:2018-10-03 16:57:43
【问题描述】:

我是微服务和事件溯源方面的新手,我正试图找出一种在 AWS 上部署整个系统的方法。

据我所知,实现事件驱动架构有两种方法:

  • 使用 AWS Kinesis 数据流
  • 使用 AWS SNS + SQS

所以我的基本策略是将每个命令转换为存储在 DynamoDB 中的事件,并利用 DynamoDB 流向其他微服务通知新事件。但是怎么做?我应该使用前两种解决方案中的哪一种?

第一个有以下优点:

  • 消息排序
  • 至少一次交货

但是缺点还是挺成问题的:

  • 没有内置的自动缩放功能(您可以使用触发器来实现)
  • 没有消息可见性功能(显然是要求确认)
  • 没有主题订阅
  • 非常严格的读取事务:您可以使用我阅读的here 中的多个分片来改进它,您必须具有未明确定义的具有不同调用优先级的 lamda 数量,并且未明确定义策略以避免跨多个实例重复处理相同的微服务。

第二个的优点是:

  • 完全托管
  • 非常高的 TPS
  • 主题订阅
  • 消息可见性功能

缺点:

  • SQS 消息是尽力排序的,但仍然不知道它们的含义。 它说“标准队列会尽最大努力保持消息的顺序,但消息的多个副本可能会乱序传递”。 这是否意味着给消息的 n 个副本,与其他消息的副本相比,第一个副本是按顺序传递的,而其他副本是无序传递的?或者“更多”可能是“全部”?

非常感谢您的各种建议!

【问题讨论】:

    标签: amazon-web-services microservices event-sourcing event-driven


    【解决方案1】:
    I'm quite a newbe in microservices and Event-Sourcing
    

    查看 Greg Young 的演讲 Polygot Data 以更深入地了解接下来的内容。

    跨服务边界共享事件有两种基本方法 - 推送模型和拉取模型。对于关心事件顺序的订阅者,拉模型更易于维护。

    基本思想是每个订阅者跟踪自己的高水位标记以了解其已处理的流中的事件数量,并查询事件列表的有序表示以获取更新。

    在 AWS 中,您通常会通过向权威服务查询更新的事件列表(其实现可能包括分页)来获取此表示。该服务可能通过直接查询 dynamodb 或通过从 DynamoDB 获取最新密钥,然后在 S3 中查找事件的缓存表示来提供事件列表。

    在这种方法中,被推出系统的“事件”实际上只是通知,允许订阅者减少写入 Dynamo 和他们自己读取之间的延迟。 p>

    我通常会使用 SNS(扇出)来广播通知。需要记账支持以处理已处理的通知的消费者将使用 SQS。但是传递有序事件的主要渠道是拉。

    我自己并没有仔细研究 Kinesis - 有一些 general discussion in earlier questions - 但我认为 Kevin Sookocheff 在他写作时会有所收获

    ...如果你再深入一点,你会发现 Kinesis 非常适合一个非常特殊的用例,如果你的应用程序不适合这个用例,Kinesis 可能比它的价值要麻烦得多。

    Kinesis 的主要用例是收集、存储和处理实时连续数据流。数据流是由数千个数据源连续生成的数据,这些数据源通常同时发送数据记录,并且大小很小(以千字节为单位)。

    Another thing: the fact that I'm accessing data from another 
    microservice stream is an anti-pattern, isn't it?
    

    嗯,将系统划分为微服务的部分目的是减少系统功能之间的耦合。跨微服务边界访问数据会增加耦合。所以那里有些紧张。

    But basically if I'm using a pull model I need to read 
    data from other microservices' stream. Is it avoidable?
    

    如果您查询所需信息的服务,而不是自己从流中挖掘出来,您可以减少耦合 - 就像向服务请求数据而不是访问 RDBMS 并自己查询表一样。

    如果您可以完全避免在服务之间共享信息,那么耦合度会更低。

    (简单示例:订单履行需要知道订单何时已付款;因此在付款时它需要一个相关性 id,但它不需要任何其他计费详细信息。)

    【讨论】:

    • 那个视频让我大吃一惊。我见过的最有趣的演讲。太感谢了。我之前从未考虑过拉模型,因为我认为当您写入 ES 时,它会存储和发布事件,并且必须假设一个推模型(更简单且更直接)。这是正确的,直到你无法实现它。所以你的建议是有一个共同的事件流或有更多的事件流按事件的主题分组?另一件事:我从另一个微服务流访问数据这一事实是一种反模式,不是吗?
    • 但基本上,如果我使用拉模型,我需要从其他微服务的流中读取数据。可以避免吗?
    • 非常感谢,我终于明白了。特别是对于 AWS,这是我的想法:我将 DynamoDB 用作 ES,使用 Dynamo Streams 我将事件放在 S3 上,我将用作获取数据的服务。在这种情况下,“主题”是 S3 存储桶,基本上我查询 eventId 的子集。由于我不想拥有重复的事件存储,因此我还将查看诸如 TTL 或 S3 对象的到期期限之类的东西。这是一个很好的解决方案吗?是不是太贵了?
    • 我发现,它很便宜,但不允许批量获取对象。我必须更多地研究我的问题并找出解决所有问题的方法。无论如何,非常感谢您的宝贵时间和建议!
    • 还有一个问题:在拉取模型中,我们通常会从同一个主题拉取多个实例。我们处于竞争消费者模式。如何实现有序处理?我的意思是,给定事件“用户创建”和“用户删除”,如果我们有一个服务使用这些事件,并且在“创建”之前处理“删除”,我们就会遇到一些一致性问题。如何避免?
    猜你喜欢
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2020-05-27
    • 2021-06-24
    • 1970-01-01
    • 2019-01-31
    相关资源
    最近更新 更多