Уникальный генератор ID, объединяющий возможности美团leaf, .baidu UidGenerator, native snowflake
Проект представляет собой генератор uid, поддерживающий четыре стратегии генерации id: segment, snowflake, UidGenerator и spring.
Проект позволяет создавать сложные id, используя в настоящее время стратегию gene (генетический метод).
workId
и datacenterId
.<bean id="snowflakeUidStrategy" class="**.TwitterSnowflakeStrategy"/>
```### 2. Baidu
- Это оптимизированная стратегия, основанная на [Baidu UidGenerator](https://github.com/baidu/uid-generator).
- **(1)** Стратегии предоставления workerId:
- **DisposableWorkerIdAssigner**: использует базу данных для управления генерацией `workerId`, зависит от базы данных и spring-jdbc (необходим bean с jdbcTemplate). Пример для MySQL:
```sql
DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE (
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'автоувеличивающийся id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'имя хоста',
PORT VARCHAR(64) NOT NULL COMMENT 'порт',
TYPE INT NOT NULL COMMENT 'тип узла: ACTUAL или CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'дата запуска',
MODIFIED TIMESTAMP NOT NULL COMMENT 'время изменения',
CREATED TIMESTAMP NOT NULL COMMENT 'время создания',
PRIMARY KEY(ID)
) COMMENT='Управление workerId для UID Генератора', ENGINE = INNODB;
```
Пример конфигурации:
```xml
<bean id="disposableWorker" class="**.DisposableWorkerIdAssigner"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">...</bean>
```
- **SimpleWorkerIdAssigner**: всегда возвращает фиксированное значение `workerId`. Значение равно 0. Пример:
```xml
<bean id="simpleWorker" class="**.SimpleWorkerIdAssigner"/>
```
- **ZkWorkerIdAssigner**: использует Zookeeper для управления генерацией `workerId`, зависит от библиотеки Zookeeper. Пример:
```xml
<bean id="zkWorker" class="**.ZkWorkerIdAssigner"/>
```
Можно настроить интервал heartbeat (`interval`), путь хранения файла workerId (`pidHome`), адрес Zookeeper (`zkAddress`) и порт heartbeat (`pidPort`). - **RedisWorkIdAssigner**: использует Redis для управления процессом генерации `workId`. Этот компонент зависит от `RedisTemplate` из `spring-data-redis`. Пример:
```xml
<bean id="redisWorker" class="**.RedisWorkIdAssigner"/>
```
Можно настроить интервал heartbeat (`interval`), путь хранения файла workerId (`pidHome`) и порт heartbeat (`pidPort`).
### 2. Стратегия генерации uid
#### - **DefaultUidGenerator** представляет собой вариант алгоритма Snowflake, где отсутствует `datacenterId`. Также добавлена поддержка пользовательских значений `workerId` и различных стратегий инициализации.
##### a. Настройка дельты секунд (28 бит)
- Относительное время с момента базовой точки времени "2016-05-20", измеряемое в секундах. Максимальное значение позволяет поддерживать период до примерно 8,7 лет.
##### b. worker id (22 бита)
- Уникальный идентификатор машины, который может поддерживать до 4,19 миллионов уникальных машин. Внутренняя реализация использует базу данных для выделения идентификатора при запуске. По умолчанию используется стратегия "one-time use", но можно выбрать повторное использование.
##### c. sequence (13 бит)
- Конкурентный последовательный номер внутри секунды. 13 бит позволяют поддерживать до 8192 конкурентных запросов в секунду.
###### Примечание: сумма всех трёх компонентов составляет 63 бита.
###### Пример конфигурации:```xml
<bean id="defaultUidGenerator" class="com.myzmds.ecp.core.uid.baidu.impl.DefaultUidGenerator" scope="prototype">
<property name="workerIdAssigner" ref="disposableWorkerIdAssigner"/>
<property name="timeBits" value="29"/>
<property name="workerBits" value="21"/>
<property name="seqBits" value="13"/>
<property name="epochStr" value="2017-12-25"/>
</bean>
```#### - **CachedUidGenerator** решает проблему ограничения конкурентной нагрузки на основе использования кольцевого буфера (`RingBuffer`) для хранения уже сгенерированных UID, что позволяет параллелизовать производство и потребление UID. Также выполняется оптимизация линии кэша, чтобы избежать проблемы псевдо-конкуренции на аппаратном уровне. В результате QPS может достигать 6 миллионов запросов в секунду.
###### Пример конфигурации:```xml
<bean id="cachedUidGenerator" class="com.myzmds.ecp.core.uid.baidu.impl.CachedUidGenerator" scope="prototype">
<property name="workerIdAssigner" ref="disposableWorkerIdAssigner" />
</bean>
<!-- Ниже перечислены опциональные конфигурации, значения которых используются по умолчанию, если они не указаны -->
<!-- RingBuffer размер увеличивающего параметра, повышает пропускную способность генерации UID. -->
<!-- По умолчанию: 3, исходный bufferSize=8192, после увеличения bufferSize= 8192 << 3 = 65536 -->
<!--<property name="boostPower" value="3"></property>-->
<!-- Указывает момент заполнения UID в RingBuffer, принимает значения от 0 до 100, по умолчанию равно 50 -->
<!-- Пример: bufferSize=1024, paddingFactor=50 -> пороговое значение=1024 * 50 / 100 = 512. -->
<!-- Когда количество доступных UID меньше 512, RingBuffer будет автоматически заполняться. -->
<!--<property name="paddingFactor" value="50"></property>-->
<!-- Другой момент заполнения RingBuffer, периодическая проверка в Schedule потоке -->
<!-- По умолчанию: не указано, Schedule поток не используется. При необходимости использования, укажите интервал Schedule потока, единицы измерения: секунды -->
<!--<property name="scheduleInterval" value="60"></property>-->
<!-- Политика отказа: когда буфер полностью заполнен и невозможно продолжить его заполнение -->
<!-- По умолчанию: не требуется указание, операция Put будет отброшена с логированием. При специальных требованиях, реализуйте интерфейс RejectedPutBufferHandler (поддерживает Lambda выражения) -->
<!--<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>-->
<!-- По умолчанию: не требуется указание, будет произведено логирование и выброшено исключение UidGenerateException. При специальных требованиях, реализуйте интерфейс RejectedTakeBufferHandler -->
<!-- <property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property> -->
</bean> (3) Предложения по распределению битов
* Для приложений, где требование к количеству одновременных соединений невелико и ожидают длительной работы, можно увеличить количество ```timeBits```, уменьшив количество ```seqBits```.
Например, если узел использует стратегию WorkerIdAssigner "use and discard", частота перезапусков составляет 12 раз в день,
то конфигурация ```{"workerBits":23,"timeBits":31,"seqBits":9}``` позволит поддерживать работу 28 узлов с совокупной пропускной способностью 14400 UID/с в течение 68 лет.
* Для часто перезапускаемых узлов с длительным сроком использования можно увеличить количество бит ```workerBits``` и ```timeBits```, а также уменьшить количество бит ```seqBits```.
Например, если узел использует стратегию WorkerIdAssigner "one-time use", частота перезапусков составляет 24*12 раз в день,
тогда конфигурация ```{"workerBits":27,"timeBits":30,"seqBits":6}``` обеспечивает работу до 37 узлов с совокупной производительностью 2400 UID/с в течение 34 лет.
3\. Segment
Оптимизированная стратегия, основанная на [leaf-segment](https://tech.meituan.com/MT_Leaf.html) от Meituan, использует двойной буфер. Взаимодействие с базой данных и использование spring-jdbc.
<bean id="leafUidStrategy" class="**.LeafSegmentStrategy"/> (1). SegmentServiceImpl — конкретная реализация, структура таблицы базы данных (пример MySQL):
DROP TABLE IF EXISTS id_segment;
CREATE TABLE id_segment (
BIZ_TAG VARCHAR(64) NOT NULL COMMENT 'Бизнес-идентификатор',
STEP INT NOT NULL COMMENT 'Шаг',
MAX_ID BIGINT NOT NULL COMMENT 'Максимальное значение',
LAST_UPDATE_TIME TIMESTAMP NOT NULL COMMENT 'Дата последнего обновления',
CURRENT_UPDATE_TIME TIMESTAMP NOT NULL COMMENT 'Дата текущего обновления',
PRIMARY KEY(BIZ_TAG)
) COMMENT='Таблица хранения номеров', ENGINE=InnoDB; (2). Поддерживает два способа обновления базы данных: синхронное и асинхронное. Конфигурирование `asynLoadingSegment` (`true` — асинхронное, `false` — синхронное), по умолчанию используется асинхронное.
Пример:
```xml
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">...</bean>
```
4. Инкрементальный ID в Spring
Предоставляет инкрементальную стратегию для Spring на основе стратегии Segment. Это не прямое использование.
5. Алгоритм шифрования
Расширенный алгоритм шифрования, основанный на теории генетического банка
### Использование
-------------------
```xml
<bean class="**.UidContext">
<property name="uidStrategy" ref="любая из вышеперечисленных стратегий" />
<property name="factor" value="опционально: фактор генетики, если установлен, активирует шифрование" />
<property name="fixed" value="опционально: основание для деления, рекомендовано использовать постоянное значение, которое нельзя изменять" />
</bean>
```
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )