powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Как сгенерировать int64 ключи для кластеризированной базы данных?
17 сообщений из 17, страница 1 из 1
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754669
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем добрый день!

Разрабатываем большой портал. СУБД: Postgre. Так как предполагаем, что в будущем, возможно, нужно будет кластеризировать данные, хотим предусмотреть это в первичных ключах таблиц базы данных. Кроме того, планируем fail-over переключения на резервный сервер базы данных. И это тоже нужно предусматривать в первичных ключах

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

Потом мы подумали использовать в качестве первичного ключа GUID. Но это 128 бит, и скорость джойнов и поиска по идентификатору будет не такой эффективной, как по int64 в 64битных серверах.

Поэтому сейчас остановились на идее генерировать в базе данных уникальные в пределах портала уникальные идентификаторы формата int64. Чтобы на разных серверах БД они не повторялись.

В связи с этим два вопроса:
1) Действительно ли мы правильно заморачиваемся? Или есть другой, более эффективный способ позволить Postgre работать в кластере и поддерживать работу базы данных в режиме fail-over?
2) Если мы все же правильно заморачиваемся, подскажите, пожалуйста, java-библиотеку, или хотя бы эффективный алгоритм генерации уникальных в рамках всех своих серверов int64 ключей?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754681
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754697
Troglodit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GUID не уникален, поэтому использовать его для первичных ключей не есть гуд, т.к. рискуете нарваться на проблему на ровном месте.
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754701
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grasoff.net http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html#getMostSignificantBits()
А разве это будет уникальное значение в рамках всего моего набора серверов?

TrogloditGUID не уникален, поэтому использовать его для первичных ключей не есть гуд, т.к. рискуете нарваться на проблему на ровном месте.
Что??? С каких это пор GUID не уникален??? И какую альтернативу Вы предлагаете?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754706
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vetal,
мне кажется кластеризация не зависит от первичных ключей.
Иначе где пресловутая горизонтальная масштабируемость?
1C добавляет префикс к ключам в филиалах. Но это не тот подход, который нужно копировать.
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754708
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grasoff.net http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html#getMostSignificantBits()
Посмотрел я, что хранится в старших байтах:
0xFFFFFFFF00000000 time_low
0x00000000FFFF0000 time_mid
0x000000000000F000 version
0x0000000000000FFF time_hi

При этом version - это тип ключа, он для всех одинаков.
А остальное - это текущее время. Чисто теоретически может возникнуть ситуация, что два параллельных сервера сгенерят ключ в одно и то же время. Или в реальной жизни такого не будет?

Может, лучше свой алгоритм, где есть три части? Идентификатор сервера, timestamp и некий sequence number? Возможно, есть готовая библиотека для этого на java?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754978
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
когда-то IBM месяц делал тест - вставки на 100 нодах

ничего не повторилось
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37754979
Kyubee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VetalНо это 128 бит, и скорость джойнов и поиска по идентификатору будет не такой эффективной, как по int64 в 64битных серверах.
А что показывают результаты измерений на реальных базах и запросах?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37755090
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KyubeeVetalНо это 128 бит, и скорость джойнов и поиска по идентификатору будет не такой эффективной, как по int64 в 64битных серверах.
А что показывают результаты измерений на реальных базах и запросах?мне вот тоже интересно
если
Код: sql
1.
2.
3.
4.
create table user (
  guid char(32) not null
);
create unique index user_guid_ix on user using btree (guid);


то что показывают результаты по "скорость джойнов и поиска по идентификатору будет не такой эффективной, как по int64 в 64битных серверах"?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37755094
пролетевший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vetal2) Если мы все же правильно заморачиваемся, подскажите, пожалуйста, java-библиотеку, или хотя бы эффективный алгоритм генерации уникальных в рамках всех своих серверов int64 ключей?
Twitter Snowflake . У них хотя и MySQL, но проблема явно похожая.
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37755450
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lepsikкогда-то IBM месяц делал тест - вставки на 100 нодах
ничего не повторилось
Что именно делал IBM? Тестирование на вставку именно 64битного ключа, который является первой частью стандартного UUID? Или что за тест?

KyubeeVetalНо это 128 бит, и скорость джойнов и поиска по идентификатору будет не такой эффективной, как по int64 в 64битных серверах.
А что показывают результаты измерений на реальных базах и запросах?
Я не знаю, мы, для начала, храним этот идентификатор как char(32). Это даже 256 бит. Как лучше хранить UUID в Postgre - непонятно.
Абсолютно логично, что работа с такими ключами будет на 64битных системах дольше, чем с int64.
Замерять не замеряли. Не видим смысла в этом, и так понятно, что быстрей будет. Или Вы считаете, что все же разница между джойнами и поисками по char(32) и int64 будет непринципиальна?
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37755487
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, Vetal!

> Разрабатываем большой портал. СУБД: Postgre. Так как предполагаем, что в
> будущем, возможно, нужно будет кластеризировать данные, хотим
> предусмотреть это в первичных ключах таблиц базы данных. Кроме того,
> планируем fail-over переключения на резервный сервер базы данных. И это
> тоже нужно предусматривать в первичных ключах
>
> К примеру, если мы сделаем первичные ключи autoincrement, то на разных
> серверах могут возникнуть данные с одним и теми же ключами, что недопустимо.

А если из 64 бит заложить 8 на ID сервера, а остальное- на собственно
ID? Хотя да, есть некоторая некрасивость решения.

> Потом мы подумали использовать в качестве первичного ключа GUID. Но это
> 128 бит, и скорость джойнов и поиска по идентификатору будет не такой
> эффективной, как по int64 в 64битных серверах.

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

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37756102
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вобщем, взял идею из Snowflake, и заимплементил свой генератор.
Выкладываю сюда, мне не жалко:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
/**
 * Generates unique 64-bit ID
 * 
 * Identifier structure:
 * bits 63 (1 bit) - not used (sign bit, after 2108 year identifier will be negative till year 2246. After 2246 year identifier will break)
 * bits 62-20 (43 bits) - time in milliseconds from midnight, January 1, 1970 UTC
 * bits 19-10 (10 bits) - cluster node number. 1024 nodes are supported
 * bits 9 (1 bit) - backward time flag. In case server was time synchronized backward, for running out conflicts, period of time till this timeshift flag will be 1.
 * bits 8-0 (9 bits) - sequence generator. In case more than 1 id requested per same millisecond allows generate up to 512 different id per millisecond. After 512 ids algorithm will wait till next millisecond 
 */
public class IdGenerator {
	
	protected final static int SEQ_NUM_BITS = 9;
	
	protected final static int NODE_NUM_BITS = 10;
	
	protected final static int BACK_TIME_BITS = 1;
	
	protected final static long SEQ_NUM_MAX = 1 << SEQ_NUM_BITS;
	
	protected static int seqNum = 0;
	
	//TODO implement requesting node number on startup. 2 in power of NODE_NUM_BITS nodes supported
	protected static final int nodeNum = 0;
	
	protected static long lastTimestamp = 0;
	
	protected static long backTimeMoment = Long.MAX_VALUE;
	
	/**
	 * Returns next Id. Main method of generator
	 * 
	 * @return
	 */
	synchronized static long nextId(){
		long curTimestamp = System.currentTimeMillis();
		
		// if time was returned backwards, preparing to turning on conflict free flag
		if(curTimestamp < lastTimestamp){
			backTimeMoment = lastTimestamp;
			lastTimestamp = curTimestamp;
		}else{
			if(curTimestamp > backTimeMoment){
				backTimeMoment = Long.MAX_VALUE;
			}
		}

		// if more than 1 identifier was generated per millisecond, increment sequence counter
		if(curTimestamp == lastTimestamp){
			seqNum++;
			
			if(seqNum >= SEQ_NUM_MAX){
				seqNum = 0;
				while(curTimestamp == lastTimestamp)
				{
					curTimestamp = System.currentTimeMillis();
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
					}
				}
				
			}
		}else{
			seqNum = 0;
		}
		
		// remembering last time when identifier was generated
		lastTimestamp = curTimestamp;
		
		// generating identifier with all its components
		return curTimestamp << (SEQ_NUM_BITS + NODE_NUM_BITS + BACK_TIME_BITS) |
				nodeNum << (SEQ_NUM_BITS + BACK_TIME_BITS) | 
				(backTimeMoment != Long.MAX_VALUE ? 1 : 0) << SEQ_NUM_BITS | seqNum;
		
	}
	
}
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37756131
Йуный джавистЪ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроме того, планируем fail-over переключения на резервный сервер базы данных. И это тоже нужно предусматривать в первичных ключах
К примеру, если мы сделаем первичные ключи autoincrement, то на разных серверах могут возникнуть данные с одним и теми же ключами, что недопустимо.

Постгрес же умеет только реплицировать один в один. Поэтому в одной базе не смогут появиться записи из разных баз.
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37756136
Kyubee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vetalхраним этот идентификатор как char(32). Это даже 256 бит. Как лучше хранить UUID в Postgre - непонятно
Не постгресовод, но гоголь подсказывает что guid появился с 8.3
Vetalразница между джойнами и поисками по char(32) и int64 будет непринципиальна?
На микрософте было сравнение int32 и guid, и таки да, непринципиально.
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37756158
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vetal,
мне непонятно:
- вы данный вопрос на форуме СУБД спрашивали? Или хотите обойтись без неё (как всегда) средствами кластеризации Java.
- какие конкретно требования по "сабжу в гарммах"?
авторРечь идёт о миллисекундах. Текущая выборка занимает 150-300 мс нужно сократить до 15 - 30 мс.
Кластер из 10 Atom D2700 vs один i7-2600
ЗЫ.
Если бы кластеры делались через ключи БД (Модель), тут у каждого второго бы они были.
IMHO
...
Рейтинг: 0 / 0
Как сгенерировать int64 ключи для кластеризированной базы данных?
    #37756250
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Vetal, капец. Проблемы на ровном месте.

Создаете на двух узлае сиквенсы с разными стартовыми условиями
и имеете уникальность на ближайшие лет 10-20.

Node1:

Код: plsql
1.
2.
3.
4.
SQL> CREATE SEQUENCE sequence
START WITH 0xFFFFFFFFFFFFFFFF
INCREMENT BY –1
NOCYCLE;



Node2:

Код: plsql
1.
2.
3.
4.
SQL> CREATE SEQUENCE sequence
START WITH 0
INCREMENT BY 1
NOCYCLE;



А после 20 лет ... ну или ишак сдохнет или Султан.

2) По поводу SYSGUID. Алгоритм его генерации - неоднозначен. Разные имплементации
могут учитывать или не учитывать MAC-адрес сетевого интерфейса (кст. какого?)
учитывать или не учитывать дату и т.п.

Так что относитесь к SYSGUID просто как формату 128-битного целого. А алгоритм
генерации - ваш собственный.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Как сгенерировать int64 ключи для кластеризированной базы данных?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]