В односистемной среде мы используем автоинкрементные ID как уникальные идентификаторы данных. Автоинкрементные ID полезны в базах данных для сортировки и индексации, но при использовании их в распределённых системах могут возникнуть конфликты. Кроме того, такие ID легко могут быть сканированы спайдерами.
В распределённых системах также используют UUID как уникальные идентификаторы данных, однако UUID представляет собой случайную последовательность символов, что делает невозможным её сортировку.
Twitter разработал алгоритм Snowflake для генерации ID в распределённых системах. ID Snowflake имеет тип int64
и состоит из следующих частей:
1 бит | 41 бит | 5 бит | 5 бит | 12 бит |
---|---|---|---|---|
Знаковый бит (зарезервированное поле) | Временная метка (текущее время - эпоха времени) | ID центра обработки данных | ID машины | Последовательность инкремента |
git clone https://github.com/GUAIK-ORG/go-snowflake.git
go run main.go
go get github.com/GUAIK-ORG/go-snowflake
// Импортирование модуля в проекте
import "github.com/GUAIK-ORG/go-snowflake/snowflake"
Тестирование на локальной машине:
Параметр | Конфигурация |
---|---|
ОС | MacBook Pro (13-дюймовая модель, 2016 года выпуска, четыре порта Thunderbolt 3) |
Процессор | 2,9 ГГц двухядерный Intel Core i5 |
Оперативная память | 8 ГБ 2133 МГц LPDDR3 |
Тестовый код ```go func TestLoad() { var wg sync.WaitGroup s, err := snowflake.NewSnowflake(int64(0), int64(0)) if err != nil { glog.Error(err) return } var check sync.Map t1 := time.Now() for i := 0; i < 200000; i++ { wg.Add(1) go func() { defer wg.Done() val := s.NextVal() if _, ok := check.Load(val); ok { // проверка конфликта ID glog.Error(fmt.Errorf("ошибка#уникальность: значение:%v", val)) return } check.Store(val, 0) if val == 0 { glog.Error(fmt.Errorf("ошибка")) return } }() } wg.Wait() elapsed := time.Since(t1) glog.Infof("генерация 200k ID заняла время: %v", elapsed) }

## 🗂 Инструкция по использованию
### Создание объекта Snowflake```go
// NewSnowflake(datacenterid, workerid int64) (*Snowflake, error)
// Аргумент 1 (int64): ID центра данных (диапазон допустимых значений: 0-31)
// Аргумент 2 (int64): ID рабочей станции (диапазон допустимых значений: 0-31)
// Возвращаемое значение 1 (*Snowflake): Объект Snowflake | nil
// Возвращаемое значение 2 (error): Код ошибки
s, err := snowflake.NewSnowflake(int64(0), int64(0))
if err != nil {
glog.Error(err)
return
}
s, err := snowflake.NewSnowflake(int64(0), int64(0))
// ......
// (s *Snowflake) NextVal() int64
// Возвращаемое значение 1 (int64): Уникальный ID
id := s.NextVal()
// ......
// ......
// GetDeviceID(sid int64) (datacenterid, workerid int64)
// Аргумент 1 (int64): Уникальный ID
// Возвращаемое значение 1 (int64): ID центра данных
// Возвращаемое значение 2 (int64): ID рабочей станции
datacenterid, workerid := snowflake.GetDeviceID(id)
// ......
// GetTimestamp(sid int64) (timestamp int64)
// Аргумент 1 (int64): Уникальный ID
// Возвращаемое значение 1 (int64): Метка времени от начала эпохи
t := snowflake.GetTimestamp(id)
// ......
// GetGenTimestamp(sid int64) (timestamp int64)
// Аргумент 1 (int64): Уникальный ID
// Возвращаемое значение 1 (int64): Метка времени при создании уникального ID
t := snowflake.GetGenTimestamp(id)
// ......
// GetGenTime(sid int64) (time string)
// Аргумент 1 (int64): Уникальный ID
// Возвращаемое значение 1 (string): Время создания уникального ID
tStr := snowflake.GetGenTime(id)
```### Просмотр использования поля метки времени (диапазон 41 бита: 69 лет после начала эпохи)
```go
// ......
// GetTimestampStatus() (state float64)
// Возвращаемое значение 1 (float64): Процент использования поля метки времени (диапазон: 0.0 - 1.0)
status := snowflake.GetTimestampStatus()
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )