首頁

目前文章總數:157 篇

  

最後更新:2024年 12月 07日

0023. SnowFlake 分散式雪花演算法 (高併發、產生唯一ID數值演算法)

日期:2018年 09月 24日

標籤: C# Asp.NET Framework Windows Forms SnowFlake Algorithm

摘要:C# 學習筆記


環境: Visual Studio 2015 C#
目的: SnowFlake演算法 C#的實作,可以應用於高併發下產生具64 bit 自增式唯一碼的流水號
應用: DB Insert每筆資料時,產生的流水號
Github:下載
基本介紹:本篇分為4大部分。
第一部分:SnowFlake原理
第二部分:C# 程式碼架構
第三部分:實作程式碼說明
第四部分:參考文獻






第一部分: SnowFlake原理

Step 1:SnowFlake原理圖

使用了63bit


Step 2: 取得唯一值的方式

關鍵點:每次為了取得唯一值,需要搭配 TimeStamp (微秒) + MacAddress (自增序號為高併發時,最大可容納數)
12 bit 允許範圍: 0~4095




第二部分:C#程式碼架構

Step 1:專案主程式介紹-1




Step 1:專案主程式介紹-2

SnowFlake主程式 : SnowFlakeAlg
SnowFlake產生ID的Mathod: SnowFlakeAlg.Method






第三部分:實作程式碼說明

Step 1:Form.cs 主程式

執行100次顯示

private void Form1_Load(object sender, EventArgs e)
{      
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(SnowFlakeAlg.GetGuid());
            }

}



Step 2:演算法主要邏輯-1 SnowFlakeAlg.cs

用一個Lock 確保產生的Id 是遞增的,如果在相同微秒下,已經用完了4095個序號,則會強制換下一微秒

/// <summary>
/// 分布式自增演算法 - 產生唯一ID
/// </summary>
public static partial class SnowFlakeAlg
{
    /// <summary>
    /// 鎖住的資源對象
    /// </summary>
    private static object lockItem = new object();

    /// <summary>
    /// 上一個時間戳- 進行比較用
    /// </summary>
    private static long lastDateTimeStamp = 0L;

    /// <summary>
    /// Sequence 序列號 允許0~4095
    /// </summary>
    private static long sequence = 0L;

    public static long GetGuid()
    {
        //非同步情況下,使用Lock 確保產生唯一ID
        lock(lockItem)
        {
            long result = 0L;
            //1. 41bit
            long timelong = SnowFlakeAlg.GetTimeSpan.GetTimeSpanReturnLong();
            //2. 10bit
            long macSn = SnowFlakeAlg.GetMacAddress.GetTenBitMacAddress();
            //3. 12bit
            sequence++;

            //seq == 0 表示 同一秒內已經被排了4095次,Seq 已經用盡,切換至下一秒
            if (timelong == lastDateTimeStamp)
            {
                if (true == SnowFlakeAlg.GetSequence.checkSeq(sequence))
                {
                    //取得下一微秒的Long值
                    timelong = SnowFlakeAlg.GetTimeSpan.GetTimeSpanReturnNextSecondLong();
                }
            }
            else//不同微秒下
            {
                sequence = 0;//歸0
            }
            //紀錄本次的TimeStamp
            lastDateTimeStamp = timelong;
            
            //41bit 
            result =((timelong) << 22) | macSn << 12 | sequence;

            return result;
        }
       
    }
}



Step 4: 執行結果

自增的唯一ID




第四部分:參考文獻

文獻列表


Twitter Blog 連結:https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html