Cassandra 数据建模少于 1000 条记录以适应一行

Cassandra data modelling less then 1000 records to fit in one row

我们有一些由生成的 UUID 唯一标识的实体。我们需要支持按名称查找查询。我们还需要支持按名称排序。

我们知道不会有超过 1000 个该类型的实体完全适合一行。硬编码主键是否可行,使用 name 作为聚类键,使用 id 作为聚类键以满足唯一性。假设我们需要学校实体。这是示例:

CREATE TABLE school (
  constant text,
  name text,
  id uuid,
  description text,
  location text,
  PRIMARY KEY ((constant), name, id)
);

初始状态会给我所有学校,然后会按确切名称进行过滤。我们这样做的原因是将所有学校放在单行中以便快速访问,将 name 作为聚类列用于过滤,并将 id 作为聚类列以保证唯一性。我们可以使用 constant = school 作为已知的硬编码值来访问此行。

我喜欢这个解决方案的一点是所有值都在一行中,而且我们可以快速读取。我们也可以通过聚类列轻松解决排序问题。我不喜欢的是 constant 的硬编码值,它的接缝很奇怪。我们可以使用 name 作为 PK,但是我们会有 1000 条记录分布在几个分区中,可能会发现所有没有名称的记录会更慢并且不会被排序。

问题 1

这是可行的解决方案吗?它是否存在我们没有发现的任何问题?我没有看到任何关于使用硬编码主键的 Cassandra 数据建模的示例,可能是出于这个原因,所以我们怀疑这个解决方案。

问题二

名称是可编辑的字段,它可能很少更改(有人可能会打错字或学校可以更改名称)但它可以更改。实现这一目标的最佳方法是什么? Delete insert inside batch(LTE 可以应用于带条件子句的同一行)?

是的,对于这么小的数据集,这是一个很好的方法。仅仅因为 Cassandra 可以跨多个节点对大型数据集进行分区并不意味着您需要对每个 table 使用该功能。通过为分区键使用常量,您是在告诉 Cassandra 您希望将数据存储在一个节点上,以便您可以按排序顺序快速访问数据。关系数据库一直作用于单个节点中的数据,所以这确实不是什么不寻常的事情。

为了安全起见,您可能希望使用大于 1 的复制因子,以便单个分区至少有两个副本。这样,如果存储数据的一个节点出现故障,您将不会失去对数据的访问权限。

如果您希望有很多客户端(即数千个客户端)经常读取和写入此 table,此方法可能会导致问题,因为它可能成为热点。只有 1000 条记录,您可以通过设置 table 缓存所有键和行来将所有行缓存在内存中。

您可能不会找到很多这样做的示例,因为人们转向 Cassandra 是为了支持大型数据集,他们希望通过使用多个分区获得可扩展性。所以例子是针对那个的。

Is this viable solution and are there any problems with it which we do not see? I did not see any example on Cassandra data modelling with hardcoded primary key probably for the reason so we are doubting this solution.

我在今年早些时候的文章中简要介绍了这种类型的建模解决方案:We Shall Have Order! 这就是所谓的 "dummy key,",其中每一行都具有相同的分区键。这是一个快捷方式,可让您通过聚类列轻松地对所有行(在未绑定的 SELECT * 上)进行排序。

此解决方案存在的问题:

  • Cassandra 允许每个分区键最多有 20 亿个列值。使用虚拟分区键时,您添加的每个值都会接近此限制。

  • 您的数据将全部存储在同一个分区中,这将在您的集群中创建一个 "hot spot"(大数据分组)。这意味着您的数据模型将立即使 Cassandra 的主要优势之一失效……数据分布。这也会使负载平衡复杂化(相同的节点和范围将继续为您的所有请求提供服务)。

  • 我可以看到您的模型是围绕 SELECT * 查询设计的。当您可以为 Cassandra 提供特定的查询键时,Cassandra 的效果最好。未绑定 SELECT * 查询(没有 WHERE 子句的查询)不适合使用 Cassandra,因为它们会导致超时(随着数据的增长)。

通过阅读您的问题,我知道您会说您只将它用于 1000 行。您的数据集永远不会超过这 1000 行,因此您不会遇到我提到的任何障碍。

那么我想知道,你为什么使用 Cassandra? 作为 Cassandra MVP,我不常问这个问题。但是您没有特别大的数据集(这是 Cassandra 旨在处理的数据集)。依靠这个事实作为 错误使用产品的理由 并不是最好的解决方案。

老实说,我建议您为自己省去一些复杂性,改用 RDBMS。这将比 Cassandra 更适合您的用例。然后您可以根据需要更新和订购任何字段。