Cassandra ByteOrderedPartitioner

问题描述 投票:0回答:2

我想在结构如下的表上执行一些范围查询:

CREATE TABLE table(

num int,
val1 int,
val2 float,
val3 text,
...
PRIMARY KEY(num)
)

范围查询应如下所示:

SELECT num, val1, val2 FROM table WHERE num>100 AND num<1000;

我阅读了这篇文章:对 cassandra 表执行范围查询,现在我在使用 ByteOrderedPartitoner 时遇到问题。

我使用 OPSCenter Web 界面并尝试创建新集群。我更改分区程序并出现以下错误:

配置集群时出错:不使用 RandomPartitioner 或 Murmur3Partitioner 时,需要 {ip: token} 形式的 token_map 参数

我找不到 token_map 参数。我究竟做错了什么?我还需要做什么才能启用查询?

我希望有人能帮助我。谢谢!

cassandra cql
2个回答
8
投票

我做错了什么?

您正在使用字节顺序分区器。它的使用已被确定为 Cassandra 反模式......有一段时间了。 Matt Dennis 有一个关于 Cassandra 反模式的slideshare 演示文稿,其中包含一张有关 BOP 的幻灯片: Don't use the Byte Ordered Partitioner

因此,虽然上面的幻灯片是为了幽默,但说真的,不要使用字节顺序分区器。它仍然包含在 Cassandra 中,因此 2011 年使用过它的用户可以有升级路径。 不应使用 BOP 构建新集群。 您应该使用(默认)Murmur3 分区器。

至于如何使用 Murmur3 分区器解决您的问题,您上面链接的问题/答案参考了 Patrick McFadin 的文章“时间序列数据建模入门”。在那篇文章中,演示了三种建模模式。他们应该能够帮助您提出合适的数据模型。基本上,您可以使用集群键对数据进行排序,然后使用范围查询读取它......只是不是通过您的 current 分区键。 CREATE TABLE tableorderedbynum( num int, val1 int, val2 float, val3 text, someotherkey text, ... PRIMARY KEY((someotherkey),num) );

检查您的数据模型,看看是否可以找到另一个密钥来帮助对数据进行分区。然后,如果您使用另一个键作为分区键,使用 num 作为集群键创建一个查询表(就像我上面那样);那么这个范围查询将起作用:

SELECT num, val1, val2 FROM tableorderedbynum WHERE someotherkey='yourvalue' AND num>100 AND num<1000;

编辑20240215

过去 9 年中出现了一些问题和评论,所以我将在这里解决它们:

如果文本列包含日语或韩语等非英语字符,会发生什么?

韩语、日语、中文等语言中的字符实际上以与其罗马对应字符
相同的方式

排序。由于扩展 UTF 字符集现在包含这些语言,因此每个字符都有一个底层 UTF 代码作为其索引,这也是它们的排序方式。

这个答案和链接的幻灯片没有提供为什么使用 BOP 是错误的具体原因。

我想我没有。可以说,Apache Cassandra® 的目标之一是确保数据均匀分布在集群中。在分区有序的范例中,这会成为问题。这是因为大型的、按字母数字排序的数据集很少具有均匀分布的值。

现在,您当然可以争辩说,今天仍然可能出现不均匀的节点。然而,Murmur3 分区器和虚拟节点等先进技术大大降低了发生这种情况的可能性。因此,

cassandra.yaml

的指导意见是:

# The default partitioner is the Murmur3Partitioner. Older partitioners
# such as the RandomPartitioner, ByteOrderedPartitioner, and
# OrderPreservingPartitioner have been included for backward compatibility only.
# For new clusters, you should NOT change this value.  



0
投票

SELECT num, val1, val2 FROM tableorderedbynum WHERE someotherkey = 'yourvalue' AND token(num) > token(100) AND token(num) < token(1000);

请注意,使用随机分区器或 Murmur3 分区器时,类似的查询将无法提供所需的结果,因为令牌不是按顺序生成的,而是本质上是随机的。 

© www.soinside.com 2019 - 2024. All rights reserved.