Время ожидания Cassandra во время запроса на чтение при согласованности один (1 ответы были необходимы, но ответили только 0 реплик)

я делаю запросы на чтение и обновление таблицы, имеющей 500000 строк, и несколько раз получаю ниже ошибки после обработки около 300000 строк, даже если узел не выключен.

время ожидания Cassandra во время запроса чтения при согласованности один (1 ответы были необходимы, но ответили только 0 реплик)

инфраструктуру детали:
Имея 5 узлов Cassandra, 5 spark и 3 узла Hadoop каждый с 8 ядрами и 28 ГБ памяти и Кассандра!--9-->фактор репликации и 3.

Кассандра 2.1.8.621 | DSE 4.7.1 | Spark 1.2.1 / Hadoop 2.7.1.

настройки Кассандра:

read_request_timeout_in_ms (ms): 10000
range_request_timeout_in_ms (ms): 10000
write_request_timeout_in_ms (ms): 5000
cas_contention_timeout_in_ms (ms): 1000 
truncate_request_timeout_in_ms (ms): 60000
request_timeout_in_ms (ms): 10000.

Я пробовал ту же работу, увеличивая read_request_timeout_in_ms (ms) до 20,000, но это не помогло.

я делаю запросы на двух столах. Ниже create для одной из таблиц:

создать Таблица:

CREATE TABLE section_ks.testproblem_section (
    problem_uuid text PRIMARY KEY,
    documentation_date timestamp,
    mapped_code_system text,
    mapped_problem_code text,
    mapped_problem_text text,
    mapped_problem_type_code text,
    mapped_problem_type_text text,
    negation_ind text,
    patient_id text,
    practice_uid text,
    problem_category text,
    problem_code text,
    problem_comment text,
    problem_health_status_code text,
    problem_health_status_text text,
    problem_onset_date timestamp,
    problem_resolution_date timestamp,
    problem_status_code text,
    problem_status_text text,
    problem_text text,
    problem_type_code text,
    problem_type_text text,
    target_site_code text,
    target_site_text text
    ) WITH bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'class': 
    'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
    AND compression = {'sstable_compression': 
    'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

запросы :

1) SELECT encounter_uuid, encounter_start_date FROM section_ks.encounters WHERE patient_id = '1234' AND encounter_start_date >= '" + formatted_documentation_date + "' ALLOW FILTERING;

2) UPDATE section_ks.encounters SET testproblem_uuid_set = testproblem_uuid_set + {'1256'} WHERE encounter_uuid = 'abcd345';

2 ответов


обычно, когда вы получаете ошибку тайм-аута, это означает, что вы пытаетесь сделать что-то, что не масштабируется хорошо в Cassandra. Исправление часто заключается в изменении схемы.

Я предлагаю вам следить за узлами во время выполнения запроса, чтобы узнать, можете ли вы определить проблемную область. Например, вы можете запустить "watch-n 1 nodetool tpstats", чтобы увидеть, если какие-либо очереди резервного копирования или удаления элементов. См. другие предложения по мониторингу здесь.

одна вещь, которая может быть в ваша конфигурация заключается в том, что вы говорите, что у вас есть пять узлов Cassandra, но только 3 рабочих искры (или вы говорите, что у вас есть три рабочих искры на каждом узле Cassandra?) Вам понадобится по крайней мере один работник spark на каждом узле Cassandra, чтобы загрузка данных в spark выполнялась локально на каждом узле, а не по сети.

трудно сказать больше, не видя вашу схему и запрос выполняется. Вы читаете из одного раздела? Я начал получать тайм-аут ошибки около 300 000 строк при чтении из одной секции. См. вопрос здесь. Единственное решение, которое я нашел до сих пор, - использовать хэш на стороне клиента в моем ключе раздела, чтобы разбить разделы на меньшие куски около 100K строк. До сих пор я не нашел способ сказать Кассандре, чтобы не тайм-аут для запроса, который я ожидаю, займет много времени.


не думайте, что конфигурация является основной причиной, но проблема модели данных.

было бы здорово увидеть структуру section_ks.встречи таблица.

предложил тщательно подумать о том, какие конкретные запросы, как ожидается, будут выполняться перед структурой таблицы(таблиц) проектирования.

насколько я вижу, эти два запроса ожидают разной структуры section_ks.встречи для запуска их с хорошей производительностью.

давайте рассмотрим каждый предоставленный запрос и попробуйте спроектировать таблицы:

первый:

выберите encounter_uuid, encounter_start_date от section_ks.встречи Где patient_id = '1234' и encounter_start_date >= '" + formatted_documentation_date + "' разрешить фильтрацию;

  • первая точка, если Кассандра заставляет вас добавить разрешить фильтрацию, это symhtome неоптимальной структуры запроса или таблицы.
  • второй момент. Первичный ключ. Удивительное объяснение о что такое первичные ключи в Cassandra данный запрос будет работать быстро и без обязательного разрешения оператора фильтрации, если patient_id и encounter_start_date образуют составной первичный ключ. перечисление столбцов внутри оператора PRIMARY KEY () должно соответствовать порядку фильтрации в вашем запросе.
  • почему разрешена обязательная фильтрация в исходном запросе? По разделу ключ Cassandra знает, на каком узле расположены данные. В случае, когда patient_id столбец не является ключом раздела, Кассандре пришлось сканировать все 5 узлов для поиска запрошенного пациента. Когда у нас много данных на узлах, такое полное сканирование обычно завершается с ошибкой по таймауту.

вот пример структуры таблицы эффективно подходит для данного запроса:

create table section_ks.encounters(
    patient_id bigint, 
    encounter_start_date timestamp, 
    encounter_uuid text,
    some_other_non_unique_column text,
    PRIMARY KEY (patient_id, encounter_start_date)
);
  • patient_id столбец будет "ключом раздела". Ответственный за распространение данных через узлы Кассандры. Простыми словами (опуская функцию репликации): различные диапазоны пациентов будут храниться на разных узлах.
  • encounter_start_date столбец будет "ключом кластеризации", ответственным за сортировку данных внутри раздела.

разрешить фильтрацию теперь можно удалить из запроса:

SELECT encounter_uuid, encounter_start_date 
FROM section_ks.encounters 
WHERE patient_id = '1234' AND encounter_start_date >= '2017-08-19';

второй запрос:

обновить section_ks.встречи набор testproblem_uuid_set = testproblem_uuid_set + {'1256'} где encounter_uuid = 'abcd345';

структура таблицы должна выглядеть примерно так:

create table section_ks.encounters(
    encounter_uuid text, -- partition key
    patient_id bigint,
    testproblem_uuid_set text, 
    some_other_non_unique_column text,
    PRIMARY KEY (encounter_uuid)
);

Если мы определенно хотели бы сделать быструю фильтрацию только encounter_uuid, он должен быть определен как ключ раздела.

хорошие статьи о разработке эффективных данных модель: