【问题标题】:Create table with many columns Cassandra 2创建具有多列 Cassandra 2 的表
【发布时间】:2016-07-24 17:02:05
【问题描述】:

我需要一个 Cassandra2 上的表,其中包含 56K 列,每列 1 个字节,用于基准测试。

我正在尝试创建一个具有此要求的“用户表”,如下所示:

create table usertable (
    y_id varchar primary key,
    field0 varchar,
    field1 varchar,
    field2 varchar,
     ...
     ...
    field55999 varchar,
    field56000 varchar);

当我尝试使用 CQLSH 从文件执行此操作时,它会永远运行而没有响应并分配大量内存。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: cassandra cqlsh cassandra-2.1


    【解决方案1】:

    尝试将您的CREATE TABLE 语句放在一个平面文件中(例如schema.cql),然后执行cqlsh -f schema.cql

    按他们的说法,56k 列是HUGE,没有理智的开发人员会创建一个包含超过 1k 列的表...在这种情况下你想测试和断言什么?

    ---- 第一条评论的答案--

    Schema 是关于元数据的,因为原始数据无论如何都会以byte[] 的形式写入磁盘上。表中的列越多,内存中的元数据就越大。

    所以在检索时,我将在选择查询中传递特定的列名(牢记性能),因此它不会检索所有列

    事情没那么简单。所有 56k 列都连续存储在磁盘上。在读取数据时,Cassandra 有索引结构来跳过分区键和集群列。对于普通列,就像您的情况一样,没有索引可以获取客户端请求的确切列,例如,如果您正在执行SELECT field1293 FROM usertable WHERE y_id = xxx,Cassandra 将需要从field1 扫描整个块直到@ 987654326@ 在选择正确的列之前进入内存,这是非常非常低效

    --- 第 N 条评论的答案 --

    我同意这会变得非常缓慢/效率低下,但我需要实现这个场景来模拟基因型数据。

    我建议尝试测试此架构:

    create table usertable (
        y_id varchar,
        field_index int,
        field_value varchard, 
        PRIMARY KEY(y_id, field_index)
    );
    
    //INSERT/UPDATE data into field N
    INSERT INTO usertable(y_id, field_index, field_value)
    VALUES('xxx', N, 'fieldN value');
    
    //DELETE field N
    DELETE FROM usertable WHERE y_id='xxx' AND field_index=N;
    
    // Read EXACTLY field N
    SELECT field_value FROM usertable WHERE y_id='xxx' AND field_index=N;
    
    // Read field N to M, N <= M
    SELECT field_value FROM usertable WHERE y_id='xxx' 
    AND field_index >=N 
    AND field_index <= M;
    

    你会发现它的效果更好

    【讨论】:

    • 如果我这样做会受到什么处罚?由于 cassandra 支持每个分区 20 亿个单元。因此,在检索时,我将在选择查询中传递特定的列名(牢记性能),因此它不会检索所有列,那么这种丑陋模式的影响或症状是什么,或者换句话说,什么是行太宽会影响吗?
    • 所以让我们考虑查询SELECT field56000 FROM usertable WHERE y_id = xxx。如果我尝试执行上述查询,那么 56000 列将被加载到内存中,然后它将执行顺序扫描,直到达到 field56000 列名。这就是你的意思对吗?如果我错了,请纠正我。
    • 是的。更准确地说,Cassandra 将按 64kb 的块将 CQL 行数据提取到内存中,并遍历所有连续块,直到找到 field56000。在您的示例中,它必须扫描整个分区。如果请求field00001,会快很多
    • 如果您在架构中使用集群列,Cassandra 将利用分区索引跳过数据块,并从请求的列到达最近的块并开始扫描从这个最近的块开始按顺序排列,优化了很多
    • 我尝试了cqlsh -f schema.cql,但得到了相同的结果。我同意这会变得非常缓慢/效率低下,但我需要实现这个场景来模拟基因型数据。
    猜你喜欢
    • 1970-01-01
    • 2021-08-13
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多