精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為什么需要分布式ID?求一種分布式ID生成方案

jf_ro2CN3Fa ? 來源:CSDN ? 2023-01-09 10:43 ? 次閱讀

1. 為什么需要分布式 ID

對于單體系統來說,主鍵 ID 常用主鍵自動的方式進行設置。這種 ID 生成方法在單體項目是可行的,但是對于分布式系統,分庫分表之后就不適應了。比如訂單表數據量太大了,分成了多個庫,如果還采用數據庫主鍵自增的方式,就會出現在不同庫 id 一致的情況,雖然是不符合業務的。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

2. 業務系統對分布式 ID 有什么要求

全局唯一性 :ID 是作為唯一的標識,不能出現重復;

趨勢遞增 :互聯網比較喜歡 MySQL 數據庫,而 MySQL 數據庫默認使用 InnoDB 存儲引擎,其使用的是聚集索引,使用有序的主鍵 ID 有利于保證寫入的效率;

單調遞增 :保證下一個 ID 大于上一個 ID,這種情況可以保證事務版本號,排序等特殊需求實現;

信息安全 :前面說了 ID 要遞增,但是最好不要連續。如果 ID 是連續的,容易被惡意爬取數據,指定一系列連續的,所以 ID 遞增但是不規則是最好的。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

3. 分布式 ID 生成方案

UUID

數據庫自增

號段模式

Redis 實現

雪花算法(SnowFlake)

百度 Uidgenerator

美團 Leaf

滴滴 TinyID

3.1 UUID

UUID (Universally Unique Identifier),通用唯一識別碼的縮寫。

UUID 的標準型式包含 32 個 16 進制數字,以連字號分為五段,形式為 8-4-4-4-12 的 36 個字符,示例 863e254b-ae34-4371-87da-204b71d46a7b。

UUID 理論上的總數為 1632=2128,約等于 3.4 x 10^38。

優點 :性能非常高,本地生成的,不依賴于網絡

缺點 :不易存儲。16 字節 128 位,36 位長度的字符串信息不安全,基于 MAC 地址生成 UUID 算法可能會造成 MAC 地址泄露,暴露使用者的位置。UUID 的無序性可能會引起數據位置頻繁變動,影響性能。

3.2 數據庫自增

在分布式環境也可以使用 MySQL 自增實現分布式 ID 的生成。如果分庫分表了,當然不是簡單地設置好 auto_increment_increment 和 auto_increment_offset 就行。在分布式系統中,我們可以多部署幾臺機器,每臺機器設置不同的初始值,且步長和機器數相等。

比如有兩臺機器,設置步長 step 為 2。Server1 的初始值為 1(1, 3, 5, 7, 9, 11…),Server2 的初始值為 2(2, 4, 6, 8, 10…)。

這是 Flickr 團隊在 2010 年撰文介紹的一種主鍵生成策略(Ticket Servers: Distributed Unique Primary Keys on the Cheap )。

假設有 N 臺機器,step 就要設置為 N,如下圖進行設置:

b76d92b8-7dff-11ed-8abf-dac502259ad0.png

這種方案看起來是可行的。但是如果要擴容,步長 step 等要重新設置。假如只有一臺機器,步長就是 1,比如 1,2,3,4,5,6。這時候如果要進行擴容,就要重新設置。機器 2 可以挑一個偶數的數字,這個數字在擴容時間內,數據庫自增達不到這個數的,然后步長就是 2。機器 1 要重新設置 step 為 2,然后還是以一個奇數開始進行自增。這個過程看起來不是很雜,但是如果機器很多的話,那就要花很多時間去維護重新設置。

這種實現的缺陷:

ID 沒有了單調遞增的特性,只能趨勢遞增。有些業務場景可能不符合;

數據庫壓力還是比較大,每次獲取 ID 都需要讀取數據庫,只能通過多臺機器提高穩定性和性能。

3.3 號段模式

這種模式也是現在生成分布式 ID 的一種方法。實現思路是,會從數據庫獲取一個號段范圍,比如 [1,1000],生成 1 到 1000 的自增 ID 加載到內存中。

建表結構如下:

CREATETABLEid_generator(
idint(10)NOTNULL,
max_idbigint(20)NOTNULLCOMMENT'當前最大id',
stepint(20)NOTNULLCOMMENT'號段的布長',
biz_typeint(20)NOTNULLCOMMENT'業務類型',
versionint(20)NOTNULLCOMMENT'版本號',
PRIMARYKEY(`id`)
)

biz_type :不同業務類型;

max_id :當前最大的 id;

step :代表號段的步長;

version :版本號,就像 MVCC 一樣,可以理解為樂觀鎖。

等 ID 都用完了,再去數據庫獲取,然后更改最大值:

updateid_generatorsetmax_id=#{max_id+step},version=version+1whereversion=#{version}andbiz_type=XXX

優點 :有比較成熟的方案,像百度 Uidgenerator,美團 Leaf;

缺點 :依賴于數據庫實現。

3.4 Redis 實現

Redis 分布式 ID 實現主要是通過提供像 INCR 和 INCRBY 這樣的自增原子命令。由于 Redis 單線程的特點,可以保證 ID 的唯一性和有序性。

這種實現方式,如果并發請求量上來后,就需要集群。不過集群后,又要和傳統數據庫一樣,設置分段和步長。

優點 :Redis 性能相對比較好,而且可以保證唯一性和有序性;

缺點 :需要依賴 Redis 來實現,系統需要引入 Redis 組件。

3.5 雪花算法(SnowFlake)

雪花算法(Snowflake)是由 Twitter 開源的分布式 ID 生成算法,以劃分命名空間的方式將 64-bit 位分割成多個部分,每個部分代表不同的含義。在 Java 中 Long 類型是 64 位的,所以 Java 程序中一般使用 Long 類型存儲。

b7912b92-7dff-11ed-8abf-dac502259ad0.jpg

第一部分:第一位占用 1 bit,始終是 0,是一個符號位,不使用;

第二部分:第 2 位開始的 41 位是時間戳。41-bit 位可表示 241 個數,每個數代表毫秒,那么雪花算法可用的時間年限是 (241)/(1000606024365)=69 年的時間;

第三部分:10-bit 位可表示機器數,即 2^10 = 1024 臺機器。通常不會部署這么多臺機器;

第四部分:12-bit 位是自增序列,可表示 2^12 = 4096 個數。覺得一毫秒個數不夠用也可以調大點。

優缺點:

優點 :雪花算法生成的 ID 是趨勢遞增,不依賴數據庫等第三方系統。生成 ID 的效率非常高,穩定性好,可以根據自身業務特性分配 bit 位,比較靈活;

缺點 :雪花算法強依賴于機器時鐘 。如果機器上時鐘回撥,會導致發號重復或者服務會處于不可用狀態。如果恰巧回退前生成過一些 ID,而時間回退后,生成的 ID 就有可能重復。

3.6 百度 Uidgenerator

百度 UidGenerator 是百度開源基于 Java 語言實現的唯一 ID 生成器,是在雪花算法 Snowflake 的基礎上做了一些改進。

引用官網的解釋:

UidGenerator 是 Java 實現的, 基于 Snowflake 算法的唯一 ID 生成器。UidGenerator 以組件形式工作在應用項目中,支持自定義 workerId 位數和初始化策略,從而適用于 docker 等虛擬化環境下實例自動重啟、漂移等場景。在實現上, UidGenerator 通過借用未來時間來解決 sequence 天然存在的并發限制;采用 RingBuffer 來緩存已生成的 UID,并行化 UID 的生產和消費,同時對 CacheLine 補齊。避免了由 RingBuffer 帶來的硬件級「偽共享」問題. 最終單機 QPS 可達 600 萬。

b7b2308a-7dff-11ed-8abf-dac502259ad0.png

Snowflake 算法描述:指定機器 & 同一時刻 & 某一并發序列,是唯一的。據此可生成一個 64 bits 的唯一 ID(long)。默認采用上圖字節分配方式:

sign(1bit):固定 1bit 符號標識,即生成的 UID 為正數;

delta seconds (28 bits):當前時間,相對于時間基點"2016-05-20"的增量值,單位:秒,最多可支持約8.7年;

worker id (22 bits):機器 id,最多可支持約 420 萬次機器啟動。內置實現為在啟動時由數據庫分配,默認分配策略為用后即棄,后續可提供復用策略;

sequence (13 bits):每秒下的并發序列,13 bits 可支持每秒 8192 個并發。

詳細介紹可參考官網說明:

ttps://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

3.7 美團 Leaf

Leaf 這個名字是來自德國哲學家、數學家萊布尼茨的一句話:There are no two identical leaves in the world “世界上沒有兩片相同的樹葉”

Leaf 提供兩種生成的 ID 的方式:號段模式(Leaf-segment)和 Snowflake 模式(Leaf-snowflake)。你可以同時開啟兩種方式,也可以指定開啟某種方式,默認兩種方式為關閉狀態。

Leafsegment 數據庫方案

其實就是前面介紹的號段模式的改進,可以引用美團技術博客的介紹:

第一種 Leaf-segment 方案,在使用數據庫的方案上,做了如下改變:

原方案每次獲取 ID 都得讀寫一次數據庫,造成數據庫壓力大。改為利用 proxy server 批量獲取 ,每次獲取一個 segment(step 決定大小)號段的值。用完之后再去數據庫獲取新的號段,可以大大減輕數據庫的壓力;

各個業務不同的發號需求用 biz_tag 字段來區分,每個 biz-tag 的 ID 獲取相互隔離,互不影響。如果以后有性能需求需要對數據庫擴容,不需要上述描述的復雜的擴容操作,只需要對 biz_tag 分庫分表就行。

表結構設計:

>+-------------+--------------+------+-----+-------------------+-----------------------------+
|Field|Type|Null|Key|Default|Extra|
+-------------+--------------+------+-----+-------------------+-----------------------------+
|biz_tag|varchar(128)|NO|PRI|||
|max_id|bigint(20)|NO||1||
|step|int(11)|NO||NULL||
|desc|varchar(256)|YES||NULL||
|update_time|timestamp|NO||CURRENT_TIMESTAMP|onupdateCURRENT_TIMESTAMP|
+-------------+--------------+------+-----+-------------------+-----------------------------+

Leafsnowflake 方案

Leafsnowflake 是在雪花算法上改進來的,引用官網技術博客介紹:

Leaf-snowflake 方案完全沿用 Snowflake 方案的 bit 位設計,即是“1+41+10+12”的方式組裝 ID 號。對于 workerID 的分配,當服務集群數量較小的情況下,完全可以手動配置。Leaf 服務規模較大,手動配置成本太高。所以使用 Zookeeper 持久順序節點的特性自動對 Snowflake 節點配置 wokerID。

Leaf-snowflake 是按照下面幾個步驟啟動的:

啟動 Leaf-snowflake 服務,連接 Zookeeper,在 leaf_forever 父節點下檢查自己是否已經注冊過(是否有該順序子節點);

如果有注冊過直接取回自己的 workerID(Zookeeper 順序節點生成的int類型ID號),啟動服務;

如果沒有注冊過,就在該父節點下面創建一個持久順序節點。創建成功后取回順序號當做自己的 workerID 號,啟動服務。

b7d0c270-7dff-11ed-8abf-dac502259ad0.png

這種方案解決了前面提到的雪花算法的缺陷。官網沒解釋,不過 Leafsnowflake 對其進行改進,官網的流程圖。

b7fb31cc-7dff-11ed-8abf-dac502259ad0.jpg

3.8 滴滴 Tinyid

Tinyid 是用 Java 開發的一款分布式 ID 生成系統,基于數據庫號段算法實現。Tinyid 擴展了 leaf-segment 算法,支持了多數據庫和 tinyid-client。

Tinyid 也是基于號段算法實現,系統實現圖如下:

b8202fcc-7dff-11ed-8abf-dac502259ad0.png

優點 :方便集成,有成熟的方案和實現;

缺點 :依賴 DB 穩定性,需要采用集群主從備份的方式提高 DB 可用性。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • MYSQL數據庫
    +關注

    關注

    0

    文章

    95

    瀏覽量

    9382
  • UUID
    +關注

    關注

    0

    文章

    22

    瀏覽量

    8109
  • Redis
    +關注

    關注

    0

    文章

    371

    瀏覽量

    10846

原文標題:分布式 ID 生成方案總結整理

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    分布式光纖測溫解決方案

    分布式光纖測溫解決方案
    的頭像 發表于 11-12 01:02 ?85次閱讀
    <b class='flag-5'>分布式</b>光纖測溫解決<b class='flag-5'>方案</b>

    分布式光纖測溫是什么?應用領域是?

    分布式光纖測溫是一種先進的溫度測量技術,它利用光纖的拉曼散射原理進行溫度監測。以下是對分布式光纖測溫的詳細介紹: 、基本原理 分布式光纖測
    的頭像 發表于 10-24 15:30 ?225次閱讀
    <b class='flag-5'>分布式</b>光纖測溫是什么?應用領域是?

    分布式光伏發電有哪些優點?分布式光伏發電有哪些應用形式?

    分布式光伏發電是一種在用戶附近或用電現場配置的小型光伏發電系統,它具有許多顯著的優點和多樣的應用形式。
    的頭像 發表于 04-29 17:44 ?3946次閱讀

    什么是分布式架構?

    分布式架構是指將個系統或應用拆分成多個獨立的節點,這些節點通過網絡連接進行通信和協作,以實現共同完成任務的一種架構模式。這種架構模式旨在提高系統的可擴展性、可靠性和性能表現。
    的頭像 發表于 01-12 15:04 ?1167次閱讀
    什么是<b class='flag-5'>分布式</b>架構?

    分布式鎖的三實現方式

    分布式鎖的三實現方式? 分布式鎖是在分布式系統中用于實現對共享資源進行訪問控制的一種機制。分布式
    的頭像 發表于 12-28 10:01 ?859次閱讀

    鴻蒙原生應用開發——分布式數據對象

    01、什么是分布式數據對象 在可信組網環境下,多個相互組網認證的設備將各自創建的對象加入同個 sessionId,使得加入的多個數據對象之間可以同步數據,也就是說,當某數據對象屬性發生
    發表于 12-08 10:01

    分布式系統硬件資源池原理和接入實踐

    體驗。 2.1 消費者場景 在消費者層面,華為分布式硬件支持智慧辦公,智慧出行等多種創新場景。例如智慧辦公場景中,使用套 PC 鍵鼠即可和周邊平板等設備跨設備操作,使用到鍵鼠外設的跨設備操控能力;多
    發表于 12-06 10:02

    redis分布式鎖的缺點

    Redis分布式鎖是一種常見的用于解決分布式系統中資源爭用問題的解決方案。盡管Redis分布式鎖具有很多優點,但它也存在
    的頭像 發表于 12-04 14:05 ?1208次閱讀

    淺析Redis 分布式鎖解決方案

    Redis 分布式鎖解決方案一種基于Redis實現的分布式鎖機制,可以確保在分布式環境中對共享資源的訪問進行同步控制,避免出現競態條件和數
    的頭像 發表于 12-04 14:00 ?464次閱讀

    redis分布式鎖可能出現的問題及解決方案

    Redis分布式鎖是一種常見的解決分布式系統中并發問題的方案。雖然Redis分布式鎖具有許多優點,但也存在
    的頭像 發表于 12-04 11:29 ?917次閱讀

    如何實現Redis分布式

    Redis是個開源的內存數據存儲系統,可用于高速讀寫操作。在分布式系統中,為了保證數據的致性和避免競態條件,常常需要使用分布式鎖來對共享
    的頭像 發表于 12-04 11:24 ?664次閱讀

    redis分布式鎖三個方法

    Redis是一種高性能的分布式緩存和鍵值存儲系統,它提供了一種可靠的分布式鎖解決方案。在分布式
    的頭像 發表于 12-04 11:22 ?1412次閱讀

    redis分布式鎖的應用場景有哪些

    Redis分布式鎖是一種基于Redis實現的分布式鎖機制,可以在分布式環境下確保資源的獨占性,避免并發訪問時的數據爭用問題。下面將詳細介紹Redis
    的頭像 發表于 12-04 11:21 ?1396次閱讀

    zookeeper分布式原理

    Zookeeper是個開源的分布式協調服務,可以用于構建高可用、高性能的分布式系統。它提供了個簡單且高效的層次命名空間,可以用來存儲配置信息、狀態信息、命名服務等。Zookeepe
    的頭像 發表于 12-03 16:33 ?622次閱讀

    springcloud 分布式事務解決方案實例

    Spring Cloud是套用于構建分布式系統的開發工具集,可以用于解決分布式系統中的各種問題,包括分布式事務。在分布式系統中,由于業務邏
    的頭像 發表于 12-03 16:32 ?1102次閱讀