乙個分布式ID的生成器 雪花演算法

2021-10-10 18:46:54 字數 2400 閱讀 7889

#coding:utf-8

'''create on 2020-11-23

@author:sandy

'''import time

class snowflake(object):

def __init__(self,datacenterid,machineid):

self.sequence = 0

self.laststmp = -1

self.sequence_bit = 12

self.machine_bit = 5

self.datacenter_bit = 5

self.max_datacenter_num = -1 ^ (-1 << self.datacenter_bit)

self.max_machine_num = -1 ^ (-1 << self.machine_bit)

self.max_sequence_num = -1 ^ (-1 << self.sequence_bit)

self.machine_left = self.sequence_bit

self.datacenter_left = self.sequence_bit + self.machine_bit

self.timestmp_left = self.datacenter_left + self.datacenter_bit

print(self.max_datacenter_num,self.max_machine_num,self.max_sequence_num)

if datacenterid > self.max_datacenter_num or datacenterid < 0:

raise exception("datacenterid",datacenterid)

if machineid > self.max_machine_num or machineid < 0:

raise exception("machineid",machineid)

self.start_stmp = 1606118422000l

self.datacenterid = datacenterid

self.machineid = machineid

def nextid(self):

curstmp = self.getnewstmp()

if curstmp < self.laststmp:

raise exception("clock moved backwards. refusing to generate id")

if curstmp == self.laststmp:

self.sequence = (self.sequence + 1) & self.max_sequence_num

if self.sequence == 0:

time.sleep(0.001)

curstmp = self.getnewstmp()

else:

pass

else:

self.sequence = 0

self.laststmp = curstmp

ret = (curstmp - self.start_stmp) << self.timestmp_left | self.datacenterid << self.datacenter_left | self.machineid << self.machine_left | self.sequence

return ret

def getnewstmp(self):

return int(time.time() * 1000)

if __name__ == '__main__':

flake = snowflake(5,5)

for i in range(1000):

nextid = flake.nextid()

print(nextid)

snowflake的結構如下(每部分用-分開):

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000  第一位為未使用,

接下來的41位為毫秒級時間(41位的長度可以使用69年),

然後是5位datacenterid和5位workerid(10位的長度最多支援部署1024個節點)

最後12位是毫秒內的計數(12位的計數順序號支援每個節點每毫秒產生4096個id序號)

如果1ms內生成的數超過4096個  也就是self.sequence = (self.sequence + 1) & self.max_sequence_num 後 self.sequence == 0 這種情況,對於碰到這種情況 sleep 一下  當然也有其他的方式解決這種情況

分布式ID生成器(雪花演算法)

目前微服務架構盛行,在分布式系統中的操作中都會有一些全域性性id的需求,所以我們不能使用資料庫本身的自增功能來產生主鍵值,只能由程式來生成唯一的主鍵值。我們採用的是開源的twitter 非官方中文慣稱 推特.是國外的乙個 是乙個社交網路及微部落格服務 的snowflake 雪花 演算法。各個段解析 ...

分布式id生成器,雪花演算法IdWorker

名稱 idworker.j a 描述 分布式自增長id twitter的 snowflake j a實現方案 核心 為其idworker這個類實現,其原理結構如下,我分別用乙個0表示一位,用 分割開部分的作用 1 0 0000000000 0000000000 0000000000 00000000...

分布式ID生成器

一 需求緣起 幾乎所有的業務系統,都有生成乙個唯一記錄標識的需求,例如 這個記錄標識往往就是資料庫中的主鍵,資料庫上會建立聚集索引 cluster index 即在物理儲存上以這個字段排序。這個記錄標識上的查詢,往往又有分頁或者排序的業務需求,例如 所以往往要有乙個time欄位,並且在time欄位上...