雪花演算法

ssrheart發表於2024-06-07

SnowFlake

雪花演算法概述

雪花演算法是由 Twitter 開發的一種分散式唯一 ID 生成演算法,主要用於分散式系統中需要生成唯一 ID 的場景。它生成的 ID 既有全域性唯一性,又有時間有序性。

雪花演算法 ID 結構

一個典型的雪花演算法生成的 ID 一共有 64 位,通常由以下幾個部分組成:

  1. 1 位符號位:永遠是 0,表示正數。
  2. 41 位時間戳:表示從一個固定時間點(通常是某個紀元時間,比如 2020-01-01 00:00:00)開始經過的毫秒數。這部分可以使用大約 69 年的時間。
  3. 10 位機器 ID:用來表示不同的機器或節點,可以支援最多 1024 個節點。
  4. 12 位序列號:用來表示同一毫秒內產生的不同 ID,每毫秒內可以生成 4096 個不同的 ID。

雪花演算法詳細實現

以下是使用 Python 實現雪花演算法的詳細步驟:

1. 匯入必要模組

import time

2. 定義 Snowflake

class Snowflake:
    def __init__(self, datacenter_id, worker_id, sequence=0):
        self.datacenter_id = datacenter_id
        self.worker_id = worker_id
        self.sequence = sequence
  • datacenter_id:資料中心 ID,表示不同的資料中心。
  • worker_id:機器 ID,表示不同的機器或節點。
  • sequence:序列號,初始化為 0。

3. 定義常量

        self.epoch = 1577836800000  # 固定的時間戳,比如 2020-01-01 00:00:00
        self.datacenter_id_bits = 5
        self.worker_id_bits = 5
        self.sequence_bits = 12
  • epoch:紀元時間,即一個固定的時間點,從這個時間點開始計算經過的毫秒數。
  • datacenter_id_bits:資料中心 ID 的位數,設為 5 位。
  • worker_id_bits:機器 ID 的位數,設為 5 位。
  • sequence_bits:序列號的位數,設為 12 位。

4. 計算最大值

        self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
        self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
        self.max_sequence = -1 ^ (-1 << self.sequence_bits)
  • max_datacenter_id:資料中心 ID 的最大值。
  • max_worker_id:機器 ID 的最大值。
  • max_sequence:序列號的最大值。

5. 定義移位數

        self.worker_id_shift = self.sequence_bits
        self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
        self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
  • worker_id_shift:機器 ID 的移位數。
  • datacenter_id_shift:資料中心 ID 的移位數。
  • timestamp_left_shift:時間戳的移位數。

6. 定義時間戳獲取方法

def _gen_timestamp(self):
    return int(time.time() * 1000)
  • _gen_timestamp:獲取當前時間戳,單位為毫秒。

7. 定義等待方法

    def _wait_for_next_millis(self, last_timestamp):
        timestamp = self._gen_timestamp()
        while timestamp <= last_timestamp:
            timestamp = self._gen_timestamp()
        return timestamp
  • _wait_for_next_millis:等待到下一毫秒,確保時間戳唯一性。

8. 生成唯一 ID

    def next_id(self):
        timestamp = self._gen_timestamp()

        if timestamp < self.last_timestamp:
            raise Exception("Clock is moving backwards. Rejecting requests until %d." % self.last_timestamp)

        if self.last_timestamp == timestamp:
            self.sequence = (self.sequence + 1) & self.max_sequence
            if self.sequence == 0:
                timestamp = self._wait_for_next_millis(self.last_timestamp)
        else:
            self.sequence = 0

        self.last_timestamp = timestamp

        return ((timestamp - self.epoch) << self.timestamp_left_shift) | \
               (self.datacenter_id << self.datacenter_id_shift) | \
               (self.worker_id << self.worker_id_shift) | \
               self.sequence
  • next_id:生成唯一 ID 的方法。
    • 獲取當前時間戳。
    • 如果當前時間戳小於上一個時間戳,丟擲異常。
    • 如果當前時間戳等於上一個時間戳,增加序列號,並檢查是否溢位。如果溢位,等待到下一毫秒。
    • 否則,重置序列號為 0。
    • 更新上一個時間戳。
    • 透過位移操作生成唯一 ID。

使用示例

# 示例使用
datacenter_id = 1  # 資料中心 ID
worker_id = 1      # 機器 ID
snowflake = Snowflake(datacenter_id, worker_id)

for _ in range(10):
    print(snowflake.next_id())
  • 初始化 Snowflake 類例項,傳入資料中心 ID 和機器 ID。
  • 呼叫 next_id 方法生成唯一 ID。

要點

  1. 雪花演算法的用途:生成分散式唯一 ID。
  2. ID 結構
    • 1 位符號位:永遠為 0。
    • 41 位時間戳:從固定時間點開始的毫秒數。
    • 10 位機器 ID:表示不同機器或節點。
    • 12 位序列號:同一毫秒內產生的不同 ID。
  3. 實現步驟
    • 匯入 time 模組。
    • 定義 Snowflake 類,初始化引數。
    • 定義常量:紀元時間、各部分的位數。
    • 計算最大值:資料中心 ID、機器 ID、序列號。
    • 定義移位數:機器 ID 移位數、資料中心 ID 移位數、時間戳移位數。
    • 獲取當前時間戳的方法 _gen_timestamp
    • 等待到下一毫秒的方法 _wait_for_next_millis
    • 生成唯一 ID 的方法 next_id
  4. 使用示例:初始化 Snowflake 例項,生成唯一 ID。

第三方包

https://blog.csdn.net/m0_61970162/article/details/126474140

安裝

pip install pysnowflake

啟動服務

snowflake_start_server --worker=1

編寫程式,獲取id

from snowflake import client

print(client.get_guid())  # 4896771064513695745

相關文章