Тайм-аут Cassandra во время запроса на чтение (результат 19 миллионов) при согласованности ONE

У меня есть кластер Cassandra с 2 узлами. И моя структура таблицы <key, Map<list, timestamp>>. Я пытаюсь получить все ключи, содержащие данный список. Мой запрос выглядит так

Statement select = QueryBuilder.select().all().from(tableName).where(QueryBuilder.containsKey("list", value)); select.setFetchSize(50000);

но я получаю тайм-аут cassandra во время запроса на чтение.

Я могу уменьшить setFetchSize, но обработка 19 миллионов строк занимает слишком много времени.

  1. Может ли кто-нибудь предложить правильный способ решения этой проблемы?
  2. есть ли альтернатива для такого рода проблемы?

Версия Кассандры = Кассандра 2.2.1


person visingh    schedule 13.01.2016    source источник
comment
Не могли бы вы опубликовать вывод desc table и что вы пытаетесь получить.   -  person undefined_variable    schedule 13.01.2016
comment
СОЗДАЙТЕ ТАБЛИЦУ теста (идентификатор текста PRIMARY KEY, список карт‹int, временная метка›) С И кэшированием = '{ключи: ВСЕ строки_на_раздел: НЕТ}' И комментарием = '' И уплотнением = {'класс':'org.apache.cassandra .db.compaction.SizeTieredCompactionStrategy'} И сжатие = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} И dclocal_read_repair_chance = 0,1 И default_time_to_live = 0 И gc_grace_seconds = 864000 И max_index_interval = 2048 И memtable_flush И min_index_interval = 128; СОЗДАТЬ ИНДЕКС list_index_test ON test (keys(list));   -  person visingh    schedule 13.01.2016
comment
есть ли способ увеличить read_timeout с помощью java-кода, чтобы я мог увеличить ** setFetchSize ** до 200 тыс. Максимальный размер каждой строки будет 200-250 байт.   -  person visingh    schedule 13.01.2016
comment
setReadTimeoutMillis в классе SocketOption. но вы должны найти реальную причину тайм-аутов. Дает ли тайм-аут для небольшого размера, например 1000?   -  person undefined_variable    schedule 13.01.2016
comment
нет, это не дает исключения тайм-аута для небольшого размера до 20000.   -  person visingh    schedule 14.01.2016


Ответы (1)


Лучшие практики моделирования данных Cassandra рекомендуют не использовать коллекции (список, набор, карту) для хранения большого объема данных. Причина в том, что при загрузке строки CQL (SELECT ... WHERE id=xxx) сервер Cassandra должен загрузить всю коллекцию в память.

Теперь, чтобы ответить на ваши вопросы:

  1. Может ли кто-нибудь предложить правильный способ решения этой проблемы?

Использование вторичного индекса для извлечения огромного набора данных (19 миллионов) — не лучший подход к вашей проблеме.

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

Решение 1. Денормализация вручную

CREATE TABLE base_table(
   id text,
   key int,
   value timestamp,
   PRIMARY KEY(id, key)
);

CREATE TABLE denormalized_table_for_searching(
  key int,
  id text
  value timestamp,
  PRIMARY KEY(key, id));

// Give me all couples (id,value) where key = xxx
// Use iterator to fetch data by page and not load 19 millions row at once !!
SELECT * FROM denormalized_table_for_searching WHERE key=xxx; 

Решение 2: автоматическая денормализация с помощью материализованных представлений Cassandra 3.0

CREATE TABLE base_table(
   id text,
   key int,
   value timestamp,
   PRIMARY KEY(id, key)
);

CREATE MATERIALIZED VIEW denormalized_table_for_searching
AS SELECT * FROM base_table
WHERE id IS NOT NULL AND key IS NOT NULL
PRIMARY KEY(key, id);

// Give me all couples (id,value) where key = xxx
// Use iterator to fetch data by page and not load 19 millions row at once !!
SELECT * FROM denormalized_table_for_searching WHERE key=xxx; 
  1. есть ли альтернатива для такого рода проблемы?

См. ответ для пункта 1. выше :)

person doanduyhai    schedule 13.01.2016
comment
в порядке. Но это увеличит размер таблицы. Предположим, если у меня есть 30 миллионов уникальных идентификаторов (строки), а карта, соответствующая каждой строке, содержит около 2000 пар (ключ, значение). Также размер пары уникальных идентификаторов (строка) и (ключ, значение) постоянно увеличивается. Разделив старую таблицу, новая таблица будет содержать около 30 * 2000 строк. Есть ли проблемы с производительностью с новой таблицей Cassandra? - person visingh; 14.01.2016
comment
Предположим, что если у меня есть 30 миллионов уникальных идентификаторов (строки), а карта, соответствующая каждой строке, содержит около 2000 пар (ключ, значение) --> В итоге у вас будет 30 миллионов разделов, каждый из которых насчитывает 2000 столбцов кластеризации, идеальный вариант использования для Cassandra, потому что ваши 30 миллионов разделов будут равномерно распределены по всем узлам в кластере. Теперь, если вы хотите получить все 30 x 10 ^ 6 * 2000 точек данных для обработки, я бы предложил использовать Apache Spark. Лучше всего подходит для сценариев использования аналитики - person doanduyhai; 14.01.2016