如何将数据从Cassandra表复制到另一个结构以获得更好的性能

时间:2017-01-03 16:48:20

标签: cassandra cql cql3 cqlsh

在一些地方,我们建议根据我们要对它们执行的查询来设计我们的Cassandra表。在this article by DataScale中他们说明了这一点:

  

事实是,拥有许多具有类似数据的类似表格在Cassandra中是件好事。将主键限制为您将要搜索的内容。如果您计划使用类似但不同的标准搜索数据,请将其设为单独的表。以不同方式存储相同数据没有缺点。重复数据是您在Cassandra的朋友。

     

[...]

     

如果您需要在14个不同的表中存储相同的数据,则将其写出14次。多次写入没有障碍。

我已经理解了这一点,现在我的问题是:只要我有一张现有的表,比如说

CREATE TABLE invoices (
    id_invoice int PRIMARY KEY,
    year int,
    id_client int,
    type_invoice text
)

但我希望按年份和类型进行查询,所以我想要像

这样的内容
CREATE TABLE invoices_yr (
    id_invoice int,
    year int,
    id_client int,
    type_invoice text,
    PRIMARY KEY (type_invoice, year)
)

id_invoice作为分区键,year作为群集键,将数据从一个表复制到另一个表的首选方法稍后优化查询?

我的Cassandra版本:

user@cqlsh> show version;
[cqlsh 5.0.1 | Cassandra 3.5.0 | CQL spec 3.4.0 | Native protocol v4]

3 个答案:

答案 0 :(得分:10)

您可以使用cqlsh COPY命令
要将发票数据复制到csv文件,请使用:

COPY invoices(id_invoice, year, id_client, type_invoice) TO 'invoices.csv';

并从csv文件复制回您案例中的表invoices_yr使用:

COPY invoices_yr(id_invoice, year, id_client, type_invoice) FROM 'invoices.csv';

如果您有大量数据,您可以使用sstable编写器和sstableloader来更快地加载数据。 http://www.datastax.com/dev/blog/using-the-cassandra-bulk-loader-updated

答案 1 :(得分:8)

为了回应关于COPY命令的说法,对于这样的事情来说这是一个很好的解决方案。

但是,我不同意批量装载机的说法,因为它使用起来非常困难。具体来说,因为您需要在每个节点上运行它(而COPY只需要在单个节点上运行)。

为了帮助大型数据集进行COPY缩放,您可以使用PAGETIMEOUTPAGESIZE参数。

COPY invoices(id_invoice, year, id_client, type_invoice) 
  TO 'invoices.csv' WITH PAGETIMEOUT=40 AND PAGESIZE=20;

适当地使用这些参数,我使用COPY成功导出/导入了3.7亿行。

有关详细信息,请查看标题为New options and better performance in cqlsh copy

的文章

答案 2 :(得分:3)

使用COPY命令(请参阅示例的其他答案)或Spark来迁移数据的替代方法是创建物化视图以便为您执行非规范化。

CREATE MATERIALIZED VIEW invoices_yr AS
       SELECT * FROM invoices
       WHERE id_client IS NOT NULL AND type_invoice IS NOT NULL AND id_client IS NOT NULL
       PRIMARY KEY ((type_invoice), year, id_client)
       WITH CLUSTERING ORDER BY (year DESC)

Cassandra会为你填补表格,所以你不必自己迁移。 3.5注意维修不能很好地工作(见CASSANDRA-12888)。