Snowflake ialah algoritma penjanaan ID teragih yang bersumberkan terbuka oleh Twitter Ia menggunakan kaedah berikut untuk menjana ID unik secara global:
Dalam artikel ini, kami akan memperkenalkan cara melaksanakan Snowflake di Golang.
Pertama, kita perlu menentukan struktur untuk menyimpan data dalam algoritma Snowflake, termasuk ID mesin, nombor siri dan cap waktu ID yang dijana terakhir dan maklumat lain.
const ( workerIdBits = 10 // 机器ID位数 sequenceBits = 12 // 序列号位数 workerIdMax = -1 ^ (-1 << workerIdBits) // 最大机器ID sequenceMask = -1 ^ (-1 << sequenceBits) // 序列号掩码 timeShiftBits = workerIdBits + sequenceBits // 时间戳左移位数 workerIdShift = sequenceBits // 机器ID左移位数 ) type Snowflake struct { lastTimestamp uint64 workerId uint16 sequence uint16 }
Antaranya, kami menggunakan pemalar untuk mewakili bilangan digit setiap data, nilai maksimum, topeng dan maklumat lain untuk memudahkan pengiraan seterusnya.
Seterusnya, kita perlu melaksanakan kaedah untuk menjana ID unik di peringkat global. Proses khusus adalah seperti berikut:
Pelaksanaan khusus adalah seperti berikut:
func (s *Snowflake) NextId() uint64 { var currTimestamp = uint64(time.Now().UnixNano() / 1e6) if currTimestamp < s.lastTimestamp { panic("Invalid timestamp") } if currTimestamp == s.lastTimestamp { s.sequence = (s.sequence + 1) & sequenceMask if s.sequence == 0 { currTimestamp = s.waitNextMillis(currTimestamp) } } else { s.sequence = 0 } s.lastTimestamp = currTimestamp return ((currTimestamp - 1483228800000) << timeShiftBits) | (uint64(s.workerId) << workerIdShift) | uint64(s.sequence) } func (s *Snowflake) waitNextMillis(currTimestamp uint64) uint64 { for currTimestamp <= s.lastTimestamp { currTimestamp = uint64(time.Now().UnixNano() / 1e6) } return currTimestamp }
Dalam pelaksanaan, kami menggunakan cap waktu UNIX untuk mewakili masa, tetapi sejak masa algoritma Snowflake menjana ID bermula pada 2017 , Kita perlu menolak nilai offset tetap (1483228800000) daripada cap masa.
Akhir sekali, kita perlu memulakan objek Snowflake dan nyatakan ID mesin. ID mesin mestilah integer antara 0 dan 1023, dan ID mesin yang berbeza dijamin berbeza.
func New(workerId int) *Snowflake { if workerId < 0 || workerId > workerIdMax { panic(fmt.Sprintf("Invalid worker ID, must be in [%d, %d]", 0, workerIdMax)) } return &Snowflake{ lastTimestamp: 0, workerId: uint16(workerId), sequence: 0, } }
Dalam pelaksanaan di atas, kami menggunakan fungsi cap waktu dan pengendali binari di Golang untuk memastikan keunikan dan kesinambungan ID, dan nombor urutan tertib rendah memastikan aliran ID meningkat. Memandangkan cap masa adalah tepat pada tahap milisaat, algoritma Snowflake boleh menjana ID yang mencukupi untuk mengelakkan konflik ID dalam senario konkurensi tinggi.
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan algoritma Snowflake di Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!