Как создать идентификаторы автоинкремента в Кассандре - PullRequest
44 голосов
/ 14 октября 2010

Мы знаем, что легко создавать идентификаторы автоинкремента в базах данных SQL, есть ли хорошее решение для этого в Cassandra? Идентификаторы должны быть для ключа или имени столбца.

Ответы [ 8 ]

33 голосов
/ 01 апреля 2015

Как насчет следующего, используя Легкие транзакции Кассандры

1 - Создать таблицу идентификаторов:

CREATE TABLE ids (
  id_name varchar,
  next_id int,
  PRIMARY KEY (id_name)
)

2 - вставьте каждый идентификатор, который вы хотите использовать в глобальной последовательности с

Например:

INSERT INTO ids (id_name, next_id)
VALUES ('person_id', 1)

3 - Затем при вставке в таблицу, где вы хотите использовать автоинкрементный ключ, выполните следующие действия:

3.1 - Получить next_id из таблицы идентификаторов:

SELECT next_id FROM ids WHERE id_name = 'person_id'

Скажем, результат следующий_ид = 1

3.2 - Увеличивать next_id следующим образом:

UPDATE ids SET next_id = 2 WHERE id_name = 'person_id' IF next_id = 1

Результат должен выглядеть следующим образом:

[{[applied]: True}]

Если оно было успешно обновлено, ИЛИ

[{[applied]: False, next_id: 2}]

Если кто-то уже обновил его.

Итак, если вы получили True, используйте id '1' - он ваш. В противном случае увеличьте значение next_id (или просто используйте возвращенный next_id) и повторите процесс.

33 голосов
/ 21 октября 2010

Создание глобальной последовательной последовательности чисел не имеет никакого смысла в распределенной системе. Используйте UUIDs .

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

15 голосов
/ 21 октября 2010

Хорошего решения не существует.

  1. Создайте столбец с номером, увеличьте число и сохраните его во всех репликах вместе с временным идентификатором, прочитайте все реплики и проверьте, является ли временный идентификатор "вашим", если не сделайте это снова ... не лучшее решение и не будет масштабироваться.

или

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

Как только что-то выходит за пределы одного экземпляра, последовательность id становится сложной, по крайней мере, если вы хотите, чтобы она масштабировалась. Это включает в себя реляционные базы данных.

5 голосов
/ 23 июня 2015

есть тип данных счетчика, который можно использовать.Рассмотрим приведенный ниже пример.

CREATE KEYSPACE counterks WITH REPLICATION =
{ 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 3 };

Создание таблицы для столбца счетчика.

CREATE TABLE counterks.page_view_counts
(counter_value counter,
url_name varchar,
page_name varchar,
PRIMARY KEY (url_name, page_name)
);

Загрузка данных в столбец счетчика.

UPDATE counterks.page_view_counts
SET counter_value = counter_value + 1
WHERE url_name='www.datastax.com' AND page_name='home';

Посмотритепри значении счетчика.

SELECT * FROM counterks.page_view_counts;

Вывод:

 url_name         | page_name | counter_value
------------------+-----------+---------------
 www.datastax.com |      home |             1

Увеличение значения счетчика.

 UPDATE counterks.page_view_counts
 SET counter_value = counter_value + 2
 WHERE url_name='www.datastax.com' AND page_name='home';

Посмотрите на значение счетчика.

 url_name         | page_name | counter_value
------------------+-----------+---------------
www.datastax.com |      home |             3  

См. Это для более подробной информации: http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

3 голосов
/ 11 мая 2013

Этот вопрос довольно старый, но я бы хотел дополнить его другим решением.

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

MySQL way

Вы можете воспроизвести способ репликации мастер-мастер mysql с параметрами auto_increment_increment и auto_increment_offset.

Чтобы воспроизвести его, вам нужно знать количество узлов или максимальное число ожидаемых узлов, а также вам нужно создать (не-кассандровый) счетчик (файл для примера) на каждом узле.

Каждый раз, когда вы хотите сгенерировать новое число, вы находите текущее значение, добавляете приращение и сохраняете его. Если он еще не существует, это смещение.

Таким образом, для 10 узлов вы получите приращение 10 и смещение 1 для первого узла, 2 для второго узла и т. Д. Узел 1 создаст идентификаторы 1, 11, 21. Узел 2 создаст ID 2, 21, 22.

Если вы хотите, чтобы ваши идентификаторы были (приблизительно) упорядочены между узлами, вам необходимо поддерживать общий счетчик и убедиться, что каждый сгенерированный идентификатор выше, чем общий счетчик. Таким образом, если ваши узлы / центры обработки данных не синхронизированы в течение длительного времени, вы не заметите большой разницы.

Префикс

В принципе, вы можете сделать то же самое, поставив перед идентификатором (если это приемлемое решение) номер узла (или имя). И вам не нужно знать количество узлов. Узел 1 будет создавать 1_1, 1_2, 1_3. Узел 2 создаст 2_1, 2_2, 2_3.

2 голосов
/ 08 июня 2017

Я думаю, ИМХО, ожидая, что Cassandra предоставит поле с автоинкрементом, НЕПРАВИЛЬНО

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

Следовательно, не принимайте решение, на какой базе данных получить автоматически увеличивающееся число

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

2 голосов
/ 30 марта 2015

Редактировать: Это решение не является правильным. Смотрите первый комментарий.

Мое решение:

1 - Создать таблицу идентификаторов:

CREATE TABLE ids (
  id_name varchar,
  next_id counter,
  PRIMARY KEY (id_name)
)

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

2.1 - Счетчик приращений (он будет создан, если не существует), используя самый высокий уровень согласованности

UPDATE ids
  SET next_id = next_id + 1
  WHERE id_name = $AUTO_INCREMENTED_ID
  USING CONSISTENCY ALL

2.2 - Получить новое значение идентификатора:

SELECT next_id
  FROM ids
  WHERE id_name = $AUTO_INCREMENTED_ID

2.3 - вставить значение с автоматически увеличивающимся идентификатором

INSERT INTO some_table ($AUTO_INCREMENTED_ID, ...)
  VALUES ($RESULT_FROM_PREVIOUS_QUERY, ...)

Слова, начинающиеся с '$' в моем ответе, говорят сами за себя (я надеюсь) заполнители ...

Конечно, это не рекомендуемый метод. Используйте его, только если вам нужно.

1 голос
/ 18 февраля 2015

Они действительно должны быть последовательными, или вам просто нужно подсчитать числа, которые намного меньше, чем UUID, который легко вводится человеком?

Если вам действительно нужен последовательныйчисел, то вам нужно будет выполнить одно из следующих действий:

  • Иметь таблицу в Кассандре, где ключ / id - это поле для генератора, а значение - это число.. делать условные обновления в цикле, пока вы не увеличите счет успешно.(плохая идея)

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

В качестве альтернативы ... Аналогично первому, но получают партиипо 100 или около того чисел за раз, и распределите их внутри вашего процесса / потока ... Это будет иметь меньше разногласий, но не будет гарантировать последовательный порядок, только уникальность ... Если вам нужны только более короткие числа, уникальные для отображения, это может быть вашим лучшим выбором.

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