我正在计划测试如何使这种架构工作:
http://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/所有数据都作为事实存储在日志中,但发布更改时必须针对表进行验证。例如,如果我发送"使用客户1创建发票",我将需要验证客户是否存在和其他内容,然后当验证通过时,提交到日志并将当前更改放入表中,因此表中有最新的信息,而我有所有更改的历史记录。
我可以将日志放入数据库的表中(我使用PostgreSql)。然而,我担心这样做的可扩展性,而且,我希望从多个客户端订阅事件流,而且我知道的其他RDBMS都不允许我在没有轮询的情况下这样做。
但是如果我使用Kafka,我担心两个存储之间的ACID,所以Kafka可能会得到错误的数据,PG回滚或类似的事情。
:
1-可以在RDBMS和日志存储OR之间保持一致性是否可以实时订阅和调优PG(或其他RDBMS)以实现快速事件存储?
简单(1)回答提供的问题:
-
正确设置事务隔离级别可能足以实现一致性,而不必担心DB回滚。除非将隔离级别设置为"serializable",否则偶尔仍会产生不一致。即使这样,你也可以保证保持一致,但仍然可能有不受欢迎的行为。例如,客户端使用异步API创建客户并快速连续放置发票,发票事件首先到达后台系统。在这种情况下,发票事件将无效,客户端将需要重试,希望在此之前创建客户。如果您控制客户端并强制它们使用同步API,则很容易避免。
-
是否可以在关系数据库中存储事件取决于您预期的数据集大小、硬件和访问模式。我是Postgres的忠实粉丝,你可以做很多事情来让事件查找非常快。我的经验法则是——如果您的操作表大小低于2300-300GB,并且您有一个不错的服务器,那么Postgres是一种选择。事件溯源通常不存在连接,常见的访问模式是按id获取所有事件(可选地受时间戳限制)。Postgres擅长这类查询,只要你能聪明地建立索引。但是,事件订阅者需要提取这些数据,所以如果您有数千个订阅者,这可能不是很好,这在实践中很少出现。
"概念正确"的答案:如果您仍然希望采用流方法并从根本上解决竞争条件,那么您必须跨系统中的所有事件提供事件排序保证。例如,您需要能够订购"添加客户1"事件和"为客户1创建发票"事件,以便您可以随时保证一致性。对于分布式系统来说,这是一个很难解决的问题(参见矢量时钟)。你可以用一些聪明的技巧来缓解它,这些技巧将适用于你的特殊情况,例如,在上面的例子中,你可以在事件到达后端时通过'customerId'来划分事件,然后你可以保证与同一客户相关的所有事件将按照创建的顺序(大致)被处理。
如果需要,我很乐意澄清我的观点。
(1)简单vs简单:强制链接