3

我们来自 RDBMS 背景,我们正在尝试做的是将现有的数据存储移植到 cassandra,以利用分布式数据库的强大功能。我们的要求是存储一个键的值,可能键是时间(计划使用纪元时间)并检索键范围之间的值

对于测试,我们创建了 ColumnFamily 并使用 cql(通过cqlsh)插入数据:

CREATE COLUMNFAMILY Log( KEY int PRIMARY KEY,Val1 varchar,Val2 varchar);

INSERT INTO Log (KEY,val1, val2) VALUES (1,'673153106.00','448768737.33'); 
INSERT INTO Log (KEY,val1, val2) VALUES (2,'673153106.50','448768737.67'); 
INSERT INTO Log (KEY,val1, val2) VALUES (3,'673153107.00','448768738.00'); 
INSERT INTO Log (KEY,val1, val2) VALUES (4,'673153107.50','448768738.33'); 
INSERT INTO Log (KEY,val1, val2) VALUES (5,'673153108.00','448768738.67'); 
INSERT INTO Log (KEY,val1, val2) VALUES (6,'673153108.50','448768739.00'); 
INSERT INTO Log (KEY,val1, val2) VALUES (7,'673153109.00','448768739.33'); 
INSERT INTO Log (KEY,val1, val2) VALUES (8,'673153109.50','448768739.67'); 
INSERT INTO Log (KEY,val1, val2) VALUES (9,'673153110.00','448768740.00'); 
INSERT INTO Log (KEY,val1, val2) VALUES (10,'673153110.50','448768740.33');

但是我们的选择未能返回正确的数据

select * from Log where KEY>4 and KEY<9;

键| val1 | val2 | 10 | 673153110.50 | 448768740.33 | 8 | 673153109.50 | 448768739.67 |

select * from Log where KEY>4 and KEY<9;

错误请求:开始键的 md5 排序在结束键的 md5 之后。这是不允许的;您可能根本不应该在 RandomPartitioner 下指定结束键

我们做错了什么吗?有没有使用随机分区在键范围之间选择值的解决方案

4

1 回答 1

14

Cassandra 禁止此类查询是有充分理由的。目前,您的所有日志条目都使用主键的 md5 和均匀分布在您的节点上。支持您的查询意味着 Cassandra 必须查询所有节点、检索所有条目、将它们存储在磁盘上并对其进行排序。每当您执行此查询时,都需要这样做。

如果您希望能够执行此查询,您可以使用 Order-Preserving-Partioner,但也不建议这样做,因为如果您按顺序插入数据,您的所有查询都将命中单个节点,从而导致不必要的热点。

通常的解决方案是使用复合主键(例如 index_name + timeuuid)。这将确保您的索引通过使用索引名称的 md5sum 均匀分布在整个集群中。但是访问索引(例如SELECT * FROM log WHERE index_name = ? AND time >= ? AND time < ?)仍然是有效的,因为数据已经按排序顺序存储在负责的节点上md5sum(index_name)。index_name 通常是一些可以帮助您对数据进行分区的键 - user_id 或 application_id 可能是一个不错的选择。

如果您认为单个 index_name 的索引对于单个节点来说可能太大,那么您可以通过将当前年份和月份添加到 index_name 来调整以前的模式。请阅读以下两篇文章以获取更多信息:

于 2012-08-30T08:14:17.197 回答