Cassandra - 给定ColumnFamily的每个节点恰好是一行?

时间:2013-12-03 16:24:30

标签: database nosql cassandra

主题说明了一切。我希望能够随机分发大量记录,但每个节点将它们聚集在一个宽行中。

举个例子,假设我收集了大约100万条记录,每条记录都有一个唯一的ID。如果我继续将主键(以及分区键)设置为唯一ID,我将在我的服务器集群中获得非常好的随机分布。但是,每条记录都是自己的行。我想让每个记录属于一个大的宽行(每个服务器节点),所以我可以将它们排序或聚集在其他列上。

如果我说我的群集中有5个节点,我可以在创建时随机分配1到5的值,并将分区键设置为此值。但是,如果我添加或删除节点,这会变得很麻烦。我想要的是对记录模数N的唯一id进行分区(id%N;其中N是节点数)。

我必须想象Cassandra中有一种基本上随机化分区的机制,甚至不使用密钥(然后在某些列上进行聚类)。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

你真的不想做你想说的事情。

首先,确实没有好的机制来确保在Cassandra中每个节点均匀分配一行。您可以通过计算令牌轻松完成一次,这样它们最初会在您的节点之间分配,但如果您曾经更改过群集拓扑(例如添加或删除节点或数据中心),那么您需要手动重新计算和移动数据。所有这一切正是Cassandra为您设计的。

不是按照每个节点一行的严格目标进行,而是妥协一下,并使用大约100-1000个总行。使用最后2位或3位数(为方便起见,您也可以使用其他任何数字)作为分片ID,并创建一个如下表格:

 create table test (shard_id int, id int, value text, primary key (shard_id,id));
 insert into test (shard_id, id, value) values(72,193727872, 'value1');
 insert into test (shard_id, id, value) values(73,193727873, 'value2');
 insert into test (shard_id, id, value) values(73,7234243873, 'value3');
 insert into test (shard_id, id, value) values(73,193727874, 'value4');

 select * from test where shard_id = 73;

  shard_id | id        | value
 ----------+-----------+--------
        73 | 193727873 | value2
        73 | 193727874 | value4
        73 | 723423873 | value3

因此,由于shard_id,您可以在群集中实现数据的均匀分布,并且通过快速枚举shard_ids,您可以检索所有值。每次读取都足够宽(有一百万个+总单元格),您可以利用线性磁盘读取,并且几乎没有足够的随机搜索。

您还可以执行任何其他操作(gt / lt比较)。您只需在代码中执行一些额外的工作,以使读取使用正确的分片ID,并在必要时继续执行下一个分片。

复杂性略有增加。

线性读取性能的降低非常小。

非常好的操作运行时特性。

答案 1 :(得分:0)

您可以尝试使用复合主键,例如,

create table wideRow(key varchar, value timeuuid, primary key (key,value));

由于您使用的是复合主键,因此分区将在key / value组合上完成,而不是仅在key上进行,并将在您的节点之间分配宽行。您的宽行将被分成每个节点一行。

答案 2 :(得分:0)

对id-modulus-cluster-size进行分区与添加和删除前面提到的节点时遇到的问题完全相同。这就是为什么Cassandra所做的事情被称为一致哈希:在向N大小的簇添加新节点时,只需要[最多] 1 / N行,而不是几乎所有这些用你的方法。

更多:http://en.wikipedia.org/wiki/Consistent_hashing