了解 Cassandra 中的令牌函数
Understanding the Token Function in Cassandra
您好,我正在阅读有关令牌函数的 Cassandra 文档,
我正在尝试为 Cassandra table 实现分页,我无法理解突出显示的行。该文件谈到了 k > 42 和 TOKEN(k) > TOKEN(42) 之间的区别,但我无法理解 "token based comparison"
期待详细解释标记函数在 WHERE 子句中的作用。
Cassandra 数据根据行 PartitionKey
的 Token
进行分区。 token
是使用哈希函数生成的。函数 Token
生成的值是通过将散列函数应用于它的参数而创建的。
也就是说,现在几乎所有驱动程序都默认自动寻呼。
为了了解应该将数据放在哪个 分区 中,C* 对每一行的 PARTITION KEY
进行了一些计算。具体来说,在每个节点上,行按分区程序生成的令牌排序(每个分区的数据按簇键排序)。不同的 partitioners 执行不同类型的计算。
虽然 Murmur3Partitioner calculates the MurmurHash of the partion key, the ByteOrderedPartitioner 使用分区键本身的原始数据字节:当您使用 Murmur3Partitioner 时,您的行按它们的 散列 排序,而当您使用 ByteOrderedPartitioner,您的行按 原始值 直接 排序。
举个例子,假设你有一个 table 这样的:
CREATE TABLE test (
username text,
...
PRIMARY KEY (username)
);
并假设您正在尝试查找与用户名 abcd
和 abce
以及 abcf
对应的行的存储位置。这些字符串的十六进制表示分别是 0x61626364
和 0x61626365
和 0x61626366
。假设我们在两个字符串上应用此 MH3 实现(x86,为简单起见,32 位,没有可选种子),我们分别得到 0x43ED676A
和 0xE297E8AA
以及 0x87E62668
。因此,在 MH3 的情况下,字符串的标记将是这 3 个值,而在 BOP 的情况下,标记将是原始数据值本身:0x61626364
、0x61626365
和 0x61626366
。
现在您可以看到,当使用不同的分区器时,存储按 token 排序的数据会产生不同的结果。 SELECT * FROM test;
查询将 return 行以不同的顺序排列。 可以(但不应该)如果您的数据已经按原始值和[=73=排序,那么这将是一个问题] 您需要以相同的顺序检索它,因为当您使用 MH3 时,该顺序与您的数据完全无关。
回到问题,TOKEN
函数允许您直接通过 数据 的标记进行过滤,而不是 您的数据 . documentation 表示:
ordering with the TOKEN function does not always provide the expected
results. Use the TOKEN function to express a conditional relation on a
partition key column. In this case, the query returns rows based on
the token of the partition key rather than on the value.
例如,您可以发出:
SELECT * FROM test WHERE TOKEN(username) <= TOKEN('abcf');
你会得到什么? abcd
和 acbf
行!!!这是因为顺序 有时 很重要...就像您尝试执行的分页一样, 将由任何可用的 C* 完美地为您处理driver(例如Java driver)。
也就是说,针对每个分区程序的优缺点,新集群的推荐分区程序是 Murmur3Partitioner, you can check the documentation。请注意,分区程序是一个 cluster-wide 设置,一旦设置,您就无法更改它,除非将所有数据推送到另一个集群。
慎重选择。
您好,我正在阅读有关令牌函数的 Cassandra 文档,
我正在尝试为 Cassandra table 实现分页,我无法理解突出显示的行。该文件谈到了 k > 42 和 TOKEN(k) > TOKEN(42) 之间的区别,但我无法理解 "token based comparison"
期待详细解释标记函数在 WHERE 子句中的作用。
Cassandra 数据根据行 PartitionKey
的 Token
进行分区。 token
是使用哈希函数生成的。函数 Token
生成的值是通过将散列函数应用于它的参数而创建的。
也就是说,现在几乎所有驱动程序都默认自动寻呼。
为了了解应该将数据放在哪个 分区 中,C* 对每一行的 PARTITION KEY
进行了一些计算。具体来说,在每个节点上,行按分区程序生成的令牌排序(每个分区的数据按簇键排序)。不同的 partitioners 执行不同类型的计算。
虽然 Murmur3Partitioner calculates the MurmurHash of the partion key, the ByteOrderedPartitioner 使用分区键本身的原始数据字节:当您使用 Murmur3Partitioner 时,您的行按它们的 散列 排序,而当您使用 ByteOrderedPartitioner,您的行按 原始值 直接 排序。
举个例子,假设你有一个 table 这样的:
CREATE TABLE test (
username text,
...
PRIMARY KEY (username)
);
并假设您正在尝试查找与用户名 abcd
和 abce
以及 abcf
对应的行的存储位置。这些字符串的十六进制表示分别是 0x61626364
和 0x61626365
和 0x61626366
。假设我们在两个字符串上应用此 MH3 实现(x86,为简单起见,32 位,没有可选种子),我们分别得到 0x43ED676A
和 0xE297E8AA
以及 0x87E62668
。因此,在 MH3 的情况下,字符串的标记将是这 3 个值,而在 BOP 的情况下,标记将是原始数据值本身:0x61626364
、0x61626365
和 0x61626366
。
现在您可以看到,当使用不同的分区器时,存储按 token 排序的数据会产生不同的结果。 SELECT * FROM test;
查询将 return 行以不同的顺序排列。 可以(但不应该)如果您的数据已经按原始值和[=73=排序,那么这将是一个问题] 您需要以相同的顺序检索它,因为当您使用 MH3 时,该顺序与您的数据完全无关。
回到问题,TOKEN
函数允许您直接通过 数据 的标记进行过滤,而不是 您的数据 . documentation 表示:
ordering with the TOKEN function does not always provide the expected results. Use the TOKEN function to express a conditional relation on a partition key column. In this case, the query returns rows based on the token of the partition key rather than on the value.
例如,您可以发出:
SELECT * FROM test WHERE TOKEN(username) <= TOKEN('abcf');
你会得到什么? abcd
和 acbf
行!!!这是因为顺序 有时 很重要...就像您尝试执行的分页一样, 将由任何可用的 C* 完美地为您处理driver(例如Java driver)。
也就是说,针对每个分区程序的优缺点,新集群的推荐分区程序是 Murmur3Partitioner, you can check the documentation。请注意,分区程序是一个 cluster-wide 设置,一旦设置,您就无法更改它,除非将所有数据推送到另一个集群。
慎重选择。