欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

分布式ID生成方式及技術(shù)實(shí)現(xiàn)(以C#為例)

admin
2024年7月8日 12:43 本文熱度 859

在分布式系統(tǒng)中,生成全局唯一的ID是一個(gè)核心問(wèn)題。這不僅關(guān)系到數(shù)據(jù)的唯一性,還直接影響到系統(tǒng)的性能和擴(kuò)展性。本文將介紹幾種常見(jiàn)的分布式ID生成方式,并通過(guò)C#示例代碼展示其中一種實(shí)現(xiàn)方式——Snowflake算法。

分布式ID生成方式概述

1. UUID

UUID(Universally Unique Identifier)是一種通過(guò)一系列算法生成的128位數(shù)字,通常基于時(shí)間戳、計(jì)算機(jī)硬件標(biāo)識(shí)符、隨機(jī)數(shù)等元素。UUID的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,無(wú)需網(wǎng)絡(luò)交互,保證了ID的全球唯一性。但其缺點(diǎn)也很明顯,如ID較長(zhǎng)(36個(gè)字符的字符串形式),可能導(dǎo)致存儲(chǔ)和索引效率低下,且通常不能保證順序性。

2. 數(shù)據(jù)庫(kù)自增ID

基于數(shù)據(jù)庫(kù)的auto_increment自增ID也可以生成分布式ID。其優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,ID單調(diào)自增,數(shù)值類(lèi)型查詢(xún)速度快。然而,在高并發(fā)場(chǎng)景下,單點(diǎn)數(shù)據(jù)庫(kù)會(huì)成為性能瓶頸,且存在單點(diǎn)故障風(fēng)險(xiǎn)。

3. Redis生成ID

Redis是一個(gè)高性能的鍵值數(shù)據(jù)庫(kù),通過(guò)其原子性的INCR和INCRBY命令可以生成唯一的遞增數(shù)值。Redis的高性能保證了即使在高負(fù)載下也能快速生成ID,但高度依賴(lài)網(wǎng)絡(luò),且需要額外的基礎(chǔ)設(shè)施管理和維護(hù)。

4. 雪花算法(Snowflake)

雪花算法是Twitter開(kāi)源的一種分布式ID生成算法,生成的是一個(gè)64位的長(zhǎng)整型數(shù)字。該算法通過(guò)組合時(shí)間戳、數(shù)據(jù)中心ID、機(jī)器ID和序列號(hào)來(lái)確保ID的全局唯一性和趨勢(shì)遞增。Snowflake算法不依賴(lài)于數(shù)據(jù)庫(kù),適合分布式環(huán)境,且生成ID的性能高。

Snowflake算法詳解及C#實(shí)現(xiàn)

Snowflake算法組成

Snowflake生成的ID由以下幾部分組成:

  • 第1位:未使用,固定為0(由于Java中l(wèi)ong的最高位是符號(hào)位,正數(shù)是0,負(fù)數(shù)是1)。
  • 時(shí)間戳(41位):記錄時(shí)間戳,毫秒級(jí)。支持69年的時(shí)間范圍。
  • 數(shù)據(jù)中心ID(5位):用來(lái)區(qū)分不同的數(shù)據(jù)中心。
  • 機(jī)器ID(5位):用來(lái)區(qū)分同一數(shù)據(jù)中心內(nèi)的不同機(jī)器。
  • 序列號(hào)(12位):同一毫秒內(nèi)產(chǎn)生的不同ID的序列號(hào)。

C#實(shí)現(xiàn)Snowflake算法

下面是一個(gè)用C#實(shí)現(xiàn)的Snowflake算法示例:

using System;

public class SnowflakeIdWorker
{
    private const long SEQUENCE_BIT = 12// 序列號(hào)占用的位數(shù)
    private const long MACHINE_BIT = 5;   // 機(jī)器標(biāo)識(shí)占用的位數(shù)
    private const long DATACENTER_BIT = 5// 數(shù)據(jù)中心占用的位數(shù)

    private const long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    private const long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private const long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);

    private long datacenterId; // 數(shù)據(jù)中心ID
    private long machineId;    // 機(jī)器ID
    private long sequence = 0L// 序列號(hào)
    private long lastStmp = -1L// 上一次時(shí)間戳

    // 起始的時(shí)間戳
    private const long START_STMP = 1480166465631L;

    public SnowflakeIdWorker(long datacenterId, long machineId)
    {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0)
        {
            throw new ArgumentException("數(shù)據(jù)中心ID超出范圍");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0)
        {
            throw new ArgumentException("機(jī)器ID超出范圍");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    public long NextId()
    {
        long currStmp = GetNewstmp();

        if (currStmp < lastStmp)
        {
            throw new Exception("時(shí)鐘倒退, ID生成失敗");
        }

        if (currStmp == lastStmp)
        {
            // 相同毫秒內(nèi),序列號(hào)自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0L)
            {
                currStmp = GetNextMill();
            }
        }
        else
        {
            // 不同毫秒內(nèi),序列號(hào)置為0
            sequence = 0L;
        }

        lastStmp = currStmp;

        return ((currStmp - START_STMP) << (SEQUENCE_BIT + MACHINE_BIT + DATACENTER_BIT)) |
               (datacenterId << (SEQUENCE_BIT + MACHINE_BIT)) |
               (machineId << SEQUENCE_BIT) |
               sequence;
    }

    private long GetNextMill()
    {
        long mill = GetNewstmp();
        while (mill <= lastStmp)
        {
            mill = GetNewstmp();
        }
        return mill;
    }

    private long GetNewstmp()
    {
        return (long)(DateTime.UtcNow - new DateTime(197011000, DateTimeKind.Utc)).TotalMilliseconds;
    }
}

class Program
{
    static void Main(string[] args)
    {
        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(11);
        Console.WriteLine(idWorker.NextId());
    }
}

代碼解釋

上述C#代碼實(shí)現(xiàn)了一個(gè)SnowflakeIdWorker類(lèi),該類(lèi)通過(guò)構(gòu)造函數(shù)接收數(shù)據(jù)中心ID和機(jī)器ID,并通過(guò)NextId方法生成下一個(gè)全局唯一的ID。代碼通過(guò)位運(yùn)算將時(shí)間戳、數(shù)據(jù)中心ID、機(jī)器ID和序列號(hào)組合成一個(gè)64位的長(zhǎng)整型數(shù)字,確保ID的全局唯一性和趨勢(shì)遞增。

結(jié)論

分布式ID生成方式多種多樣,每種方式都有其特定的應(yīng)用場(chǎng)景和優(yōu)缺點(diǎn)。Snowflake算法作為一種高效、可靠的分布式ID生成方式,被廣泛應(yīng)用于各種分布式系統(tǒng)中。通過(guò)C#實(shí)現(xiàn)Snowflake算法,可以方便地集成到各種分布式應(yīng)用中,滿(mǎn)足全局唯一ID的生成需求。


該文章在 2024/7/8 12:43:20 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved