Snowflake 算法的實現

snowflake(雪花算法)是一個開源的分布式 ID 生成算法,結果是一個 long 型的 ID。snowflake 算法將 64bit 劃分為多段,分開來標識機器、時間等信息,具體組成結構如下圖所示:
在這里插入圖片描述
snowflake 算法的核心思想是使用 41bit 作為毫秒數,10bit 作為機器的 ID(比如其中 5 個 bit 可作為數據中心,5 個 bit 作為機器 ID),12bit 作為毫秒內的流水號(意味著每個節點在每毫秒可以產生 4096 個 ID),最后還有一個符號位,永遠是 0。snowflake 算法可以根據自身業務的需求進行一定的調整。比如估算未來的數據中心個數,每個數據中心內的機器數,以及統一毫秒內的并發數來調整在算法中所需要的 bit 數。snowflake 算法的優勢是穩定性高,不依賴于數據庫等第三方系統;使用靈活方便,可以根據業務需求的特性來調整算法中的 bit 位;單機上 ID 單調自增,毫秒數在高位,自增序列在低位,整個 ID 是趨勢遞增的。而其也存在一定的缺陷,包括強依賴機器時鐘,如果機器上時鐘回撥,會導致發號重復或者服務處于不可用狀態;ID 可能不是全局遞增,雖然 ID 在單機上是遞增的,但是由于涉及到分布式環境下的每個機器節點上的時鐘,可能會出現不是全局遞增的場景。

#pragma once#include <chrono>
#include <mutex>
#include <stdexcept>class Snowflake
{public:Snowflake(uint64_t datacenter_id, uint64_t machine_id) : datacenter_id_(datacenter_id), machine_id_(machine_id){if (datacenter_id > kMaxDatacenterId || machine_id > kMaxMachineId){throw std::invalid_argument("Datacenter ID or Machine ID exceeds maximum value");}}uint64_t Generate(){std::lock_guard<std::mutex> lock(mutex_);uint64_t current_timestamp = GetCurrentTimestamp();if (current_timestamp < last_timestamp_){throw std::runtime_error("Clock moved backwards. Refusing to generate ID.");}if (current_timestamp == last_timestamp_){sequence_ = (sequence_ + 1) & kMaxSequence;if (sequence_ == 0){current_timestamp = WaitNextMillis(current_timestamp);}}else{sequence_ = 0;}last_timestamp_ = current_timestamp;return ((current_timestamp - kEpoch) << kTimestampShift) | (datacenter_id_ << kDatacenterIdShift) |(machine_id_ << kMachineIdShift) | sequence_;}private:uint64_t GetCurrentTimestamp() const{return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();}uint64_t WaitNextMillis(uint64_t last_timestamp) const{uint64_t timestamp = GetCurrentTimestamp();while (timestamp <= last_timestamp){timestamp = GetCurrentTimestamp();}return timestamp;}private:uint64_t datacenter_id_;       // 數據中心IDuint64_t machine_id_;          // 機器IDuint64_t sequence_ = 0;        // 序列號uint64_t last_timestamp_ = 0;  // 上次生成ID的時間戳// 配置參數static constexpr uint64_t kSequenceBits = 12;     // 序列號占用位數static constexpr uint64_t kMachineIdBits = 5;     // 機器ID占用位數static constexpr uint64_t kDatacenterIdBits = 5;  // 數據中心ID占用位數// 最大值計算static constexpr uint64_t kMaxSequence = (1ULL << kSequenceBits) - 1;static constexpr uint64_t kMaxMachineId = (1ULL << kMachineIdBits) - 1;static constexpr uint64_t kMaxDatacenterId = (1ULL << kDatacenterIdBits) - 1;// 位移量static constexpr uint64_t kMachineIdShift = kSequenceBits;                      // 機器ID左移位數static constexpr uint64_t kDatacenterIdShift = kSequenceBits + kMachineIdBits;  // 數據中心ID左移位數static constexpr uint64_t kTimestampShift = kSequenceBits + kMachineIdBits + kDatacenterIdBits;  // 時間戳左移位數// 起始時間(2020-01-01 00:00:0 UTC)static constexpr uint64_t kEpoch = 1577836800000ULL;std::mutex mutex_;
};

使用示例:

#include <iostream>#include "Snowflake.h"int main()
{try{Snowflake snowflake(1, 1);  // 數據中心ID=1,機器ID=1for (int i = 0; i < 10; ++i){std::cout << snowflake.Generate() << std::endl;}}catch (const std::exception& e){std::cerr << "Error: " << e.what() << std::endl;}return 0;
}

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

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

相關文章

C 語言中, scanf 函數在哪些情況下會結束輸入讀取:

在 C 語言中&#xff0c; scanf 函數在以下幾種情況下會結束輸入讀取&#xff1a; &#xff1a; 1. 遇到指定格式匹配失敗&#xff1a; scanf 按照格式字符串要求讀取輸入。當輸入數據格式與格式字符串不匹配時&#xff0c;就會結束讀取。例如 scanf(“%d”, &num) 要求輸…

括號合法題

一、括號合法題 2116. 判斷一個括號字符串是否有效 //采用從左往右和從右往左遍歷的貪心算法&#xff0c;分別保證前綴合法&#xff0c;后綴合法。public boolean canBeValid(String s, String locked) {int ns.length();if (n%21) return false;int num0;// 從左到右掃描&…

圖生生AI商品圖:一鍵更換商品,保留原背景

圖生生AI商品圖工具&#xff0c;推出 “更換商品”功能&#xff0c;只需上傳一張參考圖和自己的商品圖&#xff0c;AI自動完成商品替換&#xff0c;保留原背景&#xff0c;3秒生成專業級電商圖&#xff01;無需PS技能&#xff0c;無需復雜操作&#xff0c;真正實現 “一鍵換商品…

[7-01-03].SpringBoot3集成MinIo

MinIO學習大綱 一、Spingboot整合MinIo 第1步&#xff1a;搭建SpringBoot項目&#xff1a; 第2步&#xff1a;引入minio依賴 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&q…

Gradle Project import Eclipse

Gradle Project import Eclipse

一些SQL優化經驗(非添加索引版)

SQL 優化核心策略 偽代碼示例&#xff0c;現實比這個復雜 1. 子查詢優化 (1) 避免低效的 IN 和 NOT IN 問題&#xff1a; NOT IN 可能導致全表掃描&#xff0c;尤其是子查詢結果集較大時。 優化方案&#xff1a; 替換為 LEFT JOIN&#xff1a; -- 原查詢&#xff08;低效&am…

<項目> 高并發服務器的HTTP協議支持

目錄 HTTP模塊 模塊劃分與介紹 模塊實現 Util模塊 HTTPRequest模塊 HTTPResponse模塊 HTTPContext模塊 ParseHttpLine RecvHttpLine RecvHttpHead ParseHttpHead RecvHttpBody 對外接口 HttpServer模塊 OnConnected OnMessage Route IsFileHandler FileHandler Dispatcher …

基于Spring Boot + Vue的銀行管理系統設計與實現

基于Spring Boot Vue的銀行管理系統設計與實現 一、引言 隨著金融數字化進程加速&#xff0c;傳統銀行業務向線上化轉型成為必然趨勢。本文設計并實現了一套基于Spring Boot Vue的銀行管理系統&#xff0c;通過模塊化架構滿足用戶、銀行職員、管理員三類角色的核心業務需求…

微軟提出 Logic-RL:基于規則的強化學習釋放大語言模型推理能力

? 更多 LLM 架構文章點擊查看&#xff1a; LLM 架構專欄 大模型架構專欄文章閱讀指南 1. AI 智能體&#xff0c;顛覆還是賦能&#xff1f;一文讀懂&#xff01; 2. 1W8000 字 解鎖 AI 高效運作密碼&#xff1a;工作流與智能體如何協同&#xff1f; 3. 萬字深度剖析 AI 代理&am…

STM32八股【1】-----啟動流程和startup文件理解

啟動流程 知識點 MCU 上電復位。MSP從向量表第0個地址讀取一個32位&#xff08;2字節&#xff09;的值并保存&#xff0c;該值為棧頂地址。PC計數器從第1個地址讀取一個兩字節的值并保存&#xff0c;該值為程序入口&#xff0c;一般是Reset_Handler。想了解FLASH地址映射可以…

詳解c++20的協程,自定義可等待對象,生成器詳解

協程 c20的協程三大標簽&#xff1a;“性能之優秀”&#xff0c;“開發之靈活”&#xff0c;“門檻之高” 在講解c的協程使用前&#xff0c;我們需要先明白協程是什么&#xff0c;協程可以理解為用戶態的線程&#xff0c;它需要由程序來進行調度&#xff0c;如上下文切換與調…

JavaEE企業級開發 延遲雙刪+版本號機制(樂觀鎖) 事務保證redis和mysql的數據一致性 示例

提醒 要求了解或者熟練掌握以下知識點 spring 事務mysql 臟讀如何保證緩存和數據庫數據一致性延遲雙刪分布式鎖并發編程 原子操作類 前言 在起草這篇博客之前 我做了點功課 這邊我寫的是一個示例代碼 數據層都寫成了 mock 的形式(來源于 JUnit5) // Dduo import java.u…

A2 最佳學習方法

記錄自己想法的最好理由是發現自己的想法&#xff0c;并將其組織成可傳播的形式 (The best reason for recording what one thinks is to discover what one thinks and to organize it in transmittable form.) Prof Ackoff 經驗之談&#xff1a; 做培訓或者寫文章&#xff…

嵌入式硬件工程師從小白到入門-PCB繪制(二)

PCB繪制從小白到入門&#xff1a;知識點速通與面試指南 一、PCB設計核心流程 需求分析 明確電路功能&#xff08;如電源、信號處理、通信&#xff09;。確定關鍵參數&#xff08;電壓、電流、頻率、接口類型&#xff09;。 原理圖設計 元器件選型&#xff1a;匹配封裝、電壓、…

vue創建子組件步驟及注意事項

在 Vue 中創建子組件需要遵循組件化開發的核心原則&#xff0c;并注意數據流、通信機制、復用性等關鍵點。以下是詳細步驟和注意事項&#xff0c;結合代碼示例說明&#xff1a; 一、創建子組件的步驟 1. 定義子組件 創建一個 .vue 文件&#xff08;單文件組件&#xff09;&am…

Cocos Creator版本發布時間線

官網找不到&#xff0c;DeepSeek給的答案&#xff0c;這里做個記錄。 Cocos Creator 1.x 系列 發布時間&#xff1a;2016 年 - 2018 年 1.0&#xff08;2016 年 3 月&#xff09;&#xff1a; 首個正式版本&#xff0c;基于 Cocos2d-x 的 2D 游戲開發工具鏈&#xff0c;集成可…

【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——功能優化:用戶鑒權主體功能開發

系列文章目錄 【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——完整項目&#xff08;含完整前端后端代碼&#xff09;【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——代碼逐行精講&#xff1a;核心ChatClient對象相關構造函數【Spring AI】基于專屬知識庫的R…

【AI神經網絡】深度神經網絡(DNN)技術解析:從原理到實踐

引言 深度神經網絡&#xff08;Deep Neural Network, DNN&#xff09;作為人工智能領域的核心技術&#xff0c;近年來在計算機視覺、自然語言處理、醫療診斷等領域取得了突破性進展。與傳統機器學習模型相比&#xff0c;DNN通過多層非線性變換自動提取數據特征&#xff0c;解決…

目標跟蹤——deepsort算法詳細闡述

deepsort 算法詳解 Unmatched Tracks(未匹配的軌跡) 本質角色: 是已存在的軌跡在當前幀中“失聯”的狀態,即預測位置與檢測結果不匹配。 生命周期階段: 已初始化: 軌跡已存在多幀,可能攜帶歷史信息(如外觀特征、運動模型)。 未被觀測到: 當前幀中未找到對應的檢測框…

Vue-admin-template安裝教程

#今天配置后臺管理模板發現官方文檔的鏡像網站好像早失效了&#xff0c;自己稍稍總結了一下方法# 該項目環境需要node17及以下&#xff0c;如果npm install這一步報錯可能是這個原因 git clone https://github.com/PanJiaChen/vue-admin-template.git cd vue-admin-template n…