提交到像 Kafka + 具有 ACID 属性的数据库这样的日志?

Commit to a log like Kafka + database with ACID properties?

我正计划测试如何让这种架构发挥作用:

http://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/

所有数据都作为事实存储在日志中,但发布更改时的验证必须针对 table。例如,如果我发送 "Create Invoice with Customer 1",我将需要验证客户是否存在以及其他内容,然后当验证通过时提交到日志并将当前更改放入 table,因此 table 拥有最新的信息,但我拥有所有更改的历史记录。

我可以将日志放入 table 的数据库中(我使用 PostgreSql)。但是,我担心这样做的可扩展性,而且,我希望从多个客户端和 PG 订阅事件流,我所知道的其他 RDBMS 都不允许我在不进行轮询的情况下执行此操作。

但是如果我使用 Kafka,我担心两个存储之间的 ACID,所以 Kafka 可能会得到错误的数据,PG 回滚或类似的东西。

所以:

1- 可以保持 RDBMS 和日志存储之间的一致性,或者 2- 是否可以实时订阅并调整 PG(或其他 RDBMS)以实现快速事件存储?

所提供问题的简单 (1) 答案:

  1. 正确设置 transaction isolation level 可能足以实现一致性,而不用担心数据库回滚。除非将隔离级别设置为 'serializable',否则您仍然偶尔会造成不一致。即使那样,您也可以保证保持一致,但仍然可能有不良行为。例如,客户创建一个客户并使用异步 API 快速连续地开具发票,发票事件首先到达您的支持系统。在这种情况下,发票事件将失效,客户将需要重试,希望客户是在那个时候创建​​的。如果您控制客户端并强制他们使用 sync API.

  2. ,则很容易避免
  3. 是否可以将事件存储在关系数据库中取决于您预期的数据集大小、硬件和访问模式。我是 Postgres 的忠实粉丝,您可以做很多事情来使事件查找非常快。我的经验法则——如果您的运行 table 大小低于 2300-300GB 并且您有一台不错的服务器,Postgres 是一个不错的选择。对于事件溯源,通常没有连接,并且常见的访问模式是通过 ID 获取所有事件(可选地受时间戳限制)。如果您巧妙地建立索引,Postgres 擅长这种查询。但是,事件订阅者将需要提取此数据,因此如果您有数千个订阅者,则可能不太好,这在实践中很少见。

"Conceptually correct" 回答: 如果您仍想采用流式处理方法并从根本上解决竞争条件,那么您必须为系统中的所有事件提供事件顺序保证。例如,您需要能够对 'add customer 1' 事件和 'create invoice for customer 1' 事件进行排序,以便随时保证一致性。对于分布式系统来说,这通常是一个很难解决的问题(参见例如矢量时钟)。您可以使用一些适用于您的特定情况的巧妙技巧来减轻它,例如在上面的示例中,您可以在事件到达后端时尽早按 'customerId' 对事件进行分区,然后您可以保证与同一客户相关的所有事件都将(大致)按照创建顺序进行处理。

如果需要,很乐意澄清我的观点。

(1) 简单与简单:mandatory link