2009-10-30 6 views
3

В следующем сценарии:Как создать уникальный ID на кластер веб-серверов

1 База данных 4 Web-серверов

Как веб-серверы генерируют уникальный ID для базы данных, так что они уникальны? Да, можно использовать Auto-increment, но это слишком легко сканировать/догадываться/и т. Д. Таким образом, автоинкремент в настоящее время не является вариантом.

+0

Укажите, что вы хотите решить с помощью своих уникальных идентификаторов. Является ли это системой управления контентом? –

+0

Я не уверен, что еще вы просите ... Идентификатор должен быть уникальным для нескольких серверов J2EE для базы данных бэкэнд. Почему, хотя и важно, на самом деле это не вариант. Это больше, как мы это делаем, будь то система управления контентом, блог, онлайн-система автосервиса, система бронирования и т. Д. –

ответ

15

Используйте UUID (http://www.ietf.org/rfc/rfc4122.txt). Столкновения вряд ли, и могут быть рассмотрены, когда они возникают за счет регенерации новый UUID, или они могут быть предотвращены путем конкатенации уникальный идентификатор для каждого сервера (например, МАС-адрес): -

StringBuilder sb = new StringBuilder(UUID.randomUUID()); 
InetAddress address = InetAddress.getLocalHost(); 
String uid = sb.append(NetworkInterface.getByInetAddress(address).getHardwareAddress()); 
+0

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

+0

@Stephanie: вы уверены в этом? От http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html, безусловно, кажется, что они уникальны. Ваш опыт отличается? – CPerkins

+0

Я слышал, что вероятность столкновения равна 1 в 10^99 ... Я думаю, что ваш сейф. – Zoidberg

3

Вы можете использовать UUID:

import java.util.UUID;   

UUID uuid = UUID.randomUUID(); 
System.out.println(uuid.toString()); 
+0

Правильно, но как вы предотвращаете столкновения? По мере того, как база данных становится более полной и полной, коллизии будут только увеличиваться, и, следовательно, производительность ухудшается ... –

+0

@Stephane: Если вы используете 'randomUUID', то вы вряд ли увидите какие-либо столкновения в течение сотен лет. Просто поставьте уникальное ограничение на свой столбец идентификаторов и обработайте ошибку соответствующим образом, если это когда-либо произойдет. – LukeH

+0

Несмотря на то, что коллизии являются ТЕОРЕТИЧЕСКИ возможными, вероятность даже одного столкновения, возникающего в течение всего срока службы вашего приложения, крайне мала. –

1

Если вы действительно беспокоитесь о столкновениях, вы можете заранее создать ключи и хранить их в таблице базы данных с уникальным индексом. Затем выполняйте периодическое задание, которое заполняет таблицу во время простоя и время от времени удаляет/архивирует используемые ключи.

1

Какая система БД вы используете? Сообщает ли приложение, какой сервер делает запрос? Вы позволяете БД решить ключ или установить его в коде?

Это может быть так же просто, как использовать автоматическое приращение с префиксом или вторым полем, указывающим сервер, который запросил ключ.

1

Я не уверен, почему автоинкремент или последовательность неприемлемы. Вы хотите, чтобы внутренний идентификатор не был «догадан»? Что это такое, это номер учетной записи, и вы не хотите, чтобы кто-то мог угадать действительный номер учетной записи?

Ну, ладно, кроме уже упомянутых UUID, приходят на ум две очевидные возможности.

  1. Используйте последовательность, а затем генерировать случайное число, и создать номер счета из комбинации двух с использованием алгоритма, таким образом, что две различные последовательности чисел, не может дать такой же конечное число. Например, простой алгоритм был бы: Возьмите следующий порядковый номер, умножьте на 12345678, сгенерируйте случайное число от 0 до 12345678-1 и добавьте два вместе.

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

Если у вас есть схема, которая использует идентификатор сервера как часть идентификатора, я призываю вас, чтобы не иметь, что идентификатор быть просто номер, сохраненный в файле конфигурации где-то. Я сейчас работаю над системой, где у кого-то была яркая идея дать каждому серверу «идентификатор сервера», который встроен для записи идентификаторов, а идентификатор сервера - это небольшое целое, которое назначено вручную. Это не слишком сложно в производстве, где есть только 3 сервера. Но в разработке и тестировании, когда новые серверы постоянно растут и опускаются, а тестовые файлы конфигурации постоянно подбрасываются, больно управлять. Я бы не использовал период id сервера, но если вы собираетесь использовать его, сделайте его автоматически назначенным каким-либо центральным сервером или выведите его из IP-адреса или что-то безопасное.

Смежные вопросы