我需要存储每个每晚构建的基准运行。为此,我提出了以下数据模型。
BenchmarkColumnFamily= {
build_1: {
(Run1, TPS) : 1000K
(Run1, Latency) : 0.5ms
(Run2, TPS) : 1000K
(Run2, Latency) : 0.5ms
(Run3, TPS) : 1000K
(Run3, Latency) : 0.5ms
}
build_2: {
...
}
...
}
为了创建这样的模式,我在cassandra-cli上提出了以下命令:
create column family BenchmarkColumnFamily with
comparator = 'CompositeType(UTF8Type,UTF8Type)' AND
key_validation_class=UTF8Type AND
default_validation_class=UTF8Type AND
column_metadata = [
{column_name: TPS, validation_class: UTF8Type}
{column_name: Latency, validation_class: UTF8Type}
];
以上命令是否创建了我打算创建的模式?我混淆的原因是,当我使用以下内容将数据插入上述CF时:
set BenchmarkColumnFamily['1545']['TPS']='100';
即使比较器类型是复合的,它也会成功插入。此外,即使以下命令也能成功执行
set BenchmarkColumnFamily['1545']['Run1:TPS']='1000';
我失踪了什么?
答案 0 :(得分:2)
cassandra-cli工具在处理复合材料方面非常有限。此外,Cassandra在验证显式的,用户提供的复合材料方面可能会发生一些意想不到的事情。我不知道你的情况的确切答案,但我可以告诉你,你会发现使用CQL 3引擎更容易使用 这种模型。
例如,您的模型可以表示为:
CREATE TABLE BenchmarkColumnFamily (
build text,
run int,
tps text,
latency text,
PRIMARY KEY (build, run)
);
INSERT INTO BenchmarkColumnFamily (build, run, tps, latency) VALUES ('1545', 1, '1000', '0.5ms');
有关如何转换为存储引擎层的详细信息,请参阅this post。
答案 1 :(得分:2)
我认为你做错了什么。 CLI正在使用org.apache.cassandra.db.marshal.AbstractType<T>.fromString()
根据类型解析值的字符串。对于Composite类型,它使用':'作为字段分隔符(不是我见过的文档,但我已经尝试使用Java代码来说服自己。
没有':',它似乎只设置了Composite的第一部分,并将第二部分保留为null。要设置第二个,您可以使用
set BenchmarkColumnFamily['1545'][':NOT_TPS']='999';
从CLI中,转出CF:
list BenchmarkColumnFamily;
你应该看到所有的名字(对于所有的行),例如
RowKey: 1545
=> (column=:NOT_TPS, value=999, timestamp=1342474086048000)
=> (column=Run1:TPS, value=1000, timestamp=1342474066695000)
=> (column=TPS, value=100, timestamp=1342474057824000)
没有办法(通过CLI)将复合元素约束为非空或特定值,这是您在代码中必须做的事情。
此外,创建CF的column_metadata选项是不必要的,因为您已经将默认验证列为UTF8Type。