2016-05-07 6 views
0

Довольно новый Кассандре - У меня есть данные, что выглядит следующим образом:Cassandra Схема для стандартного SELECT/FROM/WHERE/IN запроса

<geohash text, category int, payload text>

только запрос я хочу запустить это:

SELECT category, payload FROM table WHERE geohash IN (list of 9 geohashes)

Что было бы лучшей схемой в этом случае?

Я знаю, что могу просто сделать свой geohash первичным ключом и сделать с ним, но есть ли лучший подход?

Каковы преимущества для определения PRIMARY KEY (geohash, category, payload)?

ответ

0

Это зависит от размера ваших данных для каждой строки (текст geohash, категория int, текст полезной нагрузки). Если размер вашей полезной нагрузки не достигнет десятков Мбайт, то вы можете поместить в этот же раздел больше значений geohash с помощью искусственного bucketId int, поэтому ваш запрос может быть выполнен на сервере. Схема будет выглядеть так: geohash text, bucketId int, category int, текст полезной нагрузки где ключ раздела - goehash и bucketId. Рекомендация состоит в том, чтобы иметь значительный раздел < = 100 Мб, поэтому вам не нужно искать слишком много разделов. Доступно еще here.

Если у вас есть первичный ключ (geohash, category, payload), то вы можете иметь ваши данные отсортированы по category and payload в возрастающем порядке.

0

Так на основе запроса, это звучит, как вы рассматриваете CQL схему, которая выглядит следующим образом:

CREATE TABLE geohash_data (
    geohash text, 
    category int, 
    data text, 
    PRIMARY KEY (geohash) 
); 

В Кассандре, первый (и только в этом случае) колонки в вашем PRIMARY KEY является Ключ раздела. Ключ раздела - это то, что используется для распространения данных вокруг кластера. Поэтому, когда вы делаете свой запрос SELECT ... IN(), вы в основном запрашиваете данные в 9 разных разделах, которые в зависимости от того, насколько велик ваш кластер, коэффициент репликации и уровень согласованности, который вы используете для выполнения запроса, могут в конечном итоге запросить наименее 9 серверов (и, возможно, больше). Почему это имеет значение?

  1. Задержка: чем больше разделов (и, следовательно, реплик/серверов), задействованных в нашем запросе, тем больше вероятность того, что медленный сервер сможет отрицательно повлиять на то, как быстро данные будут возвращены.
  2. Доступность: чем больше разделов (и, следовательно, реплик/серверов), участвующих в нашем запросе, тем больше вероятность того, что один сервер будет работать, может сделать невозможным выполнение запроса.

Оба эти плохие сценарии так (как Toan справедливо указывает в своем ответе и ссылку на него в комплекте), мы стараемся модели данных в Кассандре, чтобы наши запросы ударят в несколько разделов (и, следовательно, точные копии/серверов). Что это значит для вашего сценария? Не зная всех деталей, трудно сказать наверняка, но позвольте мне сделать пару догадок о вашем сценарии и дать вам пример того, как я попытаюсь его решить.

Возможно, вы уже знаете список возможных значений geohash заблаговременно (возможно, они находятся на некотором регулярном расстоянии от предопределенной сетки). Это также похоже на то, что вы можете запросить 9 значений geohash, потому что вы делаете какой-то «близостной» поиск, в котором вы пытаетесь получить данные для 9 geohash в каждом направлении вокруг данной точки.

Если это так, фокусом может быть денормализация данных во время записи в модель данных, оптимизированная для чтения. Например, схема, как это:

CREATE TABLE geohash_data (
    geohash text, 
    data_geohash text, 
    category int, 
    data text, 
    PRIMARY KEY (geohash, data_geohash) 
); 

Когда вы INSERT точка данных, вы бы рассчитать geohashes для окружающих районов, где вы ожидаете, что данные должны отображаться в результатах поиска. Тогда вы должны были бы указать INSERT данные несколько раз для каждого рассчитанного вами geohash. Таким образом, значение для geohash - это рассчитанное значение, в котором вы ожидаете, что оно появится в результатах запроса, а значение для data_geohash - это фактическое значение из данных, которые вы вставляете. Таким образом, у вас будет несколько (до 9?) Строк в вашем разделе для заданного geohash, которые представляют данные окружающих геохэшей.

Это значит, что ваш запрос SELECT теперь не должен делать IN и ударять по нескольким разделам. Вы просто запрашиваете WHERE geohash = ? за точку, которую хотите найти.

Смежные вопросы