天天看點

分布式自增ID算法Snowflake

作者:測試者穆勒

過去的項目開發中,我們常常選用的資料庫是mysql,mysql以其體積小、速度快等優勢,備受中小型項目的青睐。随着項目資料量的迅速增長,mysql已無法滿足我們的項目需求,資料遷移迫在眉睫。經多方對比綜合考慮,我們選擇了tidb分布式資料庫。但是資料遷移後我們遇到一個問題,之前mysql資料庫中,我們采用的是自增id主鍵,可選用的tidb又對自增主鍵不是很友好,是以我們選用了另一種主鍵生成方式:Snowflake算法。

算法原理

SnowFlake算法是Twitter設計的一個可以在分布式系統中生成唯一的ID的算法,它可以滿足每秒上萬條消息ID配置設定的請求,這些消息ID是唯一的且有大緻的遞增順序。

SnowFlake算法産生的ID是一個64位的整型,結構如下:

分布式自增ID算法Snowflake

第一位是辨別位,一般不使用,接下來的41位為毫秒級時間差(以1970年為起始時間,41位的長度可以使用69年,從1970-01-01 08:00:00,年 = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69),然後是5位datacenterId(最大支援25=32個,二進制表示從00000-11111,也即是十進制0-31),和5位workerId(最大支援25=32個,原理同datacenterId),是以datacenterId*workerId最多支援部署1024個節點,最後12位是毫秒内的計數(12位的計數順序号支援每個節點每毫秒産生2^12=4096個ID序号)。

所有位數加起來共64位,恰好是一個Long型。

當然,實際使用過程中,時間戳、工作機id、序列号的位數是可以根據需要調整的。

優缺點

優點:

01

趨勢遞增:毫秒數在高位,序列号在低位

02

性能高無單點:本地計算不依賴資料庫等第三方

03

使用靈活:三個組成部分的位數可按需求調整

缺點:

01

序列不連續

02

無法控制生成規則(比如序列起始等)

03

強依賴機器時鐘,如果時鐘回撥,會導緻序列重複或者系統不可用

實作代碼

#coding: utf-8
import datetime
# 起始時間, 不能改變, 2020-04-10
twepoch = 1586448000000
datacenter_id_bits = 5
worker_id_bits = 15
sequence_id_bits = 2
max_datacenter_id = 1 << datacenter_id_bits
max_worker_id = 1 << worker_id_bits
max_sequence_id = 1 << sequence_id_bits
max_timestamp = 1 << (64 - datacenter_id_bits - worker_id_bits - sequence_id_bits)

def make_snowflake(timestamp_ms, datacenter_id, worker_id, sequence_id, twepoch=twepoch):
    """generate a twitter-snowflake id, based on
    :param timestamp_ms: time since UNIX epoch in milliseconds
    :param datacenter_id: exec ip
    :param worker_id: process id,max is 32767, min is 0
    :param sequence_id: thread id, max is 3, min is 0
    :param twepoch: start time stamp
    :return:
    """
    sid = ((int(timestamp_ms) - twepoch) % max_timestamp) << datacenter_id_bits << worker_id_bits << sequence_id_bits
    sid += (datacenter_id % max_datacenter_id) << worker_id_bits << sequence_id_bits
    sid += (worker_id % max_worker_id) << sequence_id_bits
    sid += sequence_id % max_sequence_id

           

效果

采用Snowflake算法後,資料id可以保持時間遞增并且全局唯一。

分布式自增ID算法Snowflake

總結

Snowflake是分布式系統中,用來生成全局唯一ID的一種常用算法。和UUID相比,Snowflake具有簡單、占用空間小、有序等優點。但Snowflake算法也有它的弊端,時鐘回撥、時鐘錯亂問題,将是我們程式中需要考慮的問題。

[更多技術文章](https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=toutiao×tamp=1662397200&author=Muller)

繼續閱讀