C# 實現雪花算法(Snowflake Algorithm)詳解與應用

在現代分布式系統中,生成全局唯一的標識符(ID)是一個非常重要的問題。隨著微服務架構和分布式系統的普及,傳統的單機數據庫生成 ID 的方式已無法滿足高并發和高可用的需求。為了解決這個問題,Twitter 提出了 雪花算法(Snowflake Algorithm),它是一種高效、可擴展的分布式 ID 生成算法。

本文將詳細介紹雪花算法的原理、優缺點,并結合 C# 代碼示例展示如何實現這一算法。

1. 什么是雪花算法?

雪花算法(Snowflake ID)是一個分布式唯一 ID 生成算法,旨在生成具有高性能、唯一性且按時間排序的 ID。它由 Twitter 在其早期分布式系統中提出,并迅速成為生成全局唯一 ID 的標準方案。

雪花算法通過將 64 位的整數分為多個部分來編碼信息。每一部分代表不同的含義,如時間戳、機器 ID、序列號等,確保生成的 ID 不僅唯一且具有一定的時間順序。

2. 雪花算法的結構

雪花算法生成的 ID 是一個 64 位的整數,通常被分成以下幾部分:

位數描述
1 bit符號位,固定為 0
41 bits時間戳,表示自紀元時間以來的毫秒數
10 bits機器 ID,用于標識不同的機器或節點
12 bits序列號,同一毫秒內生成多個 ID 時,保證唯一性

3. 雪花算法的各部分解析

3.1 符號位(1 bit)
  • 由于生成的 ID 是正整數,符號位通常固定為 0。這一位沒有實際用途。

3.2 時間戳(41 bits)
  • 時間戳部分用來表示自一個固定時間點(通常是“紀元時間”)以來的毫秒數。41 位時間戳能夠支持大約 69 年的時間范圍,這對于絕大多數應用場景是足夠的。

  • 通過時間戳部分,生成的 ID 可以按時間順序遞增,這對于數據庫索引排序、消息隊列等非常有用。

3.3 機器 ID(10 bits)
  • 機器 ID 用來標識不同的機器節點。在分布式系統中,通常每臺機器或節點都會分配一個唯一的機器 ID,10 位的機器 ID 最大支持 1024 臺機器。

3.4 序列號(12 bits)
  • 序列號用于保證同一毫秒內生成多個 ID 時的唯一性。12 位序列號能夠支持每毫秒最多生成 4096 個不同的 ID。

4. 雪花算法的工作原理

雪花算法的工作原理非常簡單:

  1. 獲取當前時間戳:每次生成 ID 時,首先獲取當前的時間戳(單位:毫秒),并與上次生成 ID 的時間戳進行比較。如果時間戳相同,則進入同一毫秒內生成 ID 的過程。

  2. 生成序列號:在同一毫秒內,每次生成 ID 時,序列號會自增。序列號的最大值是 4095,若達到上限,算法將等待下一毫秒來生成新的 ID。

  3. 拼接 ID:通過將各部分(時間戳、機器 ID 和序列號)拼接成一個 64 位的整數,得到最終的雪花 ID。

5. 雪花算法的優缺點

優點
  1. 高效性:雪花算法生成 ID 的速度非常快,可以在高并發場景下高效地生成唯一的 ID。

  2. 全局唯一性:通過結合時間戳、機器 ID 和序列號,確保生成的 ID 在分布式環境中是全局唯一的。

  3. 有序性:雪花算法生成的 ID 按照時間戳遞增,可以用于按時間排序的數據場景。

  4. 高可擴展性:通過配置機器 ID 和序列號的位數,雪花算法能夠支持大規模的分布式系統,能夠為數千臺機器生成唯一的 ID。

缺點
  1. 依賴時鐘:雪花算法依賴于系統時鐘,如果系統時鐘發生回撥(例如系統時間被手動修改),可能會導致 ID 沖突。為了解決這個問題,通常需要在算法中增加時鐘回撥檢測機制。

  2. 機器 ID 限制:機器 ID 的位數有限制(例如 10 位),因此最多只能支持 1024 臺機器。如果機器數量超過限制,可能需要調整機器 ID 位數,或者采取其他方法來解決。

6. C# 實現雪花算法

接下來,我們將使用 C# 實現一個簡單的雪花算法生成器類 SnowflakeIdGenerator,并展示如何生成唯一的雪花 ID。

6.1 C# 實現雪花算法
using System;public class SnowflakeIdGenerator
{// 雪花算法的各個參數private static readonly long Epoch = new DateTime(2022, 1, 1).Ticks / 10000;  // 設置紀元時間(單位:毫秒)private static readonly int MachineIdBits = 10;  // 機器ID部分占用的位數private static readonly int SequenceBits = 12;   // 序列號部分占用的位數private static readonly long MaxMachineId = -1L ^ (-1L << MachineIdBits);  // 最大機器ID(1023)private static readonly long SequenceMask = -1L ^ (-1L << SequenceBits);   // 最大序列號(4095)private long lastTimestamp = -1L;  // 上次生成ID的時間戳private long machineId;            // 機器IDprivate long sequence = 0L;        // 序列號private readonly object lockObject = new object();// 構造函數:傳入機器IDpublic SnowflakeIdGenerator(long machineId){if (machineId > MaxMachineId || machineId < 0){throw new ArgumentException($"Machine ID should be between 0 and {MaxMachineId}");}this.machineId = machineId;}// 生成下一個唯一的IDpublic long NextId(){lock (lockObject){long timestamp = GetCurrentTimestamp();if (timestamp == lastTimestamp){// 同一毫秒內,序列號加1sequence = (sequence + 1) & SequenceMask;if (sequence == 0){// 如果序列號溢出,等待下一毫秒timestamp = WaitNextMillis(lastTimestamp);}}else{sequence = 0;}lastTimestamp = timestamp;// 組合成64位的IDreturn (timestamp - Epoch) << (MachineIdBits + SequenceBits)  // 時間戳部分| (machineId << SequenceBits)                        // 機器ID部分| sequence;                                          // 序列號部分}}// 獲取當前時間戳(毫秒)private long GetCurrentTimestamp(){return DateTime.UtcNow.Ticks / 10000 - Epoch;  // 獲取當前時間的毫秒數}// 等待下一毫秒private long WaitNextMillis(long lastTimestamp){long timestamp = GetCurrentTimestamp();while (timestamp <= lastTimestamp){timestamp = GetCurrentTimestamp();}return timestamp;}
}
6.2 使用示例
public class Program
{public static void Main(){var generator = new SnowflakeIdGenerator(1);  // 創建一個機器 ID 為 1 的 SnowflakeIdGenerator 實例for (int i = 0; i < 10; i++){long id = generator.NextId();  // 生成一個新的唯一IDConsole.WriteLine(id);          // 打印生成的ID}}
}

7. 總結

雪花算法是一種高效、全局唯一且有序的分布式 ID 生成算法,廣泛應用于大規模分布式系統中。通過時間戳、機器 ID 和序列號的組合,雪花算法能夠生成具有高性能和高可擴展性的唯一 ID。在 C# 中,雪花算法的實現非常簡單,并能夠為分布式系統中的每個節點提供唯一的標識符。

盡管雪花算法有許多優點,但它也依賴于系統時鐘,因此在使用時需要特別注意系統時鐘的回撥問題。如果你的系統對時間順序有高

要求,雪花算法無疑是一個理想的選擇。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80248.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80248.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80248.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32+ESP8266連接onenet新平臺

若該文為原創文章&#xff0c;轉載請注明原文出處。 阿里云物聯網平臺無法開通了&#xff0c;所以嘗試使用onenet平臺。 一、硬件 1、STM32F103C8T6最?系統板 2、ESP-01S 3、DHT11 二、軟件 1、KEIL5.29 2、Token生成工具 3、app inventor 三、原理 四、平臺搭建 1、注…

深入解析Spring Boot與Redis集成:高效緩存實踐

深入解析Spring Boot與Redis集成&#xff1a;高效緩存實踐 引言 在現代Web應用開發中&#xff0c;緩存技術是提升系統性能的重要手段之一。Redis作為一種高性能的鍵值存儲數據庫&#xff0c;廣泛應用于緩存、會話管理和消息隊列等場景。本文將詳細介紹如何在Spring Boot項目中…

Python自學筆記3 常見運算符

常用運算符 加減法 python的自動數據類型轉換 整形轉為浮點型 實數轉為復數 數字類型不能和浮點數類型相加減 乘除法 數據轉換基本同加減法&#xff0c; 但字符串可以和整數相加減&#xff0c;作用是字符串的自我復制 反斜杠 成員運算符 判斷一個元素是不是一個序列的成員…

[特殊字符]接口測試用例設計指南:全面覆蓋與精準驗證

一、接口測試的核心價值 接口作為系統間通信的橋梁&#xff0c;其穩定性和準確性直接影響業務功能。通過科學設計的測試用例&#xff0c;可以提前暴露接口潛在缺陷&#xff0c;降低上下游系統的耦合風險。本文將系統講解接口測試的用例設計策略&#xff0c;覆蓋查詢類接口與操…

[SpringBoot]Spring MVC(2.0)

緊接上文&#xff0c;這篇我們繼續講剩下的HTTp請求 傳遞JSON數據 簡單來說&#xff1a;JSON就是?種數據格式,有??的格式和語法,使??本表??個對象或數組的信息,因此JSON本質是字符串. 主要負責在不同的語?中數據傳遞和交換 JSON的語法 1. 數據在 鍵值對(Key/Value) …

錨點跳轉跟蹤#

一、html <div ref"computingref"><section id"section1"> </section><section id"section2"> </section><section id"section3"> </section> </div><div class"nav-list&q…

一文了解多模態大模型LLaVA與LLaMA的概念

目錄 一、引言 二、LLaVA與LLaMA的定義 2.1 LLaMA 2.2 LLaVA 2.3 LLaVA-NeXT 的技術突破 三、產生的背景 3.1 LLaMA的背景 3.2 LLaVA的背景 四、與其他競品的對比 4.1 LLaMA的競品 4.2 LLaVA的競品 五、應用場景 5.1 LLaMA的應用場景 5.2 LLaVA的應用場景 六…

【LLM】大模型算力基礎設施——核心硬件GPU/TPU,架構技術NVLink/RDMA,性能指標FP64/FLOPS(NVIDIA Tesla型號表)

【LLM】大模型算力基礎設施——核心硬件GPU/TPU&#xff0c;架構技術NVLink/RDMA&#xff0c;性能指標FP64/FLOPS&#xff08;NVIDIA Tesla型號表&#xff09; 文章目錄 1、核心硬件GPU/TPU&#xff0c;NVIDIA Tesla2、集群架構設計 NVLink / RDMA / Alluxio3、性能關鍵指標&am…

spark的Standalone模式介紹

Apache Spark 的 Standalone 模式是其自帶的集群管理模式&#xff0c;無需依賴外部資源管理器&#xff08;如 YARN 或 Mesos&#xff09;&#xff0c;可快速部署和運行 Spark 集群。以下是對 Standalone 模式的詳細介紹&#xff1a; 1. 核心組件 Master 節點 集群的主控制器…

YOLOv7訓練時4個類別只出2個類別

正常是4個類別&#xff1a; 但是YOLOv7訓練完后預測總是只有兩個類別&#xff1a; 而且都是LFM和SFM 我一開始檢查了下特征圖大小&#xff0c;如果輸入是640*640的話&#xff0c;三個尺度特征圖是80*80,40*40,20*20&#xff1b;如果輸入是416*416的話&#xff0c;三個尺度特征…

【Unity】用事件廣播的方式實現游戲暫停,簡單且實用!

1.前言 在做Unity項目的時候&#xff0c;要考慮到“游戲暫停”的功能&#xff0c;最直接的辦法是修改游戲的Time.TimeScale 0f。但是這種方式的影響也比較大&#xff0c;因為它會導致游戲中很多程序無法正常運行。 于是我就有了一個想法&#xff0c;在游戲中想要暫停的對象&…

Suna: 開源多面手 AI 代理

GitHub&#xff1a;GitHub - kortix-ai/suna: Suna - Open Source Generalist AI Agent 更多AI開源軟件&#xff1a;發現分享好用的AI工具、AI開源軟件、AI模型、AI變現 - 小眾AI Suna 是一個完全開源的 AI 助手&#xff0c;可幫助您輕松完成實際任務。通過自然對話&#xff0c…

直接從圖片生成 html

1. 起因&#xff0c; 目的: 無意間碰到一個網站: https://wise.com/zh-cn/currency-converter/brl-to-cny-rate其實我就是想搜一下巴西的貨幣單位是什么。這個網站的設計很漂亮&#xff0c; 尤其是顏色搭配很不錯&#xff0c;討人喜歡。所以我想讓 AI 幫我生成類似的效果。本文…

驗證碼與登錄過程邏輯學習總結

目錄 前言 一、驗證碼與登錄 二、使用步驟 1.先apipost測試一波 2.先搞驗證碼 3.跨域問題 4.后端走起 總結 前言 近期要做一個比較完整的demo&#xff0c;需要自己做一個前端登錄頁面&#xff0c;不過api接口都是現成的&#xff0c;一開始以為過程會很easy&#xff0c;…

軌道炮--范圍得遍歷,map巧統計

1.思路很難想&#xff0c;但代碼一看一下就明白了&#xff0c;就是模擬時間&#xff0c;map存起來遍歷也不受10*6影響 2.每次先統計點對應的直線&#xff0c;再動這個點&#xff0c;map一遍歷實時更新ma統計max&#xff0c;AC!!!! https://www.luogu.com.cn/problem/P8695 #i…

Vue 3.5 新特性深度解析:全面升級的開發體驗

Vue 3.5 新特性深度解析&#xff1a;全面升級的開發體驗 前言 隨著Vue 3.5的正式發布&#xff0c;這個漸進式JavaScript框架再次帶來了令人興奮的改進。本文將深入剖析Vue 3.5的核心更新&#xff0c;幫助開發者快速掌握新特性并應用于實際項目。 ? 核心新特性 1. 增強的響應…

質量管理工程師面試總結

今天閑著無聊參加了學校招聘會的一家雙選會企業&#xff0c;以下是面試的過程。 此次面試采用的是一對多的形式。&#xff08;此次三個求職者&#xff0c;一個面試官&#xff09; 面試官&#xff1a;開始你們每個人先做個自我介紹吧。 哈哈哈哈哈哈哈哈&#xff0c;其實我們…

c++ std庫中的文件操作學習筆記

1. 概述 C標準庫提供了 頭文件中的幾個類來進行文件操作&#xff0c;這些類封裝了底層的文件操作&#xff0c;提供了面向對象和類型安全的接口&#xff0c;使得文件讀寫更加便捷和高效。主要的文件流類包括&#xff1a; std::ifstream&#xff1a;用于從文件中讀取數據。 st…

【網絡安全】SQL注入

如果文章不足還請各位師傅批評指正&#xff01; 想象一下&#xff0c;你經營著一家咖啡店&#xff0c;顧客可以通過店內的點單系統下單。這個系統會根據顧客的輸入&#xff0c;向后廚發送指令&#xff0c;比如“為顧客A準備一杯拿鐵”。 然而&#xff0c;如果有個不懷好意的顧客…

解決Mawell1.29.2啟動SQLException: You have an error in your SQL syntax問題

問題背景 此前在openEuler24.03 LTS環境下的Hive使用了MySQL8.4.2&#xff0c;在此環境下再安裝并啟動Maxwell1.29.2時出現如下問題 [ERROR] Maxwell: SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version f…