雪花算法能高性能地生成有序的唯一id,解决一些分布式服务中生成全局唯一id的需求。本章是该github的go实现版。

一:概念

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000

id的结构组成:64位 = 1未使用 + 41 毫秒时间戳 + 5 datacenterid + 5 workerid + 12 毫秒级的计数「每毫秒可以生成4096个id序号」

注:datacenterid的5位也可以直接舍弃掉,分配10个workerid。

二:代码

snowflake.go

package main

import (
	"errors"
	"time"
)

var startStamp int64 = 1588829612000 //当前时间戳

var sequenceBit int64 = 12  // 序列占位数
var machineBit int64 = 5    // 机器id占位数
var dataCenterBit int64 = 5 // 数据中心id占位数

var maxDataCenterNum int64 = -1 ^ (-1 << dataCenterBit) // 数据中心id最大值
var maxMachineNum int64 = -1 ^ (-1 << machineBit)       // 机器id最大值
var maxSequence int64 = -1 ^ (-1 << sequenceBit)        // 序列最大值

var machineLeft = sequenceBit                      // 机器id左移位数
var dataCenterLeft = sequenceBit + machineBit      // 数据中心id左移位数
var timestampLeft = dataCenterBit + dataCenterLeft // 时间戳左移位数

var sequence int64 = 0  // 同一毫秒序列
var lastStmp int64 = -1 // 上一个毫秒戳

type SnowFlake struct {
	dataCenterId, machineId int64
}

/**
获取下个uuid
*/
func (snowFlake SnowFlake) getNextId() (int64, error) {
	var currStmp = getNewstamp()
	if currStmp < lastStmp {
		return 0, errors.New("时间不可倒退,bro")
	}
	if currStmp == lastStmp {
		sequence = (sequence + 1) & maxSequence
		if sequence == 0 {
			currStmp = getNextMill()
		}
	} else {
		sequence = 0
	}

	lastStmp = currStmp
	return (currStmp-startStamp)<<timestampLeft | snowFlake.dataCenterId<<dataCenterLeft | snowFlake.machineId<<machineLeft | sequence, nil

}

/**
获取比当前时间戳更新的时间戳
*/
func getNextMill() int64 {
	var mill = getNewstamp()
	for mill <= lastStmp {
		mill = getNewstamp()
	}
	return mill
}

/**
获取当前毫秒时间戳
*/
func getNewstamp() int64 {
	return time.Now().UnixNano() / 1e6
}

main.go

package main

import (
	"fmt"
	"time"
)

func main() {
	var dataCenterId int64 = 2
	var machineId int64 = 3
	start := time.Now()
	snowFlake := SnowFlake{dataCenterId, machineId}
	for i := 0; i < 1000000; i++ {
		snowFlake.getNextId()
	}
	fmt.Println(time.Since(start))
}

三 :效率

单机上,6c12t,100w数据用了200ms

您或许感兴趣

[2020-01-04]有限状态机-状态表实现

发表评论

电子邮件地址不会被公开。