Я просматриваю сеть, пытаясь найти решение, которое позволит нам генерировать уникальные идентификаторы в региональной среде.
Я рассмотрел следующие варианты (среди прочего):
SNOWFLAKE (по щебетать)
- Похоже, что это отличные решения, но мне просто не нравится добавленная сложность управления другим программным обеспечением только для создания идентификаторов;
- На данном этапе у него нет документации, поэтому я не думаю, что это будет хорошая инвестиция;
- Узлы должны иметь возможность связываться друг с другом с помощью Zookeeper (как насчет задержки или сбоя связи?)
UUID
- Просто посмотрите на это: 550e8400-e29b-41d4-a716-446655440000;
- Его 128-битный идентификатор;
- Были некоторые известные столкновения (в зависимости от версии, я думаю) см. этот пост.
АВТОМАТИЧЕСКОЕ ОБЕСПЕЧЕНИЕ В ОТНОШЕНИИ ДАННЫХ, КАК МОЙКАЛ
- Это кажется безопасным, но, к сожалению, мы не используем реляционные базы данных (настройки масштабируемости);
- Мы могли бы развернуть сервер MySQL для этого, как то, что делает Flickr, но опять же это представляет собой еще один пункт отказа/узкого места. Также добавлена сложность.
АВТОИНКРИМЕНТ В НЕЗАВИСИМОЙ БАЗЕ ДАННЫХ, КАК СОТРУДНИЧЕСТВО
- Это может работать, поскольку мы используем Couchbase в качестве нашего сервера базы данных, но
- Это не сработает, если у нас есть несколько кластеров в разных регионах, проблемы с задержкой, сбои сети: в какой-то момент идентификаторы будут сталкиваться в зависимости от объема трафика;
МОЕ ПРЕДЛОЖЕННОЕ РЕШЕНИЕ (мне нужна помощь)
Давайте скажем, что у нас есть кластеры, состоящие из 10 узлов Couchbase и 10 узлов приложения в 5 разных регионах (Африка, Европа, Азия, Америка и Океания). Это делается для обеспечения того, чтобы контент обслуживался из ближайшего к пользователю местоположения (для повышения скорости) и обеспечения избыточности в случае бедствий и т.д.
Теперь задача состоит в том, чтобы генерировать идентификаторы, которые не сталкиваются, когда происходит репликация (и балансировка), и я думаю, что это может быть достигнуто в 3 этапа:
Шаг 1
Всем регионам будут назначены целые идентификаторы (уникальные идентификаторы):
- 1 - Африка;
- 2 - Америка;
- 3 - Азия;
- 4 - Европа;
- 5 - Ociania.
Шаг 2
Назначьте идентификатор для каждого приложения node, которое добавляется в кластер, имея в виду, что в одном кластере может быть до 99 999 серверов (хотя я сомневаюсь: так же, как безопасная мера предосторожности). Это будет выглядеть примерно так (поддельные IP-адреса):
- 00001 - 192.187.22.14
- 00002 - 164.254.58.22
- 00003 - 142.77.22.45
- и т.д.
Обратите внимание, что все они находятся в одном кластере, поэтому вы можете иметь node 00001 для каждого региона.
Шаг 3
Для каждой записи, вставленной в базу данных, для ее идентификации будет использоваться инкрементированный идентификатор, и вот как это будет работать:
Couchbase предлагает функцию увеличения, которую мы можем использовать для создания идентификаторов внутри кластера. Чтобы обеспечить избыточность, в кластере будут созданы 3 реплики. Поскольку они находятся в одном и том же месте, я думаю, что должно быть безопасно предположить, что если весь кластер не будет работать, один из узлов, ответственных за это, будет доступен, в противном случае количество реплик может быть увеличено.
Объединяя все это
Скажите, что пользователь подписывается из Европы: Приложение node, обслуживающее запрос, в этом случае получит код региона (4), получите свой собственный идентификатор (скажем 00005), а затем получите увеличенный идентификатор ( 1) из Couchbase (из одного кластера).
В итоге мы получим 3 компонента: 4, 00005,1
. Теперь, чтобы создать идентификатор из этого, мы можем просто присоединить эти компоненты к 4.00005.1
. Чтобы сделать это еще лучше (я не слишком уверен в этом), мы можем конкатенировать (не добавлять их), чтобы в итоге получилось: 4000051
.
В коде это будет выглядеть примерно так:
$id = '4'.'00005'.'1';
NB: Не $id = 4+00005+1;
.
Pros
- Идентификаторы выглядят лучше, чем UUID;
- Они кажутся достаточно уникальными. Даже если node в другой области сгенерировал один и тот же инкрементный идентификатор и имеет тот же самый идентификатор node, что и выше, мы всегда располагаем региональным кодом для их разделения;
- Они все равно могут быть сохранены как целые числа (возможно, большие целые числа без знака);
- Все это часть архитектуры, никаких дополнительных сложностей.
против
- Нет сортировки (или есть)?
- Здесь мне нужны ваши данные (большинство)
Я знаю, что каждое решение имеет недостатки и, возможно, больше того, что мы видим на поверхности. Можете ли вы выявить любые проблемы с этим целым подходом?
Заранее благодарю вас за помощь: -)
ИЗМЕНИТЬ
Как показано в @DaveRandom, мы можем добавить 4-й шаг:
Шаг 4
Мы можем просто сгенерировать случайное число и добавить его к идентификатору, чтобы предотвратить предсказуемость. Эффективно, вы получите что-то вроде этого:
4000051357
вместо 4000051
.