Как скопировать данные из таблицы Cassandra в другую структуру для лучшей производительности

В нескольких местах он советовал создавать наши таблицы Cassandra в соответствии с запросами, которые мы будем выполнять на них. В в этой статье DataScale говорится следующее:

Истина заключается в том, что иметь много похожих таблиц с подобными данными - это хорошо в Кассандре. Ограничьте первичный ключ именно тем, с кем будете искать. Если вы планируете искать данные с похожими, но разными критериями, сделайте их отдельной таблицей. Нет недостатка в том, что одни и те же данные хранятся по-разному. Дублирование данных - ваш друг в Кассандре.

[...]

Если вам нужно сохранить один и тот же фрагмент данных в 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:

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

Ответ 1

Повторяя сказанное о команде COPY, это отличное решение для чего-то подобного.

Однако я не согласен с тем, что было сказано о Bulk Loader, поскольку его использование бесконечно сложнее. В частности, потому что вам нужно запустить его на каждом узле (тогда как COPY нужно запускать только на одном узле).

Чтобы помочь масштабировать COPY для больших наборов данных, вы можете использовать параметры PAGETIMEOUT и PAGESIZE.

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

Используя эти параметры соответствующим образом, я использовал COPY для успешного экспорта/импорта 370 миллионов строк.

Для получения дополнительной информации ознакомьтесь с этой статьей: Новые параметры и лучшая производительность в копии cqlsh.

Ответ 2

Вы можете использовать команду 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

Ответ 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)

Кассандра заполнит таблицу для вас, чтобы вам не пришлось мигрировать самостоятельно. Начиная с версии 3.5, следует помнить, что ремонт не работает должным образом (см. CASSANDRA-12888).

Обратите внимание: что материализованные представления, вероятно, не лучшая идея для использования, и было изменено на "экспериментальный" статус