【发布时间】:2021-09-03 22:24:13
【问题描述】:
我在 Cassandra 中找不到太多关于虚拟分区键的主题,但我能找到的内容倾向于您应该完全避免使用它们的想法。通过虚拟,我的意思是一个列,其唯一目的是为所有行包含相同的值,从而将所有数据放在一个节点上并提供尽可能低的基数。例如:
dummy | id | name
-------------------------
0 | 01 | 'Oliver'
0 | 02 | 'James'
0 | 03 | 'Nicholls'
关于为什么应该避免使用虚拟分区键的两个要点是:
1) 您最终会得到数据“热点”。 1 个节点上存储了大量数据,因此该节点周围的流量较多,并且您在集群周围的分布很差。
2) 分区空间是有限的。如果将所有数据放在一个分区上,最终将无法存储更多数据。
我可以理解这些点,并且我同意你肯定想避免这些情况,所以我把这个想法抛在脑后,试着为我的表想一个好的分区键。有问题的表存储站点,在我们的系统中查询表有两种常见的方式。请求单个站点或请求所有站点。
这让我陷入了尴尬的境地,因为该表要么在任何内容或站点 ID 上都被查询,而将唯一字段设置为分区键会给我在请求所有站点的查询时提供非常高的基数和高延迟.
所以我决定只选择一个基数相对较低的任意字段,即使它不能反映实际查询数据的方式,只是因为它比基数过高要好或过低。不过这种方法也有问题。
我可以在 x 列上对我的数据进行分区,但我们有许多客户,他们都以不同的方式使用我们的系统,所以 x 为 1 个客户可能会给出我想要的结果,但可能会给另一个客户带来糟糕的结果。
在这一点上,我的选择已经不多了。我的表中需要一个对所有客户端都一致的字段,但是这个字段不存在,所以我现在正在考虑使用一个新字段,其中包含一个 1-3 的随机数,然后对该字段进行分区,这本质上只是一个虚拟字段。唯一的区别是我想稍微随机化这些值以避免热点和无限的行增长。
我知道这是一个数据建模问题,它因系统而异,当然在某些情况下您必须选择两害相权取其轻(没有完美的解决方案),但我我真正关注的问题是:
在 Cassandra 中,虚拟分区键是完全不应该考虑的,还是在某些情况下可以接受?如果您认为是前者,那么您将如何处理这种情况?
【问题讨论】:
标签: cassandra