分布式唯一 ID 生成方案

在復雜分布式系統中,往往需要對大量的數據和消息進行唯一標識。如在美團點評的金融、支付、餐飲、酒店、貓眼電影等產品的系統中,數據日漸增長,對數據分庫分表后需要有一個唯一 ID 來標識一條數據或消息,數據庫的自增 ID 顯然不能滿足需求;特別一點的如訂單、騎手、優惠券也都需要有唯一 ID 做標識。此時一個能夠生成全局唯一ID 的系統是非常必要的。

Leaf——美團點評分布式ID生成系統

本文主要介紹一些常見的分布式唯一 ID 生成方案。

UUID(通用唯一識別碼)

UUID 是 Universally Unique Identifier 的縮寫,其目的是為了滿足在分布式系統中,各個節點可以獨立的生成唯一標識符,不需要依賴一個中心化的服務來分配 ID。相關設計最早在 1980 年代就已經提出,最終 2005 年在 RFC4122 中被完整定義。2024 年最新的 RFC 9562 發布,新增了 3 個新版本的 UUID 生成算法,取代了 RFC4122。

UUID 本身是一個長度為 128bit 的數字,通常用 32 位長度的 16 進制數字表示。因此其理論上的總數為 2^128,約等于 3.4 x 10^38。也就是說如果每納秒生成一萬個 UUID(每秒 10 萬億個),在完全隨機版本下,需要 1700 萬億年才能生成完所有的 UUID,妥妥的直到宇宙盡頭(宇宙預測壽命為 138 億年)。

在實際使用中,生成的 UUID 由 32 個字符和 4 個連字符表示,格式為 8-4-4-4-12,我們一般會在生成后將 - 給替換掉 UUID.randomUUID().toString().replaceAll("-","")

RFC 4122 中定義了 5 個版本的 UUID,每個版本的算法不同,應用范圍也不同,分別為:

  • Time-based UUID:基于時間的 UUID。通過本機 MAC 地址、時間戳以及a隨機數計算出 UUID,格式為 timestamp(60bit)-clock_seq(14bit)-MAC(48bit),另外還有 4bit 的 version 字段和 2 bit 的 variant 字段。因為使用了 MAC 地址,因此理論上絕對唯一,但 UUID 暴露了 MAC 地址,私密性不夠好。

  • DCE Security UUID:DCE安全的UUID。和版本一類似,但會將時間戳的前 4 位替換為 POSIX 的 UID 或 GID,實際很少使用。

  • UUID from names(MD5):基于名字的 UUID,通過 MD5(命名空間ID + 名稱) 計算出哈希值,該版本可以保證相同輸入產生相同輸出,但目前 MD5 已經不再安全,容易受到碰撞攻擊,現在推薦用 UUIDv5 替代。

  • truly random UUID:完全隨機 UUID。根據隨機數或者偽隨機數生成 UUID,這是使用最廣泛的版本,JDK 中實現的就是這個版本。

  • UUID from names(SHA1):UUIDv3 的升級版,通過 SHA1(命名空間ID + 名稱) 計算出哈希值,該版本可以保證相同輸入產生相同輸出,安全性相對較高。

RFC9562 又提出了三個新的版本,分別是:

  • Time-based UUID:對 UUIDv1 的升級,對時間戳進行了重排,將時間戳從高到低位有序排列,從而提高了數據庫索引性能。

  • Unix Epoch-based UUID:基于 Unix 時間戳的 UUID,使用當前時間戳(自 1970 年 1 月 1 日以來的毫秒數)作為 UUID 的前 48 位,整體格式為 timestamp(48bit)-version(4bit)-randomA(12bit)-variant(2bit)-randomB(62bit)。 Version7 是專為現代數據庫和分布式系統設計的、基于時間的 UUID 格式。它結合了時間戳和高質量的隨機數,從而實現了優秀的排序性和唯一性。

    如果開發者使用的語言生態已經支持 Version7,應該優先使用該版本。以筆者熟悉的 Java 和 Golang 為例,JDK 尚不支持 Version7,但已經有 uuid-creator和 java-uuid-generator 開源庫支持;Golang 方面 Google 官方的uuid 庫已經支持。

  • Custom UUID:自定義 UUID,一種實驗性質或供應商特定用途的 UUID,除了 version 和 variant 字段外,其余 122bit 可以自由定義。

下面是使用 Java 和 Golang 生成的 Version4 和 Version7 版本的 UUID 示例:

  • Golang 示例
package mainimport "github.com/google/uuid"func main() {uuidv4 := uuid.New()println("UUIDv4: " + uuidv4.String())uuidv7, _ := uuid.NewV7()println("UUIDv7: " + uuidv7.String())
}

輸出結果如下

UUIDv4: 496a53aa-e690-4d8f-bf77-316d294e2f81
UUIDv7: 01989e87-e56c-729b-a341-5faa691e4b24
  • Java 示例

import java.util.UUID;public class UUIDDemo {public static void main(String[] args) {//默認是版本 4,完全隨機 IDUUID uuid = UUID.randomUUID();// 替換 -System.out.println(uuid.toString().replaceAll("-",""));}
}

輸出結果如下

676a8fee6c1b48028dfc86e2bc35e4fe

數據庫自增 ID

一般在設計數據庫表時,一定會有一個 AUTO_INCREMENT=1 的 ID 字段,其本身就是一個表范圍的全局唯一 ID。但如果數據量達到一定量級,需要分庫分表時,生成的 ID 就會重復,此時一般需要設置自增 ID 的起始值和增長步長,比如 MySQL 提供了兩個字段進行設置:

  • auto_increment_offset:自增 ID 的起始值,默認是 1。
  • auto_increment_increment:自增 ID 的增長步長,默認是 1。

比如當通過分庫分表拆分為三個數據庫時,可以設置如下起始值和步長來實現全局自增 ID 唯一:

像數據庫的自增 ID、Redis 的 INCRINCRBY 命令,Zookeeper 的 Sequential 節點,都帶有自增屬性,因此都可以用來實現分布式唯一ID,但這些方案都會對中間件產生依賴。無論是使用的編碼復雜度,還是對中間件的高可用性要求,相比其他方案都會有一定的劣勢。

雪花算法

Snowflake(雪花算法) 是由 Twitter 提出的分布式唯一 ID 生成方案。其核心思想是將時間戳、機器 ID 和序列號結合在一起,生成一個 64 位的唯一 ID。

雪花算法的 ID 結構如下:

  • 1 個保留位,始終為 0。
  • 41 位時間毫秒時間戳,其可用年限大約為 69 年。
  • 10 位機器 ID,支持 1024 臺機器。還可以繼續細分, 5 位給 IDC,5 位給工作機器。
  • 12 位序列號,可以表示 2^12 = 4096 個數。因此雪花算法最大支持每毫秒生成 4096 個 ID。

基于以上字段分布,雪花算法可以每毫秒在一個數據中心的一臺機器上產生4096個有序的不重復的ID

不過因為是時間戳的原因,雪花算法在生成 ID 時需要考慮時鐘回撥的問題。如果系統時間發生回撥,可能會導致生成的 ID 重復。因此在使用雪花算法時,需要確保系統時間的準確性。Twitter 的官方實現并沒有對其做明確處理,只是簡單的報錯,這樣會導致分布式ID服務短期內不可用。后續的開源方案,像美團的 Leaf,百度的 UidGenerator 都對其做了優化,這也是比較常用的兩個開源庫,在實際工程中如果需要,可以在詳細調研后進行選型。

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

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

相關文章

飛算JavaAI賦能高吞吐服務器模擬:從0到百萬級QPS的“流量洪峰”征服之旅

引言:當“流量洪峰”來襲,如何用低代碼馴服高并發? 在數字化時代,從電商平臺的“雙11”大促到社交網絡的突發熱點事件,再到金融系統的實時交易高峰,服務器時刻面臨著**高吞吐量(High Throughput…

C#數據訪問幫助類

一.中文注釋using System; using System.Data; using System.Xml; using System.Data.SqlClient; using System.Collections;namespace Microsoft.ApplicationBlocks.Data.Ch {/// <summary>/// SqlServer數據訪問幫助類/// </summary>public sealed class SqlHelp…

B站 韓順平 筆記 (Day 21)

目錄 1&#xff08;面向對象高級部分練習題&#xff09; 1.1&#xff08;題1&#xff09; 1.2&#xff08;題2&#xff09; 1.3&#xff08;題3&#xff09; Vehicles接口類&#xff1a; Horse類&#xff1a; Boat類&#xff1a; Plane類&#xff1a; VehiclesFactory…

Linux(十四)——進程管理和計劃任務管理

文章目錄前言一、程序與進程的關系1.1 程序與進程的定義1.2 父進程與子進程二、查看進程信息2.1 ps 命令&#xff08;重點&#xff09;2.2 動態查看進程信息top命令&#xff08;重點&#xff09;2.3 pgrep命令查詢進程信息2.4 pstree命令以樹形結構列出進程信息三、進程的啟動方…

太陽光模擬器在無人機老化測試中的應用

在無人機技術飛速發展的當下&#xff0c;其戶外作業環境復雜多變&#xff0c;長期暴露在陽光照射下&#xff0c;部件老化問題日益凸顯&#xff0c;嚴重影響無人機的性能與壽命。紫創測控Luminbox專注于太陽光模擬器技術創新與精密光學測試系統開發&#xff0c;其涵蓋的 LED、鹵…

網絡原理-TCP_IP

1.UDP&#xff08;即用戶數據報協議&#xff09;UDP是一種無連接的傳輸層協議&#xff0c;提供簡單的、不可靠的數據傳輸服務。它不保證數據包的順序、可靠性或重復性&#xff0c;但具有低延遲和高效率的特點。UDP協議段格式16位UDP?度,表?整個數據報(UDP?部UDP數據)的最??…

GitHub Actions YAML命令使用指南

version: 2 updates:- package-ecosystem: "github-actions"directory: "/"schedule:interval: "weekly"這段代碼是 Dependabot 的配置文件&#xff08;通常放在 .github/dependabot.yml 中&#xff09;&#xff0c;它的作用是 自動化管理 GitHu…

決策樹算法學習總結

一、經典決策樹算法原理 &#xff08;一&#xff09;ID3 算法 核心思想&#xff1a;以 “信息增益” 作為劃分屬性的選擇標準&#xff0c;通過最大化信息增益來提升數據集的 “純度”。 關鍵概念 —— 信息增益&#xff1a;指某個屬性帶來的 “熵減”&#xff08;即純度提升量&…

內網安全——出網協議端口探測

在實戰中難免會遇到各種各樣的情況&#xff0c;其中對于目標主機是否出網這是一個十分值得收集的信息&#xff0c;因為完全不出網你就獲取不到主機了 端口 Linux 系統 對于 Linux 系統&#xff0c;探測其允許出網的端口&#xff0c;這里使用的是 Linux 的自帶命令&#xff0c;所…

C#WPF實戰出真汁13--【營業查詢】

1、營業查詢介紹本模塊是最后一個模塊&#xff0c;該板塊需要的功能有&#xff1a;營業數據列表&#xff0c;查詢數據&#xff0c;導出數據&#xff0c;數據統計。2、UI設計布局TabControl 是 WPF 中用于創建多頁標簽式界面的控件&#xff0c;常用于組織多個子內容區域。每個子…

基于 Java 和 MySQL 的精品課程網站

基于 Java 和 MySQL 的精品課程網站設計與實現一、 畢業設計&#xff08;論文&#xff09;任務書摘要&#xff1a;近年來&#xff0c;教育信息化發展十分迅猛&#xff0c;人們的教育觀念、教育手段、學習方法、學習渠道等等都發生了重大的變化。知識性人才也已經日益成為了一個…

全球首款 8K 全景無人機影翎 A1 發布解讀:航拍進入“先飛行后取景”時代

全球首款 8K 全景無人機影翎 A1 發布解讀&#xff1a;航拍進入“先飛行后取景”時代 特別說明&#xff1a;本文所有圖片素材來源于影翎官網 影翎官方介紹稱&#xff1a;“全球首款”是指截至 2025 年&#xff0c;A1 是首臺全面整合的全景無人機&#xff1a;無需外掛全景相機配件…

androidstudio內存大小配置

help->Edit Custom Vm option-Xmx8096m或者其他數值 改成-Xmx10240m然后設置里面的內存大小也要修改一下

vue3和elementPlus中的el-dropdown-menu中的背景樣式修改

1. 效果展示2. 代碼展示在el-dropdown-menu下加載類名,class"my-dropdown-menu"<el-dropdown-menu class"my-dropdown-menu"><el-dropdown-item :command"{ action: upgrade, data }">升級</el-dropdown-item><el-dropdown…

計算機網絡--HTTP協議

1. 什么是 HTTP 協議全稱&#xff1a;Hyper Text Transfer Protocol&#xff08;超文本傳輸協議&#xff09;作用&#xff1a;用于在服務器與客戶端&#xff08;通常是瀏覽器&#xff09;之間傳輸超文本數據&#xff08;如文字、圖片、視頻、音頻&#xff09;的應用層協議。工作…

Bee1.17.25更新Bug,完善功能.不支持NOSQL,分庫分表Sharding(2.X版有)

Bee 1.17.25 正常的ORM功能都有,但不支持NOSQL, 分庫分表Sharding; 若需要可使用2.X版. Bee, 接口簡單&#xff0c;功能齊全&#xff0c;性能好&#xff0c;支持原生分頁性能更高&#xff1b;還有分庫分表 (Sharding 分片) 功能&#xff0c;也支持 MongoDB ORM. Bee Hiberna…

RAG流程全解析:從數據到精準答案

Rag流程分析第一部分&#xff1a;數據處理與向量化 原始文檔進入系統&#xff0c;先經過格式識別&#xff0c;把 pdf、docx、pptx、掃描圖片等統一轉成文字流。文字流丟進分段器&#xff0c;按固定長度或語義邊界切成若干文本塊&#xff0c;每個塊再生成唯一 id。如果文檔里有表…

Matplotlib數據可視化實戰:Matplotlib圖表注釋與美化入門

圖表注釋與標簽&#xff1a;提升數據可視化效果 學習目標 通過本課程的學習&#xff0c;學員將掌握如何使用Matplotlib在圖表中添加文本注釋、圖例、標題和軸標簽&#xff0c;從而提高圖表的可讀性和信息傳達能力。本課程將通過實際案例&#xff0c;幫助學員理解每個元素的作用…

GitLab 安全漏洞 CVE-2025-7739 解決方案

本分分享極狐GitLab 補丁版本 18.2.2, 18.1.4, 18.0.6 的詳細內容。這幾個版本包含重要的缺陷和安全修復代碼&#xff0c;我們強烈建議所有私有化部署用戶應該立即升級到上述的某一個版本。對于極狐GitLab SaaS&#xff0c;技術團隊已經進行了升級&#xff0c;無需用戶采取任何…

C端高并發項目都有哪些

C端&#xff08;用戶端&#xff09;高并發項目通常涉及大規模用戶直接訪問的服務&#xff0c;其核心挑戰是如何在海量用戶同時請求下&#xff0c;保證系統的穩定性、高性能、高可用和一致性。以下是一些典型的C端高并發項目類型和具體案例&#xff1a;?核心類型與典型案例&…