Когда вы действительно вынуждены использовать UUID как часть дизайна? - PullRequest
113 голосов
/ 01 апреля 2009

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

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

UUID пахнет для меня как глобальные переменные. Есть много способов, которыми глобальные переменные делают для более простого проектирования, но это просто ленивый дизайн.

Ответы [ 16 ]

576 голосов
/ 24 апреля 2009

Я написал UUID-генератор / синтаксический анализатор для Ruby, поэтому я считаю себя достаточно хорошо осведомленным в этом вопросе. Существует четыре основных версии UUID:

UUID версии 4 - это всего лишь 16 байтов случайности, извлекаемые из криптографически безопасного генератора случайных чисел, с небольшим изменением бит для идентификации версии и варианта UUID. Это очень маловероятно, чтобы столкнуться, но это может произойти, если используется PRNG или если у вас просто действительно, действительно, действительно, действительно, действительно, очень неудача.

UUID версии 5 и 3 используют хеш-функции SHA1 и MD5 соответственно, чтобы объединить пространство имен с частью уже уникальных данных для генерации UUID. Это, например, позволит вам создать UUID из URL. Столкновения здесь возможны, только если основная хеш-функция также имеет столкновение.

UUID версии 1 являются наиболее распространенными. Они используют MAC-адрес сетевой карты (который, если не был подделан, должен быть уникальным), а также временную метку и обычное переключение битов для генерации UUID. В случае машины, у которой нет MAC-адреса, 6 байтов узла генерируются с помощью криптографически безопасного генератора случайных чисел. Если два UUID генерируются последовательно достаточно быстро, чтобы временная метка соответствовала предыдущему UUID, временная метка увеличивается на 1. Коллизии не должны возникать, если не произойдет одно из следующего: MAC-адрес подделан; Одна машина, на которой работают два разных приложения, генерирующих UUID, генерирует UUID в один и тот же момент; Две машины без сетевой карты или без доступа уровня пользователя к MAC-адресу получают одинаковую последовательность случайных узлов и генерируют идентификаторы UUID в один и тот же момент; У нас заканчиваются байты для представления метки времени и перехода на ноль.

Реально, ни одно из этих событий не происходит случайно в пределах пространства идентификаторов одного приложения. Если вы не принимаете идентификаторы, скажем, в масштабе Интернета или в ненадежной среде, где злоумышленники могут сделать что-то плохое в случае коллизии идентификаторов, вам просто не о чем беспокоиться. Важно понимать, что если вы генерируете тот же UUID версии 4, что и я, в большинстве случаев это не имеет значения. Я сгенерировал идентификатор в совершенно другом пространстве идентификаторов, чем у вас. Мое приложение никогда не узнает о столкновении, поэтому столкновение не имеет значения. Честно говоря, в одном пространстве приложений без злонамеренных акторов вымирание всей жизни на Земле произойдет задолго до того, как вы столкнетесь, даже с UUID версии 4, даже если вы генерируете довольно много UUID в секунду.

Кроме того, 2 ^ 64 * 16 - это 256 эксабайт. Например, вам нужно будет хранить идентификаторы на 256 экзабайт, прежде чем у вас будет 50% вероятность коллизии идентификаторов в одном пространстве приложения.

67 голосов
/ 01 апреля 2009

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

Я читал, что в соответствии с парадоксом дня рождения вероятность возникновения коллизии UUID составляет 50% после генерации 2 ^ 64 UUID. Теперь 2 ^ 64 - это довольно большое число, но вероятность коллизии в 50% кажется слишком рискованной (например, сколько UUID должно существовать, прежде чем вероятность коллизии составит 5% - даже если это кажется слишком большой вероятностью) .

Проблема этого анализа состоит из двух частей:

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

  2. Строго говоря, UUID должны быть уникальными только среди множества других UUID, с которыми они могут сравниваться. Если вы генерируете UUID для использования в качестве ключа базы данных, не имеет значения, используется ли где-то еще в злой альтернативной вселенной тот же UUID, который используется для идентификации интерфейса COM. Также как это не вызовет путаницы, если на Альфа-Центавре есть кто-то (или что-то) по имени «Майкл Берр».

29 голосов
/ 03 апреля 2009

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

16 голосов
/ 01 апреля 2009

Акцент на «разумно» или, как вы говорите, «эффективно»: достаточно хорошо, как работает реальный мир. Объем вычислительной работы, связанной с устранением этого разрыва между «практически уникальным» и «действительно уникальным», огромен. Уникальность - это кривая с убывающей отдачей. В какой-то момент на этой кривой есть грань между тем, что «достаточно уникальное» все еще доступно, и тогда мы ОЧЕНЬ круто искривляемся. Стоимость добавления большей уникальности становится довольно большой. Бесконечная уникальность имеет бесконечную стоимость.

UUID / GUID, условно говоря, является вычислительно быстрым и простым способом генерации идентификатора, который может быть разумно предполагаемым универсально уникальным. Это очень важно во многих системах, которые должны интегрировать данные из ранее не подключенных систем. Например: если у вас есть система управления контентом, которая работает на двух разных платформах, но в какой-то момент необходимо импортировать контент из одной системы в другую. Вы не хотите, чтобы идентификаторы менялись, поэтому ваши ссылки между данными из системы A остаются неизменными, но вы не хотите никаких коллизий с данными, созданными в системе B. UUID решает это.

14 голосов
/ 01 апреля 2009

Никогда не обязательно создавать UUID. Однако удобно иметь стандарт, в котором офлайн пользователи могут каждый генерировать ключ к чему-либо с очень низкой вероятностью столкновения.

Это может помочь в разрешении репликации базы данных и т.д ...

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

В любом случае, слово о вероятности столкновения взято из Википедии:

Чтобы представить эти цифры в перспективе, каждый год рискует быть пораженным По оценкам метеорита, это один шанс из 17 миллиардов, что эквивалентно вероятность создания нескольких десятков триллионов UUID в год и имея один дубликат. Другими словами, только после генерации 1 миллиарда UUID каждую секунду в течение следующих 100 лет, вероятность создания только один дубликат будет около 50%.

12 голосов
/ 01 апреля 2009

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

Вы беспокоитесь об этом?

11 голосов
/ 01 апреля 2009

Классический пример - репликация между двумя базами данных.

DB (A) вставляет запись с int ID 10 и в то же время DB (B) создает запись с ID 10. Это коллизия.

С UUID этого не произойдет, поскольку они не будут совпадать. (почти наверняка)

7 голосов
/ 07 апреля 2010

У меня есть схема, позволяющая избежать UUID. Установите сервер где-нибудь и сделайте так, чтобы каждый раз, когда какой-либо части программного обеспечения требовался универсальный уникальный идентификатор, он связывался с этим сервером, и он раздает его. Простой!

За исключением того, что с этим есть некоторые реальные практические проблемы, даже если мы игнорируем откровенную злобу. В частности, этот сервер может выйти из строя или стать недоступным из части Интернета. Решение проблемы сбоя сервера требует репликации, и это очень трудно , чтобы получить правильные сведения (см. Литературу по алгоритму Paxos, чтобы узнать, почему достижение консенсуса неудобно), и довольно медленно. Более того, если все серверы недоступны из определенной части сети, никто клиентов, подключенных к этой подсети, не сможет ничего сделать, потому что все они будут ждать новых идентификаторов.

Итак ... используйте простой вероятностный алгоритм для их генерации, который вряд ли даст сбой в течение жизни Земли, или (финансируйте и) создайте крупную инфраструктуру, которая будет представлять собой развертывание PITA и будет иметь частые сбои. Я знаю, на какой я пойду.

4 голосов
/ 26 января 2010

Если вы просто посмотрите на альтернативы, например, для простого приложения базы данных, чтобы каждый раз запрашивать базу данных перед созданием нового объекта, вы вскоре обнаружите, что использование UUID может эффективно снизить сложность вашей системы. Конечно, если вы используете int-ключи, то они 32-битные, что будет хранить четверть 128-битного UUID. Конечно, алгоритмы генерации UUID потребляют больше вычислительных ресурсов, чем просто увеличивая число. Но кого это волнует? Затраты на управление «полномочиями» на присвоение уникальных номеров легко перевешивают это на порядки, в зависимости от вашего предполагаемого пространства идентификатора уникальности.

3 голосов
/ 01 апреля 2009

На UUID == Ленивый дизайн

Я не согласен с тем, чтобы выбирать твои бои. Если дубликат UUID статистически невозможен и математика доказана, тогда зачем волноваться? Тратить время на разработку вашей небольшой системы генерации NUUID нецелесообразно, всегда есть дюжина других способов улучшить вашу систему.

...