Intereting Posts
Изменение размера изображений PHP: уникальные посещения / обращения к определенным элементам с помощью файлов cookie / ip Реализация поисковой системы сайта, которая ищет статические страницы Как правильно размещать и вставлять значения в базу данных? Префикс MySQL таблиц или многих баз данных MySQL? Сбросьте все, кроме буквенно-цифровых и европейских символов в PHP Подсчет количества конкретных символов внутри строки Какова цель контроллера в шаблоне MVC с использованием PHP? Как рассчитать PageViews сайта, используя статистику Alexa (формула?) Как вернуть true или false функцию ответа на данные ajax? Проверка подключения к Интернету с помощью командной строки PHP на Linux Эффективный способ получить последнюю часть строки только после определенной базовой строки Если нет вложения, тогда отправьте сообщение, иначе, кнопку загрузки изображения Структура данных MySQL по сравнению с рассчитанными данными для данных типа Checkbox Текст dsiplay от ckeditor

Предлагаемое решение: создание уникальных идентификаторов в распределенной среде

Я просматриваю сеть, пытаясь найти решение, которое позволит нам генерировать уникальные идентификаторы в региональной среде.

Я рассмотрел следующие варианты (среди прочего):

SNOWFLAKE (по щебетать)

  • Это похоже на отличные решения, но мне просто не нравится сложность управления другим программным обеспечением только для создания идентификаторов;
  • На данном этапе у него нет документации, поэтому я не думаю, что это будет хорошая инвестиция;
  • Узлы должны иметь возможность связываться друг с другом с помощью Zookeeper (как насчет задержки / сбоя связи?)

UUID

  • Посмотрите на это: 550e8400-e29b-41d4-a716-446655440000 ;
  • Его 128-битный идентификатор;
  • Были некоторые известные столкновения (в зависимости от версии, я думаю) см. Этот пост .

АВТОИНКРИМЕНТ В ОТНОШЕНИИ БАЗЫ ДАННЫХ, КАК MYSQL

    • Это кажется безопасным, но, к сожалению, мы не используем реляционные базы данных (настройки масштабируемости);
    • Мы могли бы развернуть сервер MySQL для этого, как то, что делает Flickr, но опять же, это вводит еще один пункт отказа / узкого места. Также добавлена ​​сложность.

    АВТОИНКРИМЕНТ В НЕЗАВИСИМОЙ БАЗЕ ДАННЫХ, КАК СОТРУДНИЧЕСТВО

    • Это может работать, поскольку мы используем Couchbase в качестве нашего сервера базы данных, но;
    • Это не сработает, если у нас есть несколько кластеров в разных регионах, проблемы с задержкой, сбои сети: в какой-то момент идентификаторы будут сталкиваться в зависимости от объема трафика;

    МОЕ ПРЕДЛОЖЕННОЕ РЕШЕНИЕ (мне нужна помощь)

    Допустим, что у нас есть кластеры, состоящие из 10 узлов Couchbase и 10 приложений в 5 разных регионах (Африка, Европа, Азия, Америка и Океания). Это делается для обеспечения того, чтобы контент обслуживался из ближайшего к пользователю местоположения (для повышения скорости) и обеспечения избыточности в случае бедствий и т. Д.

    Теперь задача состоит в том, чтобы генерировать идентификаторы, которые не сталкиваются, когда происходит репликация (и балансировка), и я думаю, что это может быть достигнуто за 3 шага:

    Шаг 1

    Всем регионам будут назначены целые идентификаторы (уникальные идентификаторы):

    • 1 – Африка;
    • 2 – Америка;
    • 3 – Азия;
    • 4 – Европа;
    • 5 – Очиания.

    Шаг 2

    Назначьте идентификатор каждому узлу приложения, который добавлен в кластер, имея в виду, что в одном кластере может быть до 99 999 серверов (хотя я сомневаюсь: как безопасная мера предосторожности). Это будет выглядеть примерно так (поддельные IP-адреса):

    • 00001 – 192.187.22.14
    • 00002 – 164,254,58,22
    • 00003 – 142,77,22,45
    • и так далее.

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

    Шаг 3

    Для каждой записи, вставленной в базу данных, для ее идентификации будет использоваться инкрементированный идентификатор, и так оно и будет работать:

    Couchbase предлагает функцию инкремента, которую мы можем использовать для создания идентификаторов внутри кластера. Чтобы обеспечить избыточность, в кластере будут созданы 3 реплики. Поскольку они находятся в одном и том же месте, я думаю, что следует быть уверенным в том, что если весь кластер не работает, один из узлов, ответственных за это, будет доступен, в противном случае количество реплик может быть увеличено.

    Объединяя все это

    Скажем, пользователь подписывается из Европы: узел приложения, обслуживающий запрос, получит код региона (в этом случае 4), получит свой собственный идентификатор (скажем, 00005 ), а затем получит увеличенный идентификатор ( 1 ) из Couchbase (из того же кластер).

    В итоге мы 4, 00005,1 3 компонента: 4, 00005,1 . Теперь, чтобы создать идентификатор из этого, мы можем просто присоединить эти компоненты к 4.00005.1 . Чтобы сделать его еще лучше (я не слишком уверен в этом), мы можем объединить (не добавлять их) компоненты, чтобы в итоге: 4000051 .

    В коде это будет выглядеть примерно так:

    $id = '4'.'00005'.'1';

    NB: Не $id = 4+00005+1; ,

    Pros

    • Идентификаторы выглядят лучше, чем UUID;
    • Они кажутся достаточно уникальными. Даже если узел в другой области сгенерировал один и тот же инкрементированный идентификатор и имеет тот же идентификатор узла, что и тот, который указан выше, мы всегда располагаем региональным кодом для их разделения;
    • Они все еще могут храниться как целые числа (возможно, большие целые числа без знака);
    • Все это часть архитектуры, никаких дополнительных сложностей.

    Cons

    • Нет сортировки (или есть)?
    • Здесь мне нужны ваши данные (большинство)

    Я знаю, что каждое решение имеет недостатки и, возможно, больше того, что мы видим на поверхности. Можете ли вы выявить какие-либо проблемы с помощью всего этого подхода?

    Заранее спасибо за вашу помощь 🙂

    РЕДАКТИРОВАТЬ

    Как предложил @DaveRandom, мы можем добавить 4-й шаг:

    Шаг 4

    Мы можем просто сгенерировать случайное число и добавить его к идентификатору, чтобы предотвратить предсказуемость. Эффективно, вы получите что-то вроде этого:

    4000051357 вместо 4000051 .

    Related of "Предлагаемое решение: создание уникальных идентификаторов в распределенной среде"

    Я думаю, что это выглядит довольно солидно. Каждый регион поддерживает согласованность, и если вы используете XDCR, конфликтов не возникает. INCR является атомарным внутри кластера, поэтому у вас не будет проблем. На самом деле вам не требуется часть машинного кода. Если все серверы приложений в регионе подключены к одному и тому же кластеру, это не имеет значения для инфиниции его части 00001. Если это полезно для вас по другим причинам (какая-то аналитика), то во что бы то ни стало, но это необязательно.

    Таким образом, это может быть просто «4». 1 '(используя ваш пример)

    Можете ли вы привести мне пример того, какая «сортировка» вам нужна?

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

    Например : если идентификаторы от 1 до 100, которые вы узнаете из простого запроса GET на клавише счетчика, вы можете назначать задания по группам, эта задача занимает 1-10, следующие 11-20 и т. Д., А работники может выполняться параллельно. Если вы добавите энтропию, вам нужно будет использовать Map / Reduce View, чтобы вытащить коллекцию, так что вы теряете преимущество шаблона значения ключа.

    Во-вторых : поскольку вы заинтересованы в удобочитаемости, полезно добавить идентификатор типа документа / объекта, и это можно использовать в Map / Reduce Views (или вы можете использовать ключ json для определения этого).

    Пример: 'u:'. '4'. '1'

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

    @ scalabl3

    Вас беспокоят идентификаторы по двум причинам:

    1. Потенциал для коллизий в сложной сетевой инфраструктуре
    2. Внешность

    Начиная со второго выпуска, «Внешний вид». Хотя UUID, конечно же, не очень красив, когда дело доходит до идентификатора, уменьшаются отдачи, поскольку вы вводите поистине уникальный номер в сложном центре обработки данных (или центрах обработки данных), как вы упомянули. Я не уверен, что в восприятии приложения происходит резкое изменение, когда длинный номер по сравнению с UUID используется, например, в URL-адресе веб-приложения. В идеале ни один из них не будет показан, и ID будет только когда-либо отправляться через запросы Ajax и т. Д. Хотя предпочтительный чистый запоминающийся URL-адрес предпочтительнее, он никогда не останавливал меня от покупок на Amazon (где у них есть абсолютно отвратительные URL-адреса). 🙂

    Даже с вашим предложением, идентификаторы, в то время как они будут короче в количестве символов, чем UUID, они не более запоминаются, чем UUID. Таким образом, появление, вероятно, останется спорным.

    Говоря о первом пункте …, да, есть несколько случаев, когда известно, что UUID генерируют конфликты. Хотя это не должно происходить в правильно сконфигурированной и постоянно полученной архитектуре, я могу видеть, как это может произойти (но я лично гораздо меньше обеспокоен этим).

    Итак, если вы говорите об альтернативах, я стал поклонником простоты объекта MongoDB ObjectId и его методов избежания дублирования при создании идентификатора. Полная документация находится здесь . Быстрые релевантные элементы похожи на ваш потенциальный дизайн несколькими способами:

    ObjectId – это 12-байтовый тип BSON, построенный с использованием:

    • 4-байтовое значение, представляющее секунды с эпохи Unix,
    • 3-байтовый идентификатор машины,
    • 2-байтовый идентификатор процесса и
    • 3-байтовый счетчик, начиная со случайного значения.

    Временная метка часто может быть полезна для сортировки. Идентификатор машины похож на ваш сервер приложений, имеющий уникальный идентификатор. Идентификатор процесса – это просто дополнительная энтропия и, наконец, чтобы предотвратить конфликты, есть счетчик, который автоматически увеличивается, когда временная метка такая же, как и в последний раз, когда создается ObjectId (так что ObjectIds могут быть созданы быстро). ObjectId s может быть сгенерирован на клиенте или в базе данных. Кроме того, ObjectIds занимают меньше байтов, чем UUID (но только 4). Конечно, вы не могли использовать временную метку и сбросить 4 байта.

    Для пояснения я не предлагаю использовать MongoDB, но должен быть вдохновлен техникой, которую они используют для генерации идентификатора.

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