2016-03-17 3 views
2

Когда я пытаюсь выполнить запрос ниже, я всегда получаю QueryTimeOutException,Cassandra CQL выберите запрос бросками время чтения из исключения всегда

Exception is, 
    com.datastax.driver.core.exceptions.ReadTimeoutException: Cassandra timeout during read query at consistency QUORUM (2 responses were required but only 0 replica responded) 

Query is, 
    SELECT * FROM my_test.my_table WHERE key_1 = 101 ORDER BY key_2 ASC LIMIT 25; 

Я использую Кассандры версии 2.1.0 с 3-мя узлами, Single DC с репликацией 3, cassandra.yaml имеет все значения по умолчанию и у меня возник следующее пространство ключей и таблицу в качестве схемы,

CREATE KEYSPACE my_test 
    WITH REPLICATION = { 
    'class' : 'SimpleStrategy', 
    'replication_factor' : 3 
}; 

CREATE TABLE my_test.my_table (
    key_1 bigint, 
    key_2 bigint, 
    key_3 text, 
    key_4 text, 
    key_5 text, 
    key_6 text, 
    key_7 text, 
    key_8 text, 
    key_9 text, 
    key_10 text, 
    key_11 timestamp, 
    PRIMARY KEY (key_1, key_2) 
); 

в настоящее время таблицы имеет около 39000 записей, но первоначально это 50000 записей, 11000 записей были удалены для некоторые бизнес-логики.

Один из раствора to avoid such exception is to increase query read time out, но моя схема и запрос являются more direct why should I increase my read time out? Так как в моем запросе я дал ключ раздела (key_1), чтобы он точно дошел до адресата, после этого я указал начальный диапазон ключа выделения, Поэтому он должен извлекаться с максимальным временем в 2 секунды, но это не так , Но ниже запрос работает нормально и получены результаты менее чем за 1 сек (Difference is, ASC is not working and DESC is working)

SELECT * FROM my_test.my_table WHERE key_1 = 101 ORDER BY key_2 DESC LIMIT 25; 

Опять же согласно схеме ключ кластера порядок по умолчанию является ASC, поэтому получение данных в ASC должен быть быстрее, чем для того, DESC как за документацию по кассандре. Но в моем случае это наоборот.


Снова некоторые подсказки. Ниже приведены запросы, которые были опробованы через CQLSH.

Следующий запрос работает и извлек результаты менее 1 секунду

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 > 1 AND key_2 < 132645 LIMIT 1; 

Но, следующий запрос не работает и бросает тайм-аут исключения,

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 > 1 AND key_2 < 132646 LIMIT 1; 

Но, следующие запросы работают и извлекают результаты менее 1 секунды

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132644; 
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132645; 
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132646; 
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132647; 

Strange поведение любая помощь будет оценена.

+0

Попробуйте включить трассировку CQLSH и посмотрите, что он вам говорит: https://docs.datastax.com/ru/cql/3.3/cql/cql_reference/tracing_r.html – bechbd

+0

cqlsh> SELECT * FROM my_test.my_table WHERE key_1 = 101 ORDER BY key_2 ASC LIMIT 500; code = 1200 [узел-координатор, приуроченный к ожиданию ответов реплик-узлов] message = «Время ожидания операции - получено только 0 ответов». info = {'received_responses': 0, 'data_retrieved': False, 'required_responses': 1, 'consistency': 1} Задержка отслеживания не завершена в течение 10 секунд –

+0

@bechbd Я предполагаю, что трассировка запроса даст результат, если запрос завершен , –

ответ

1

Вопрос был разрешен after restarting all the 3 cassandra servers. Я не знаю, что, черт возьми, создает проблемы. Поскольку на производственном сервере невозможно получить точный Root Cause.

1

Для каждого ключа_1 будет около 1000000 ключей_2.

И это то, что происходит, когда вы берете 2 миллиарда ячеек на лимит раздела и пытаетесь использовать все это. Я знаю, что я ответил на множество сообщений здесь, признав, что есть жесткий предел в 2 миллиарда ячеек на раздел, ваш (очень) широкий ряд станет неуклюжим и, вероятно, тайм-аут длинный до этого. Это то, что я считаю, что вы видите.

Решение здесь - это метод, называемый «bucketing». В принципе, вам нужно найти дополнительный ключ для разделения ваших данных. Слишком много строк CQL записываются в один и тот же раздел данных, и bucketing поможет вернуть отношение раздела к кластерным ключам обратно на нормальный уровень.

Логический способ использования bucketing - это элемент времени. Я вижу, что ваш последний ключ - это метка времени.Я не знаю, сколько строк каждый key_1 получает в день, но скажем, что вы получаете только несколько тысяч каждый месяц. В этом случае, я хотел бы создать дополнительный ключ секционирования month_bucket:

CREATE TABLE my_test.my_table (
    key_1 bigint, 
    key_2 bigint, 
    ... 
    key_11 timestamp, 
    month_bucket text, 
    PRIMARY KEY ((key_1,month_bucket) key_2) 
); 

Это позволит вам поддерживать запрос, как это:

SELECT * FROM my_test.my_table 
WHERE key_1 = 101 AND month_bucket = '201603' 
    AND key_2 > 1 AND key_2 < 132646 LIMIT 1; 

Опять bucketing на месяц является лишь примером. Но в основном вам нужно найти дополнительный столбец для разделения ваших данных.

+0

Да, конечно, я знаю об этом, но когда эта проблема возникает, таблица имеет только 39000 записей, но изначально она имеет 50000 записей, 11000 записей были удалены для некоторой бизнес-логики. Об этом я упомянул в своем вопросе. Итак, у него 50000 записей с рядом надгробий. Так что это должно оправдать мои ожидания. –

+0

А также аналогичным образом, порядок кластеров по умолчанию - это ASC, поэтому в моем случае ASC должен работать очень быстро, чем DESC (Причина: очень большая широкая строка ...), но в обратном порядке она обратная. Это также я упомянул в своем вопросе. –

+1

@JayaAnanthram «Так что это должно оправдать мои ожидания». И все же это не так. Послушайте, я знаю, что никто не любит, когда ему говорят, что им нужно полностью сдуть и перезагрузить свои данные для изменения модели * после того, как они пошли на производство. Но ваши ряды слишком широки, и на самом деле это не так быстро.Идите вперед и протестируйте обе модели с помощью cassandra-stress, и не только это должно работать, но я уверен, что ваш op/s будет намного выше с «ведром», чем с очень широкой строкой. – Aaron