Python實現雪花算法
其實這段代碼很早之前就寫好了,當時寫這段代碼也沒有用到分布式系統,知道總比不知道好,自己鑽研下,能給自己帶來代碼的靈感。
此版本絕對不是百度搜出來千篇一律的代碼。
雪花算法介紹
很多教程已經介紹的很清楚了,簡而言之,雪花算法(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了,壓縮了后面的位數,其實核心思想是一樣的。
這段代碼也不過是給大家一個參照罷了。