Snowflake 分佈式id生成器--生成唯一ID

在 Snowflake 算法中,通常包含以下幾個部分來構造一個唯一的 ID:

  1. 時間戳(Timestamp):佔據了 64 位 ID 中的高 41 位,用來表示生成 ID 的時間。通過時間戳的遞增,保證了生成的 ID 是遞增且唯一的。

  2. 數據中心 ID(Data Center ID):用於標識不同的數據中心,通常佔據了 5 位。

  3. 機器 ID(Worker ID):用於標識同一數據中心下的不同機器,也通常佔據了 5 位。

  4. 序列號(Sequence Number):用來保證同一毫秒內生成的多個 ID 的唯一性,通常佔據了 12 位。

Snowflake 算法的構造一般是這樣的:

  1. 初始化:傳入數據中心 ID 和機器 ID,初始化 Snowflake 實例時會生成一個開始時間戳(通常是指定一個固定的起始時間)。

  2. 生成 ID:在生成 ID 的時候,根據當前時間戳、數據中心 ID、機器 ID 和序列號生成一個 64 位的唯一 ID。

在 C++ 中,你可以定義一個 Snowflake 類,包含合適的成員變量和方法,以實現 Snowflake 算法。以下是一個簡單的示例:

 

#include <iostream>
#include <chrono>
#include <thread>

class Snowflake {
private:
    int dataCenterId;
    int workerId;
    long long sequence;
    long long lastTimestamp;

public:
    Snowflake(int dataCenterId, int workerId) : dataCenterId(dataCenterId), workerId(workerId), sequence(0), lastTimestamp(-1) {}

    long long generateId() {
        long long timestamp = getCurrentTimestamp();

        if (timestamp < lastTimestamp) {
            // 時間回退,拋出異常或者等待直到時間追上
            throw std::runtime_error("Clock moved backwards. Refusing to generate id.");
        }

        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & 0xFFF; // 序列號取值範圍爲0~4095
            if (sequence == 0) {
                timestamp = waitNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = timestamp;

        return ((timestamp - 1609459200000) << 22) | (dataCenterId << 17) | (workerId << 12) | sequence;
    }

private:
    long long getCurrentTimestamp() {
        return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    }

    long long waitNextMillis(long long lastTimestamp) {
        long long timestamp = getCurrentTimestamp();
        while (timestamp <= lastTimestamp) {
            timestamp = getCurrentTimestamp();
        }
        return timestamp;
    }
};

int main() {
    Snowflake snowflake(1, 1); // 數據中心ID爲1,機器ID爲1

    for(int i=0;i<100;i++){
        long long uniqueId = snowflake.generateId();
        std::cout << "Generated unique ID: " << uniqueId << std::endl<<std::flush;
    }
    return 0;
}

在這個示例中,generateId 方法根據當前時間戳、數據中心 ID、機器 ID 和序列號生成唯一的 ID。getCurrentTimestamp 方法獲取當前的毫秒級時間戳,waitNextMillis 方法用來等待直到時間追上。整個 Snowflake 類實現了一個簡單的 Snowflake 算法生成唯一 ID。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章