雪花算法是在一个项目体系中生成全局唯一ID标识的一种方式,偶然间看到了Python使用雪花算法不尽感叹真的是太便捷了。它生成的唯一ID的规则也是通过常用的时间戳来统计的,但是计算方式却更为精准。除此之...
雪花算法是在一个项目体系中生成全局唯一ID标识的一种方式,偶然间看到了python使用雪花算法不尽感叹真的是太便捷了。
它生成的唯一ID的规则也是通过常用的时间戳来统计的,但是计算方式却更为精准。除此之外,再配合上不同机器属性分布式的使用就可以使生成的ID在整个单击或是分布式项目保持唯一性。
雪花算法通过时间规则,以二进制的方式将进行时间戳以及机器属性等信息的填充,所以生成后的唯一ID是按照时间递增的规律来排列的。为了形成对比,下面先看看在Java开发中的雪花算法是如何生成唯一ID的。
packageutils;
publicclassSnowflake{
/**开始时间截(2015-01-01)*/
privatefinallongtwepoch=1420041600000L;
/**机器id所占的位数*/
privatefinallongworkerIdBits=5L;
/**数据标识id所占的位数*/
privatefinallongdatacenterIdBits=5L;
/**支持的最大机器id,结果是31(这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)*/
privatefinallongmaxWorkerId=-1L^(-1L<<workerIdBits);
/**支持的最大数据标识id,结果是31*/
privatefinallongmaxDatacenterId=-1L^(-1L<<datacenterIdBits);
/**序列在id中占的位数*/
privatefinallongsequenceBits=12L;
/**机器ID向左移12位*/
privatefinallongworkerIdShift=sequenceBits;
/**数据标识id向左移17位(12+5)*/
privatefinallongdatacenterIdShift=sequenceBits+workerIdBits;
/**时间截向左移22位(5+5+12)*/
privatefinallongtimestampLeftShift=sequenceBits+workerIdBits+datacenterIdBits;
/**生成序列的掩码,这里为4095(0b111111111111=0xfff=4095)*/
privatefinallongsequenceMask=-1L^(-1L<<sequenceBits);
/**工作机器ID(0~31)*/
privatelongworkerId;
/**数据中心ID(0~31)*/
privatelongdatacenterId;
/**毫秒内序列(0~4095)*/
privatelongsequence=0L;
/**上次生成ID的时间截*/
privatelonglastTimestamp=-1L;
publicSnowflake(longworkerId,longdatacenterId){
if(workerId>maxWorkerId||workerId<0){
thrownewIllegalArgumentException(String.format("workerIdcan'tbegreaterthan%dorlessthan0",maxWorkerId));
}
if(datacenterId>maxDatacenterId||datacenterId<0){
thrownewIllegalArgumentException(String.format("datacenterIdcan'tbegreaterthan%dorlessthan0",maxDatacenterId));
}
this.workerId=workerId;
this.datacenterId=datacenterId;
}
publicsynchronizedlongnextId(){
longtimestamp=timeGen();
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
if(timestamp<lastTimestamp){
thrownewRuntimeException(
String.format("Clockmovedbackwards.Refusingtogenerateidfor%dmilliseconds",lastTimestamp-timestamp));
}
//如果是同一时间生成的,则进行毫秒内序列
if(lastTimestamp==timestamp){
sequence=(sequence+1)&sequenceMask;
//毫秒内序列溢出
if(sequence==0){
//阻塞到下一个毫秒,获得新的时间戳
timestamp=tilNextMillis(lastTimestamp);
}
}
//时间戳改变,毫秒内序列重置
else{
sequence=0L;
}
//上次生成ID的时间截
lastTimestamp=timestamp;
//移位并通过或运算拼到一起组成64位的ID
return((timestamp-twepoch)<<timestampLeftShift)//
|(datacenterId<<datacenterIdShift)//
|(workerId<<workerIdShift)//
|sequence;
}
protectedlongtilNextMillis(longlastTimestamp){
longtimestamp=timeGen();
while(timestamp<=lastTimestamp){
timestamp=timeGen();
}
returntimestamp;
}
protectedlongtimeGen(){
returnSystem.currentTimeMillis();
}
publicstaticvoidmain(String[]args){
Snowflakeidworker=newSnowflake(0,0);
for(inti=0;i<100;i++){
longid=idWorker.nextId();
System.out.println(Long.toBinaryString(id));
System.out.println(id);
}
}
}
通过上述的Java代码块就能生成100个唯一的ID,并且在Java代码块中定义生成ID时各种属性信息,大概有100行代码左右,我截取了生成唯一ID的部分结果来展示。
111001000000000011001001011001011010110000000000000000010111
1026834554947633175
111001000000000011001001011001011010110000000000000000011000
1026834554947633176
111001000000000011001001011001011011000000000000000000000000
1026834554951827456
111001000000000011001001011001011011000000000000000000000001
1026834554951827457
这样的代码块可能使用C++的方式实现的话过程可能更为复杂,相比之下Python开发的话比较简单,因为大佬们已经将一些复杂的东西都写好了,我们经常只需要直接调用即可,这里说明一下不同编程语言都是我们做业务的一种工具,都有自己诞生的使命。
接下来,我们使用python调用第三方模块的方式来实现雪花算法,具体使用python实现雪花算法生成唯一ID的思路肯定和Java也是相似的。
在python中,大佬们已经封装了pysnowflake的python非标准库,这也是python之所以方便的原因,通过pip的方式将其安装完成就能大显身手了。
pipinstallpysnowflake-ihttps://pypi.tuna.tsinghua.edu.cn/simple/
安装完成之后需要启动雪花算法生成唯一ID的服务,并且可以定义工作的数量,这里我们将工作数量定义为1启动服务。

将snowflake.client导入到代码块中,相当于我们作为客户端去访问服务端就会直接生成唯一ID。
#Importhttp://www.cppcns.comingthe`snowflake.client`module. importsnowflake.client #Callingthe`get_guid()`functionfromthe`snowflake.client`module. uuid=snowflake.client.get_guid() #Printingthevalueofthe`uuid`variable. print(uuid) #Printingthebinaryrepresentationofthe`uuid`variable. print(bin(uuid)) #4674877370191056897 #0b100000011100000100000000011001100011010110000000001000000000001
到此这篇关于Python利用雪花算法实现生成唯一ID的文章就介绍到这了,更多相关Python雪花算法生成唯一ID内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!










