Apache kafka 数据存储/BigTable ACID和密钥更新通知
我有一个Kafka主题,它包含目录数据和以下命令:Apache kafka 数据存储/BigTable ACID和密钥更新通知,apache-kafka,google-cloud-platform,google-cloud-datastore,google-cloud-bigtable,Apache Kafka,Google Cloud Platform,Google Cloud Datastore,Google Cloud Bigtable,我有一个Kafka主题,它包含目录数据和以下命令: 项目\插入 部分项目更新 删除项目 全部删除 现在我需要使用这个主题,可能的100k msgs/sec流,到一些DB,这将帮助我将原始命令流转换为项目流状态。因此,DB中只有当前项状态。基本上DB将用于查找 我的想法是: 在数据存储中插入/更新/删除项 一旦处理了特定的消息,我将向另一个流发送新消息,告诉下游消费者某些项目已插入/更新/删除。这些使用者随后将从数据存储中读取项目的当前状态,并将项目状态摄取到另一个卡夫卡主题 我担心的是数据存储的
如果您有任何其他解决此问题的想法/建议,我将很高兴。首先要考虑的是消息速率。数据存储无法支持每实体组写入速率超过1/秒(每个实体都是实体组的一部分),请参阅。因此,如果您希望每秒更新多个项/实体,则数据存储不适合 要使用云数据存储实现ACID,您需要避免。这是可能的 通过以下方法可以避免读取实体值的最终一致性 使用仅键查询、祖先查询或按键查找( get()方法)。我们将在中讨论这些不同类型的查询 下面有更多的深度 我将放弃祖先查询作为一种可能性,因为它将要求所有相应的实体都位于同一个实体组中,从而放大了上述写入限制的影响。另见 棘手的部分是
upsert
操作,更具体地说是创建新实体和更新/删除现有实体之间的区别
如果您不能始终从项目数据生成/确定唯一的项目标识符(或传递上一阶段确定的唯一项目标识符),则意味着您需要一个查询,该查询无法在事务内部执行,其结果将取决于最终的一致性。数据存储也不适合这种情况
但是如果您可以获取这样的唯一标识符,那么您可以将其用作实体键标识符,事情很简单:upsert
操作变成一个简单的事务性尝试,通过该键获取实体(强一致),并且(在同一事务中):
- 如果
失败且代码不存在,则使用该键创建一个新实体get
- 如果
成功,则更新实体并将其保存回去获取
upserts
具有很强的一致性。Bigtable用户设计的模式将其所有事务数据都放在一行中
Cloud Bigtable支持upserts
,并且在insert
和update
之间没有区别。还有一个delete by range,理论上可以用于delete_all
案例
高交易率和低成本是使用Cloud Bigtable的正确原因。或者,您可以考虑使用云扳手,它是用于高吞吐量事务数据的。