【问题标题】:Is it better to subscribe to changes or a full data set?订阅更改或完整数据集更好吗?
【发布时间】:2018-09-23 15:54:47
【问题描述】:

假设我有两个服务AB。服务A 有一组类似[ "foo", "bar" ] 的项目,并且是负责将项目引入系统的服务。服务B 需要订阅这个数据集。有两种方法可以做到这一点:

  1. 订阅完整数据集
  2. 订阅更改

举个具体的例子,假设数据集经历了类似的演变

  • [ "foo", "bar" ]
  • [ "foo", "bar", "baz" ]
  • [ "foo", "baz" ]
  • [ "foo", "baz", "buz" ]

每次更改发送到服务B 的消息可能与上述完全相同,也可能类似于

  • { add: [ "foo", "bar" ], subtract: [] }
  • { add: [ "baz" ], subtract: [] }
  • { add: [], subtract: [ "bar" ] }
  • { add: [ "buz" ], subtract: [] }

问题是哪个会更好。我的观点是第一个更好,原因如下

  • 最终一致性。首先,如果一条消息丢失或出现其他故障导致B 无法处理一条消息,它总是会在它成功处理另一条消息时得到纠正。其次,为了自动纠正这些失败场景,系统会增加很多复杂性。
  • Idemptoency。 与上述类似,如果服务A 意外发送重复消息,在第一种设计中完全可以,而在第二种设计中,这种情况需要额外的复杂性来处理。李>
  • Delta 并不是真正的优化。 最初听起来像是一种优化,说“我们系统的其余部分只会处理更改”,但问题是 有人 必须计算变化,那么为什么应该A 而不是B,这如何减少操作总数?

【问题讨论】:

    标签: design-patterns service microservices publish-subscribe


    【解决方案1】:

    因此,您指出了订阅整个数据集而不仅仅是 delta 的好处,并且这些要点都经过充分考虑,在大多数情况下,从订阅者的角度来看,努力管理 delta 是不值得的。

    但我希望你从制作人的角度来看。生产者必须在处理某些事件,比如 add 和 sub。当事件生成时,它只有“Baz”。 他将处理该操作,然后查询他的系统以检查整个数据并将其发送出去。 然而他本可以把你送出去

    { 加:[“baz”],减:[] }

    因此,在此类情况下,生产者向您发送 delta 的成本会更低。 需要注意的另一件事是这些查询发生了多少次,以及为什么您的订阅者需要它。如果您以商店中的库存为例,那么任何购买事件都将删除库存,并且任何退货都可能增加。 这样的事件太多了,如果我们每次有购买事件时都通过实际读取系统来发送库存更新,那可能会很慢。

    这个故事的另一面,为什么订阅者需要这个,他可能需要它来看看他是否可以展示产品。如果是这样的话,他不会真正关心库存是 10 还是 11 还是 9。 他担心它是否接近于零,在这种情况下,增量更新可能有意义。

    但单独的增量更新可能对您没有帮助。就像你说的那样,它们不是幂等的,也不是一致的。为了解决这个问题,我更喜欢同时使用两者。

    以更小的间隔发送增量更新。让系统变坏,但在它变坏之前通过推送完整的数据集来纠正它。

    对于那些能够忍受 delta 缺点的人来说,可以使用不太可靠但快速的 delta 更新,而对于那些寻求一致性的人来说,可以使用完整的数据更新。但是,您会根据生产者的限制来限制它们。如果它们的成本很高,你就不要频繁地这样做。

    那么一个比另一个更好吗? 我会说,这取决于您的用例,您可以选择其中一个而不是另一个,或者它们可以相互补充。

    【讨论】:

      【解决方案2】:

      首先请注意,如果您使用 set,只要不更改顺序,“add”和“subtract”之类的操作就是幂等的(它实际上是一个有用的属性至少在某些情况下,因为在某些情况下,您的“服务器”可以发送具有相同操作的第二条消息而不会弄乱客户端数据)。

      其次,作为去年使用基于差异的系统的人,我强烈建议在发送完整数据集可行的情况下避免这种情况。当您开始通过多个实体编辑相同的数据时,事情会很快变得复杂。

      当整个数据的大小远大于更新数据的大小时(例如,10^6 项,而您一次更改两个或三个),基于差​​异的方法会更好。显示数据时,您通常需要一个增量(例如,在 UI 中,您从列表中删除两行,而不是删除整个列表然后重新创建它);从两个大数据块计算它可能需要时间。此外,当它们不再适合内存时,尝试对整个数据集进行操作也会成为问题(并且在每次操作时向客户端重新发送兆字节甚至千兆字节的数据是不明智的)。

      【讨论】:

        猜你喜欢
        • 2021-06-09
        • 2016-11-25
        • 2019-06-05
        • 2018-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-03
        相关资源
        最近更新 更多