2016-10-10 8 views
0

Я хочу запросить полный раздел моей таблицы. Мой составной ключ раздела состоит из (id, date, hour_of_timestamp). id и date - это строки, hour_of_timestamp - целое число.Запрос Cassandra - IN или TOKEN для запроса всего раздела?

Мне нужно было добавить поле hour_of_timestamp в мой ключ раздела из-за горячих точек при проглатывании данных.

Теперь мне интересно, какой самый эффективный способ запросить полный раздел моих данных? Согласно this blog, использование SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp IN (0,1,...23); вызывает множество накладных расходов на узле координатора.

Лучше использовать функцию TOKEN и запросить раздел с двумя токенами? Такие, как SELECT * from mytable WHERE TOKEN(id,date,hour_of_timestamp) >= TOKEN('x','10-10-2016',0) AND TOKEN(id,date,hour_of_timestamp) <= TOKEN('x','10-10-2016',23);

Так что мой вопрос: Должен ли я использовать запрос IN или TOKEN для запроса всего раздела моих данных? Или я должен использовать 23 запроса (по одному для каждого значения hour_of_timestamp), и пусть водитель сделает все остальное?

Я использую Cassandra 3.0.8 и последний драйвер Java Datastax для подключения к кластеру из 6 узлов.

+0

Можете ли вы опубликовать все свое определение PRIMARY KEY? – Aaron

+0

@AARON PRIMARY KEY ((log_creator, дата, час), ts, log_id) является фактическим определением. Я скорректировал имена полей в вопросе, чтобы быть более «общим» ... 'ts' имеет тип' timestamp', а 'log_id' - еще одна строка. – j9dy

ответ

1

Вы говорите:

Теперь мне интересно, что это наиболее эффективный способ запроса полного раздела моих данных? Согласно этому блогу, используя SELECT * от mytable WHERE id = 'x' AND date = '10 -10-2016 'AND hour_of_timestamp IN (0,1, ... 23); вызывает много накладных расходов на узле координатора.

, но на самом деле вы запросили бы 24 раздела.

Возможно, вы имели в виду, что у вас был дизайн, в котором один раздел был теперь состоящим из 24 разделов, потому что вы добавляете час, чтобы избежать горячей точки во время приема данных. Отмечая, что в обеих моделях (старом с точками доступа, и этими новыми) данных еще по заказу метки времени, у вас есть два варианта:

  1. Выполнить 1 запрос на время.
  2. Запустите 2 запроса в первый раз, а затем по одному для получения результатов «предварительной выборки».
  3. Выполнение 24 запросов параллельно.

СЛУЧАЙ 1

Если обрабатывать данные последовательно, первый выбор для выполнения запроса в течение часа 0, обрабатывать данные и, когда закончите, запустите запрос в течение часа 1 и так on ... Это простая реализация, и я не думаю, что она заслуживает большего.

СЛУЧАЙ 2

Если запрос занимает больше времени, чем ваша обработка данных, вы можете «предвыборка» некоторые данные. Таким образом, в первый раз вы можете запускать 2 запроса параллельно, чтобы получить данные как часов 0 и 1, так и начать обработку данных за час 0.В то же время поступают данные за час 1, поэтому, когда вы завершаете обработку данных за час 0, вы можете предварительно извлечь данные за час 2 и начать обработку данных за час 1. И так далее .... Таким образом, вы можете ускорить передачу данных обработка. Конечно, в зависимости от ваших таймингов (обработка данных и время запроса) вы должны оптимизировать количество запросов «предварительной выборки».

Также обратите внимание, что драйвер Java выполняет разбиение на страницы для вас автоматически, и в зависимости от размера загруженного раздела вы можете отключить эту функцию, чтобы не блокировать обработку данных, или, возможно, захотите получить дополнительные данные с помощью чего-либо как this:

ResultSet rs = session.execute("your query"); 
for (Row row : rs) { 
    if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched()) 
     rs.fetchMoreResults(); // this is asynchronous 
    // Process the row ... 
} 

где можно настроить, что rs.getAvailableWithoutFetching() == 100 лучше удовлетворить ваши требования предварительной выборки.

Вы также можете предварительно выбрать более одного раздела в первый раз, чтобы вы гарантировали, что ваша обработка не будет ждать какой-либо части, получающей данные.

СЛУЧАЙ 3

Если необходимо обрабатывать данные из различных разделов вместе, к примеру, нужно как данные часа 3 и 6, то вы могли бы попытаться сгруппировать данные по «зависимости» (например, запрос как час 3 и 6 параллельно).

Если вам нужно все из них, то необходимо запустить 24 запроса параллельно, а затем присоединиться к ним на уровне приложений (вы уже знаете, почему вам следует избегать IN для нескольких разделов). Помните, что ваши данные уже заказаны, поэтому ваши усилия на уровне приложений будут очень маленькими.