雪花算法是一种分布式全局唯一ID,一般不需要过多的深入了解,一般个人项目用不到分布式之类的大型架构,另一方面,则是因为,就算用到市面上很多 ID 生成器帮我们完成了这项工作。
很多教程已经介绍的很清楚了,简而言之,雪花算法(Snowflake)就如它的名字一样,即“世界上没有任何两片雪花是一样的。”
雪花算法的使用场景就很明确了,用于确保全局唯一的id。还有一个从名字无法看出的特点就是,还能保证id的自增属性。
以下是抄的千篇一律的雪花算法介绍,帮助记忆下。
Snowflake 以 64 bit 来存储组成 ID 的4 个部分:
1、最高位占1 bit,值固定为 0,以保证生成的 ID 为正数;
2、中位占 41 bit,值为毫秒级时间戳;
3、中下位占 10 bit,值为工作机器的 ID,值的上限为 1024;
4、末位占 12 bit,值为当前毫秒内生成的不同 ID,值的上限为 4096;
也参考了另一篇文章的说法,将中下位代表机器id分为两部分,一部分代表机房,一部分代表机房机器号,虽然我们没有机房,当时也可以用此区分不同业务。
代码实现
百度看到很多人写的代码都很长,看着头疼。知道原理,那么就用代码写个看起来没那么复杂的版本吧。
import time
class Snow:
"""雪花算法生成全局自增唯一id"""
init_date = time.strptime('2020-01-01 00:00:00', "%Y-%m-%d %H:%M:%S")
start = int(time.mktime(init_date) * 1000)
last = int(time.time() * 1000)
pc_room = 1
pc = 1
seq = 0
@classmethod
def get_guid(cls):
"""获取雪花算法生成的id"""
now = int(time.time() * 1000)
if now != cls.last:
cls.last = now
cls.seq = 1
else:
while cls.seq >= 4096:
time.sleep(0.1)
return cls.get_guid()
cls.seq += 1
time_diff = now - cls.start
pk = (time_diff << 22) ^ (cls.pc_room << 18) ^ (cls.pc << 12) ^ cls.seq
return pk
里面的一些配置是应该写到项目的配置文件里去引用的,具体还是根据实际情况进行选择吧。
也看到有人说研究出比雪花算法性能更好的生成全局唯一id的算法,仔细一看,不过是把41bit的时间戳变成47bit了,压缩了后面的位数,其实核心思想是一样的。