【发布时间】:2014-05-19 20:41:57
【问题描述】:
我的 Cassandra ColumnFamily 使用 Murmur3Partitioner,并具有复合分区键。 使用这个分区器,我试图创建一个令牌,但是这个令牌工厂似乎只允许长值。 是否可以为“token(partition_column1, partition_column2)”之类的东西生成这些哈希?
【问题讨论】:
标签: cassandra murmurhash
我的 Cassandra ColumnFamily 使用 Murmur3Partitioner,并具有复合分区键。 使用这个分区器,我试图创建一个令牌,但是这个令牌工厂似乎只允许长值。 是否可以为“token(partition_column1, partition_column2)”之类的东西生成这些哈希?
【问题讨论】:
标签: cassandra murmurhash
它应该可以工作。事实上,如果您的分区键是复合键,您应该无法仅为单个列创建令牌。您确定您已正确定义复合键吗?
cqlsh:testks> create table t1(k1 int, k2 text, v text, primary key((k1, k2)));
cqlsh:testks> insert into t1(k1, k2, v) values (1, 'key', 'value');
cqlsh:testks> select * from t1;
k1 | k2 | v
----+-----+-------
1 | key | value
(1 rows)
cqlsh:testks> select token(k1) from t1;
Bad Request: Invalid number of arguments in call to function token: 2 required but 1 provided
cqlsh:testks> select token(k2) from t1;
Bad Request: Invalid number of arguments in call to function token: 2 required but 1 provided
cqlsh:testks> select token(k1, k2) from t1;
token(k1, k2)
---------------------
8064425790465501062
(1 rows)
【讨论】:
partitioner.getToken(ByteBuffer) API。具体可以看github.com/apache/cassandra/blob/trunk/src/java/org/apache/…中CQLtoken()函数的实现。
这是计算哈希的公式,我在 Datastax 网上找到的:
(((2**64 / number_of_tokens) * i) - 2**63) for i in range(number_of_tokens)
此散列函数创建分区键的 64 位散列值
所以哈希可以在 -2^63 到 +2^63-1 的范围内(2 到 63 次方)
【讨论】:
计算复合分区键令牌的算法: Primary_key((text, int)) -> 因此分区键是composite_partition_key (text, int)。
示例:带有 Composite_partition_key ('hello', 1) 的行
应用算法:
1- 以大端(16 位)表示形式对复合分区键的组件进行布局:
first_component = '你好' -> 68 65 6c 6c 6f
sec_component = 1 -> 00 00 00 01
68 65 6c 6c 6f 00 00 00 01
2-在每个组件之前添加两个字节长度的组件
first_component = 'hello', length= 5-> 00 05 68 65 6c 6c 6f
sec_component = 1,因此长度 = 4 -> 00 04 00 00 00 01
00 05 68 65 6c 6c 6f 00 04 00 01
3-在每个组件后添加零值
first_component = 'hello' -> 00 05 68 65 6c 6c 6f 00
sec_component = 1 -> 00 04 00 00 00 01 00
4-结果
00 05 68 65 6c 6c 6f 00 00 04 00 00 00 01 00
现在将结果作为您的 murmur3 函数理解的二进制基数传递(确保它是 cassandra 变体)。
【讨论】: