id生成器雪花算法和雪花算法的sony实现
1 雪花算法
首先确定我们的数值是64位,int64类型,被划分为四部分,不含开头的第一个bit,因为这个bit是符号位。用41位来表示收到请求时的时间戳,单位为毫秒,然后五位来表示数据中心的id,然后再五位来表示机器的实例id,最后是12位的循环自增id(到达1111,1111,1111后会归0)。
这样的机制可以支持我们在同一台机器上,同一毫秒内产生2 ^ 12 = 4096
条消息。一秒共409.6万条消息。从值域上来讲完全够用了。但是对微博这样的场景来说,时间戳可能会标识更小的粒度。
2**41 秒的话为69730年,我们标识成毫秒69年, 其实10毫秒就够了。690年。也就是说一豪秒可以产生409万条消息
当然,我们可以使用更长的bit来表示,这个需要考虑业务量了。理论上我们可以实现无线长度的数据,因为只要使用字符串就行。
2 雪花算法的sony实现
2.1 功能描述
39位时间戳,8位序列id,16位机器id
2.2 详细描述
作者自己的描述
// 39 bits for time in units of 10 msec
// 8 bits for a sequence number
// 16 bits for a machine id
每10ms生成一个id,
核心代码
uint64(sf.elapsedTime)<<(BitLenSequence+BitLenMachineID) |
uint64(sf.sequence)<<BitLenMachineID |
uint64(sf.machineID)
每次生成后需要休眠10ms
type Settings struct {
StartTime time.Time//开始时间
//机器id
MachineID func() (uint16, error)
//检测机器id
CheckMachineID func(uint16) bool
}
// Sonyflake is a distributed unique ID generator.
type Sonyflake struct {
//锁
mutex *sync.Mutex
//开始时间
startTime int64
//
elapsedTime int64
//序列号
sequence uint16
//机器id
machineID uint16
}
const sonyflakeTimeUnit = 1e7 // nsec, i.e. 10 msec
2.3 待改进
其实sony的雪花算法要在实际的场合使用,待改进的地方太多了。
1 机器编码问题,使用ipv4
2 生成id太少,每10ms生成256个,1秒大概2.56万个id,在有些场景下感觉不太够用
我后续可以完善写一个更好的可用的库。