国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C# 分布式自增ID算法snowflake(雪花算法)

這篇具有很好參考價(jià)值的文章主要介紹了C# 分布式自增ID算法snowflake(雪花算法)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 概述

分布式系統(tǒng)中,有一些需要使用全局唯一ID的場景,這種時候?yàn)榱朔乐?code>ID沖突可以使用36位的UUID,但是UUID有一些缺點(diǎn),首先他相對比較長,另外UUID一般是無序的。有些時候我們希望能使用一種簡單一些的ID,并且希望ID能夠按照時間有序生成。而Twittersnowflake解決了這種需求,最初Twitter把存儲系統(tǒng)從MySQL遷移到Cassandra,因?yàn)?code>Cassandra沒有順序ID生成機(jī)制,所以開發(fā)了這樣一套全局唯一ID生成服務(wù)。

該項(xiàng)目地址為:https://github.com/twitter/snowflake 是用 Scala實(shí)現(xiàn)的

參考:

  • C# 分布式自增ID算法snowflake(雪花算法) - 五維思考 - 博客園 (cnblogs.com)

  • C#雪花Id_c# 雪花id-CSDN博客

2. 結(jié)構(gòu)

第1位 第2位 第3位 第4位 第5位
位數(shù) 時間戳(ms) 數(shù)據(jù)中心ID(DatacenterId ) 工作節(jié)點(diǎn)ID (MachineId ) 自增序列號
0 0000000000 0000000000 0000000000 000000000000
  • 第1位:未使用
  • 第2位:接下來的41位為毫秒級時間(41位的長度可以使用69年),用毫秒級的時間戳來表示自1970年1月1日 00:00:00 GMT以來的時間。
  • 第3-4位:用來區(qū)分不同的數(shù)據(jù)中心 datacenterIdmachineId,可根據(jù)實(shí)際情況分配,最多可容納1024個數(shù)據(jù)中心(2^10=10位的長度最多支持部署1024個節(jié)點(diǎn)),也可以設(shè)置成5位,最大節(jié)點(diǎn)是32個。
  • 最后12位是毫秒內(nèi)的計(jì)數(shù)(12位的計(jì)數(shù)順序號支持每個節(jié)點(diǎn)每毫秒產(chǎn)生4096個ID序號)

一共加起來剛好64位,為一個Long型。(轉(zhuǎn)換成字符串長度為18)

snowflake生成的ID整體上按照時間自增排序,并且 整個分布式 系統(tǒng)內(nèi)不會產(chǎn)生ID碰撞(由datacentermachineId作區(qū)分),并且效率較高。據(jù)說:snowflake每秒能夠產(chǎn)生26萬個ID。

注意:

  • 在實(shí)際使用中,需要根據(jù)不同的分布式環(huán)境配置合適的數(shù)據(jù)中心ID和工作節(jié)點(diǎn)ID,以保證生成的雪花Id的唯一性和順序性。
  • 其中 dataCenterIdworkerId 分別是數(shù)據(jù)中心和工作節(jié)點(diǎn)的標(biāo)識,該生成器依賴于數(shù)據(jù)中心ID和工作節(jié)點(diǎn)ID兩個參數(shù)進(jìn)行初始化。具體的生成過程是根據(jù)當(dāng)前時間戳、數(shù)據(jù)中心ID、工作節(jié)點(diǎn)ID和自增序列號,通過位運(yùn)算組合生成一個64位的唯一標(biāo)識。

3. 代碼

3.1 IdWorker.cs

using System;
/// <summary>
/// Twitter的分布式自增ID雪花算法
/// </summary>
public class IdWorker
{
    //起始的時間戳
    private static long START_STMP = 1480166465631L;

    //每一部分占用的位數(shù)
    private static int SEQUENCE_BIT = 12; //序列號占用的位數(shù)
    private static int MACHINE_BIT = 5;   //機(jī)器標(biāo)識占用的位數(shù)
    private static int DATACENTER_BIT = 5;//數(shù)據(jù)中心占用的位數(shù)

    //每一部分的最大值
    private static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    private static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);

    //每一部分向左的位移
    private static int MACHINE_LEFT = SEQUENCE_BIT;
    private static int DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private static int TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;

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

    #region 單例:完全懶漢
    private static readonly Lazy<IdWorker> lazy = new Lazy<IdWorker>(() => new IdWorker());
    public static IdWorker Singleton { get { return lazy.Value; } }
    private IdWorker() { }
    #endregion

    public IdWorker(long cid, long mid)
    {
        if (cid > MAX_DATACENTER_NUM || cid < 0) throw new Exception($"中心Id應(yīng)在(0,{MAX_DATACENTER_NUM})之間");
        if (mid > MAX_MACHINE_NUM || mid < 0) throw new Exception($"機(jī)器Id應(yīng)在(0,{MAX_MACHINE_NUM})之間");
        datacenterId = cid;
        machineId = mid;
    }

    /// <summary>
    /// 產(chǎn)生下一個ID
    /// </summary>
    /// <returns></returns>
    public long nextId()
    {
        long currStmp = getNewstmp();
        if (currStmp < lastStmp) throw new Exception("時鐘倒退,Id生成失敗!");

        if (currStmp == lastStmp)
        {
            //相同毫秒內(nèi),序列號自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列數(shù)已經(jīng)達(dá)到最大
            if (sequence == 0L) currStmp = getNextMill();
        }
        else
        {
            //不同毫秒內(nèi),序列號置為0
            sequence = 0L;
        }

        lastStmp = currStmp;

        return (currStmp - START_STMP) << TIMESTMP_LEFT       //時間戳部分
                      | datacenterId << DATACENTER_LEFT       //數(shù)據(jù)中心部分
                      | machineId << MACHINE_LEFT             //機(jī)器標(biāo)識部分
                      | sequence;                             //序列號部分
    }

    private long getNextMill()
    {
        long mill = getNewstmp();
        while (mill <= lastStmp)
        {
            mill = getNewstmp();
        }
        return mill;
    }

    private long getNewstmp()
    {
        return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
    }
}



3.2 IdWorkerTest.cs (測試)

使用

IdWorker idworker = IdWorker.Singleton;
Console.WriteLine(idworker.nextId());

測試

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Test.Simple
{
    public static class IdWorkerTest
    {
        public static void Test()
        {
            /***
             * 
             *  兩種測試方法,均為500并發(fā),生成5000個Id:
             *  Machine1() 模擬1臺主機(jī),單例模式獲取實(shí)例
             *  Machine5() 模擬5臺主機(jī),創(chuàng)建5個實(shí)例
             */
            
            Machine1();

            Machine2();

            Machine5();
        }

        public static void Machine1()
        {

            int cid = 1;
            int mid = 15;
            Console.WriteLine("雪花ID -- IdWorkerTest -- 模擬1臺主機(jī)( 數(shù)據(jù)中心{0} - 機(jī)器節(jié)點(diǎn){1}): ", cid, mid);
            IdWorker idworker = new IdWorker(cid, mid);
            Console.WriteLine(idworker.nextId());

            cid = 2;
            mid = 10;
            Console.WriteLine("雪花ID -- IdWorkerTest -- 模擬1臺主機(jī)( 數(shù)據(jù)中心{0} - 機(jī)器節(jié)點(diǎn){1}): ", cid, mid);
            idworker = new IdWorker(cid, mid);
            Console.WriteLine(idworker.nextId());
        }

        public static void Machine2()
        {
            Console.WriteLine("雪花ID -- IdWorkerTest -- 模擬1臺主機(jī) : ");
            for (int j = 0; j < 500; j++)
            {
                Task.Run(() =>
                {
                    IdWorker idworker = IdWorker.Singleton;
                    for (int i = 0; i < 10; i++)
                    {
                        Console.WriteLine(idworker.nextId());
                    }
                });
            }
        }

        public static void Machine5()
        {
            Console.WriteLine("雪花ID -- IdWorkerTest -- 模擬5臺主機(jī) : ");
            List<IdWorker> workers = new List<IdWorker>();
            Random random = new Random();
            for (int i = 0; i < 5; i++)
            {
                workers.Add(new IdWorker(1, i + 1));
            }
            for (int j = 0; j < 500; j++)
            {
                Task.Run(() =>
                {
                    for (int i = 0; i < 10; i++)
                    {
                        int mid = random.Next(0, 5);
                        Console.WriteLine(workers[mid].nextId());
                    }
                });
            }
        }
    }
}


在這里插入圖片描述
c# 雪花算法,.NET項(xiàng)目,c#,分布式,算法
c# 雪花算法,.NET項(xiàng)目,c#,分布式,算法
結(jié)束文章來源地址http://www.zghlxwxcb.cn/news/detail-846552.html

到了這里,關(guān)于C# 分布式自增ID算法snowflake(雪花算法)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 分布式—雪花算法生成ID

    分布式—雪花算法生成ID

    由64個Bit(比特)位組成的long類型的數(shù)字 0 | 0000000000 0000000000 0000000000 000000000 | 00000 | 00000 | 000000000000 1個bit:符號位,始終為0。 41個bit:時間戳,精確到毫秒級別,可以使用69年。 10個bit:工作機(jī)器ID,可以部署在1024個節(jié)點(diǎn)上。 12個bit:序列號,每個節(jié)點(diǎn)每毫秒內(nèi)最多可以生成

    2024年02月11日
    瀏覽(20)
  • 分布式唯一ID 雪花算法

    分布式唯一ID 雪花算法

    ?????????個人主頁:五敷有你? ? ?? ???系列專欄:算法分析與設(shè)計(jì) ??穩(wěn)中求進(jìn),曬太陽 雪花算法是 64 位 的二進(jìn)制,一共包含了四部分: 1位是符號位,也就是最高位,始終是0,沒有任何意義,因?yàn)橐俏ㄒ挥?jì)算機(jī)二進(jìn)制補(bǔ)碼中就是負(fù)數(shù),0才是正數(shù)。 41位是時間戳

    2024年04月10日
    瀏覽(24)
  • 分布式ID(2):雪花算法生成ID

    分布式ID(2):雪花算法生成ID

    1 雪花算法簡介 這種方案大致來說是一種以劃分命名空間(UUID也算,由于比較常見,所以單獨(dú)分析)來生成ID的一種算法,這種方案把64-bit分別劃分成多段,分開來標(biāo)示機(jī)器、時間等,比如在snowflake中的64-bit分別表示如下圖(圖片來自網(wǎng)絡(luò))所示: 41-bit的時間可以表示(1L

    2024年01月20日
    瀏覽(30)
  • 分布式id解決方法--雪花算法

    分布式id解決方法--雪花算法

    uuid,jdk自帶,但是數(shù)據(jù)庫性能差,32位呀。 mysql數(shù)據(jù)庫主鍵越短越好,B+tree產(chǎn)生節(jié)點(diǎn)分裂,大大降低數(shù)據(jù)庫性能,所以uuid不建議。 redis的自增,但是要配置維護(hù)redis集群,就為了一個id,還要引入一套redis。費(fèi)事,成本高。 如果有序自增別人就知道你的業(yè)務(wù)量多少了。 分布式

    2024年02月04日
    瀏覽(23)
  • 雪花算法生成分布式主鍵ID

    直接上代碼,復(fù)制即可使用 在這個示例中,你可以通過 SnowflakeIdGenerator.init(dataCenterId, workerId); 初始化數(shù)據(jù)中心 ID 和工作 ID,然后通過 SnowflakeIdGenerator.generateId(); 靜態(tài)方法生成 Snowflake ID 的字符串形式。

    2024年02月22日
    瀏覽(23)
  • 【智能排班系統(tǒng)】雪花算法生成分布式ID

    【智能排班系統(tǒng)】雪花算法生成分布式ID

    在復(fù)雜而龐大的分布式系統(tǒng)中,確保數(shù)據(jù)實(shí)體的唯一標(biāo)識性是一項(xiàng)至關(guān)重要的任務(wù),生成全局唯一且有序的ID生成機(jī)制成為必不可少的環(huán)節(jié)。雪花算法(Snowflake Algorithm)正是為此目的而生,以其簡潔的設(shè)計(jì)、高效的表現(xiàn)與良好的擴(kuò)展性贏得了業(yè)界的廣泛認(rèn)可。 雪花算法最早由

    2024年04月10日
    瀏覽(22)
  • 【Java筆記】分布式id生成-雪花算法

    【Java筆記】分布式id生成-雪花算法

    隨著業(yè)務(wù)的增長,有些表可能要占用很大的物理存儲空間,為了解決該問題,后期使用數(shù)據(jù)庫分片技術(shù)。將一個數(shù)據(jù)庫進(jìn)行拆分,通過數(shù)據(jù)庫中間件連接。如果數(shù)據(jù)庫中該表選用ID自增策略,則可能產(chǎn)生重復(fù)的ID,此時應(yīng)該使用分布式ID生成策略來生成ID。 snowflake是Twitter開源的

    2024年02月11日
    瀏覽(22)
  • 雪花算法,在分布式環(huán)境下實(shí)現(xiàn)高效的ID生成

    其實(shí)雪花算法比較簡單,可能稱不上什么算法,就是一種構(gòu)造UID的方法。 點(diǎn)1:UID是一個long類型的41位時間戳,10位存儲機(jī)器碼,12位存儲序列號。 點(diǎn)2:時間戳的單位是毫秒,可以同時鏈接1024臺機(jī)器,每臺機(jī)器每毫秒可以使用4096個序列號,我們會給生成id上一個同步鎖,阻塞

    2024年02月15日
    瀏覽(29)
  • JAVA實(shí)用工具: 改良版雪花算法-分布式唯一ID神器

    JAVA實(shí)用工具: 改良版雪花算法-分布式唯一ID神器

    Seata內(nèi)置了一個分布式UUID生成器,用于輔助生成全局事務(wù)ID和分支事務(wù)ID。具體如下特點(diǎn): 高性能 全局唯一 趨勢遞增 這個分布式UUID生成器是基于雪花算法進(jìn)行改良的,本文針對改良的方法、目的等進(jìn)行總結(jié) 改良版雪花算法的實(shí)現(xiàn)原理參考如下: Seata基于改良版雪花算法的分

    2024年02月14日
    瀏覽(24)
  • 對于現(xiàn)有的分布式id發(fā)號器的思考 id生成器 雪花算法 uuid

    目錄 雪花id tinyid uuid 分布式id特點(diǎn) 業(yè)務(wù)編號 數(shù)據(jù)中心編號 當(dāng)前時間 ip地址 當(dāng)前序號 對于時鐘回?fù)軉栴} 發(fā)號器機(jī)器當(dāng)期時間小于redis的時間 解決步驟 發(fā)號器機(jī)器當(dāng)期時間等于redis時間 發(fā)號器機(jī)器當(dāng)期時間大于redis最大的時間(相關(guān)的key不存在) 分布式id的單次獲取和批次獲

    2024年02月13日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包