id生成器雪花算法和雪花算法的sony实现

jiayuqicz 2020-05-05

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,在有些场景下感觉不太够用

我后续可以完善写一个更好的可用的库。

相关推荐