Проблема с пейджинговым механизмом Cassandra TOKEN - PullRequest
1 голос
/ 08 июля 2019

В нашем наборе данных много повторяющихся ключей разделов.Мы используем метод TOKEN для разбивки данных на страницы.Если строки с дублирующимися ключами разбиты по странице, мы не получим остаток дубликатов при следующем вызове.

Например, предположим, что у нас есть следующие ключи: 1 2 3 5 5 5 6 78 и у нас есть ограничение в 5 строк на запрос.Первый запрос " select * from table, где TOKEN (id)> TOKEN ('') limit 5; " возвращает 1 2 3 5 5, как и ожидалось.Второй запрос " select * from table, где TOKEN (id)> TOKEN ('5') limit 5; " возвращает 6 7 8. Это не желаемое поведение, мы хотим, чтобы второй запрос возвратил 56 7 8. Размышляя об этом, становится очевидным, почему это происходит: « (TOKEN (id)> TOKEN ('5') » завершается неудачей, если id == 5

Мы делаемчто-то не так или это так, как он работает? Мы используем последнюю версию драйвера Java, но я не думаю, что это проблема с драйвером, поскольку драйвер Golang также демонстрирует такое поведение

У нас (в основном)Обойти эту проблему можно, либо удалив все дублированные записи в конце набора строк (в примере 5 5), либо сбросив последнюю запись (чтобы охватить случай, когда последняя запись дублируется во втором наборе записей).если набор записей - все дубликаты. Очевидно, что более высокие ограничения уменьшают этот крайний случай, но это не кажется безопасным для использования в производственной среде.

* РЕДАКТИРОВАНИЕ *

Метод TOKEN рекомендуется во многих случаях.f страницы как здесь, в Stackoverflow, так и в других местах в Интернете.Но, очевидно, это не сработает: - (

@ alex:

Спасибо за ваш ответ. Это был просто упрощенный пример проблемы. На самом деле у нас 30 миллионов строки используем предел в 1000. Когда таблица была впервые разработана несколько лет назад, разработчик не понимал, как работает ключ раздела, поэтому он использовал идентификатор пользователя в качестве раздела, что дает нам 30 миллионов разделов. Мы считаем, что это по крайней мереЭто позволяет нам сократить время восстановления (в настоящее время для кластера 12 часов). Чтобы решить проблему с ключом раздела, нам нужно скопировать всю таблицу в новую с другим ключом раздела (в рабочей среде). Эта страница https://docs.datastax.com/en/developer/java-driver/2.1/manual/paging/ кажется лучшим решением.

@ Nadav:

Спасибо за ваш ответ. Простое удаление ограничения приведет к превышению времени ожидания запроса в нескольких слоях нашего программного обеспечения.Страница DataStax, представленная выше, кажется нам лучшим решением.

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Вы не должны и не можете использовать диапазоны токенов и LIMIT для пролистывания результатов, и вы сами поняли, что это не работает - потому что LIMIT обрезает некоторые результаты, и у вас нет возможностипродолжить.

Вместо этого Cassandra предоставляет вам отдельную функцию подкачки : вы делаете запрос, получаете первые 1000 (или что угодно) строк и также «cookie»с помощью которого вы можете возобновить запрос, чтобы получить следующую страницу результатов.Пожалуйста, обратитесь к документации вашего любимого драйвера о синтаксисе использования Cassandra paging на вашем любимом языке.Это не «LIMIT» - это отдельная функция.

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

1 голос
/ 08 июля 2019

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

В вашем случае размер страницы не соответствует размеру набора результатов - у вас есть 6 результатов, а следующий набор результатов (для token(id) > token(5)) имеет только 3 строки.Я не знаю решения, которое работает «из коробки» (кроме select * from table, но оно может прерваться в случае, если у вас много данных).В вашем случае я бы лучше использовал более широкие диапазоны (например, весь диапазон токенов) и результаты страницы внутри него (без использования limit), а затем обработал случай, когда вам нужно переключиться на следующий диапазон токенов, и выу меня есть несколько строк, оставшихся от предыдущего диапазона токенов.

У меня есть пример кода Java , который выполняет эффективное сканирование всех диапазонов токенов, аналогично тому, что делает соединитель Spark.Основной трюк заключается в том, чтобы направить запрос к узлу, который содержит данные, поэтому он будет считывать данные непосредственно с самого узла, без необходимости достигать других узлов (если вы, конечно, читаете с LOCAL_ONE).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...