我们来自RDBMS背景,我们要做的是将现有数据存储移植到cassandra,以利用分布式数据库的强大功能。 我们的要求是存储关于密钥的值,可能关键是时间(计划使用纪元时间)和检索关键范围之间的值
对于测试,我们使用cql(通过cqlsh
)创建了ColumnFamily并插入了数据:
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;
KEY | val1 | val2 | 10 | 673153110.50 | 448768740.33 | 8 | 673153109.50 | 448768739.67 |
select * from Log where KEY>4 and KEY<9;
错误请求:启动密钥的md5在结束密钥的md5之后排序。这不是 允许;你可能根本不应该指定结束键 RandomPartitioner
我们做错了什么?。是否有任何解决方案可以使用randompartition在键范围之间选择值
答案 0 :(得分:14)
Cassandra禁止这种查询是有充分理由的。目前,通过使用主键的md5总和,所有日志条目均匀分布在节点上。支持您的查询意味着Cassandra必须查询所有节点,检索所有条目,将它们存储在磁盘上并对它们进行排序。每当执行此查询时,都需要这样做。
如果您希望能够执行此查询,您可以使用Order-Preserving-Partioner,但也不建议这样做,因为如果您按顺序插入数据,所有查询都会遇到单个节点,从而导致不必要的热斑点。
通常的解决方案是使用复合主键(例如index_name + timeuuid)。这将确保您的索引通过使用indexname的md5sum均匀分布在群集中。但访问索引(例如SELECT * FROM log WHERE index_name = ? AND time >= ? AND time < ?
)仍然有效,因为数据已经按照排序顺序存储在负责md5sum(index_name)
的节点上。 index_name通常是一些帮助您对数据进行分区的键 - user_id或application_id可能是一个很好的候选者。
如果您认为单个index_name的索引可能对单个节点来说很大,那么您可以通过将当前年份和月份添加到index_name来调整先前的架构。请阅读以下两篇文章以获取更多信息: