主题说明了一切。我希望能够随机分发大量记录,但每个节点将它们聚集在一个宽行中。
举个例子,假设我收集了大约100万条记录,每条记录都有一个唯一的ID。如果我继续将主键(以及分区键)设置为唯一ID,我将在我的服务器集群中获得非常好的随机分布。但是,每条记录都是自己的行。我想让每个记录属于一个大的宽行(每个服务器节点),所以我可以将它们排序或聚集在其他列上。
如果我说我的群集中有5个节点,我可以在创建时随机分配1到5的值,并将分区键设置为此值。但是,如果我添加或删除节点,这会变得很麻烦。我想要的是对记录模数N的唯一id进行分区(id%N;其中N是节点数)。
我必须想象Cassandra中有一种基本上随机化分区的机制,甚至不使用密钥(然后在某些列上进行聚类)。
感谢您的帮助。
答案 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行,而不是几乎所有这些用你的方法。