<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # :-: 分布式ID生成器解決方 ## 一、介紹 ### 1\. 什么情況下我們需要ID生成器 * 數據庫水平拆分的情況下,主鍵由于需要作為業務標識使用,需要唯一。 * 業務編號需要暴露給用戶,但是又不想被用戶猜到需要被隱藏的業務編號 * 業務編號需要體現業務信息,比如訂單分類訂單渠道等等 ### 2\. ID生成器設計目標 * 全局唯一 * 每秒可生成100W+ * 趨于遞增(對索引友好) * 高可用 * 可伸縮 ## 二、常見ID生成方案 ### 1\. UUID UUID 是 通用唯一識別碼(Universally Unique Identifier)的縮寫,是一種軟件建構的標準,亦為開放軟件基金會組織在分布式計算環境領域的一部分????UUID是由一組32位數的16進制數字所構成,是故UUID理論上的總數為1632=2128,約等于3.4 x 1038。也就是說若每納秒產生1兆個UUID,要花100億年才會將所有UUID用完。????UUID的標準型式包含32個16進制數字,以連字號分為五段,形式為8-4-4-4-12的32個字符。示例: 550e8400-e29b-41d4-a716-446655440000**每秒產生10億筆UUID,100年后只產生一次重復的機率是50%** * 優點: * 本地生成,沒有網絡消耗 * 可以任意水平擴展 * 生成效率高 * 生成節點不限 * 缺點 * 沒有排序,無法保證趨勢遞增。 * UUID往往是使用字符串存儲,查詢的效率比較低。 * 存儲空間比較大,如果是海量數據庫,就需要考慮存儲量的問題。 * 傳輸數據量大 * 不可讀 ### 2\. 數據庫自增列 可以通過設置bigint類型的數據庫自增列,在事務中通過Insert操作獲取主鍵Id * 優點 * 可以實現ID完全遞增 * 部署簡單,有DB就可以 * 缺點 * 生成效率差,取決于數據庫性能指標,每秒生成一萬ID都很難 * 依賴于數據庫,如果DB發生故障,在做主從切換的時候可能會引發BUG ### 3\. Redis生成ID 當使用數據庫來生成ID性能不夠要求的時候,我們可以嘗試使用Redis來生成ID。這主要依賴于Redis是單線程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY來實現。????????可以使用Redis集群來獲取更高的吞吐量。假如一個集群中有5臺Redis。可以初始化每臺Redis的值分別是1,2,3,4,5,然后步長都是5。各個Redis生成的ID為:A:1,6,11,16,21B:2,7,12,17,22C:3,8,13,18,23D:4,9,14,19,24E:5,10,15,20,25????????這個,隨便負載到哪個機確定好,未來很難做修改。但是3-5臺服務器基本能夠滿足器上,都可以獲得不同的ID。但是步長和初始值一定需要事先需要了。使用Redis集群也可以方式單點故障的問題。????????另外,比較適合使用Redis來生成每天從0開始的流水號。比如訂單號=日期+當日自增長號。可以每天在Redis中生成一個Key,使用INCR進行累加。 * 優點 * 不依賴于數據庫,靈活方便,且性能優于數據庫。 * 數字ID天然排序,對分頁或者需要排序的結果很有幫助。 * 缺點 * 如果系統中沒有Redis,還需要引入新的組件,增加系統復雜度。 * 需要編碼和配置的工作量比較大。 ### 4\. MongoDB的ObjectId MongoDB的ObjectId和snowflake算法類似。它設計成輕量型的,不同的機器都能用全局唯一的同種方法方便地生成它。MongoDB 從一開始就設計用來作為分布式數據庫,處理多個節點是一個核心要求。使其在分片環境中要容易生成得多。其格式如下:![](https://box.kancloud.cn/1e4a893f81e6ea1fb879b887d9d8a4c7_757x253.png)????????前4 個字節是從標準紀元開始的時間戳,單位為秒。時間戳,與隨后的5 個字節組合起來,提供了秒級別的唯一性。由于時間戳在前,這意味著ObjectId 大致會按照插入的順序排列。這對于某些方面很有用,如將其作為索引提高效率。這4 個字節也隱含了文檔創建的時間。絕大多數客戶端類庫都會公開一個方法從ObjectId 獲取這個信息。????????接下來的3 字節是所在主機的唯一標識符。通常是機器主機名的散列值。這樣就可以確保不同主機生成不同的ObjectId,不產生沖突。為了確保在同一臺機器上并發的多個進程產生的ObjectId 是唯一的,接下來的兩字節來自產生ObjectId 的進程標識符(PID)。????????前9 字節保證了同一秒鐘不同機器不同進程產生的ObjectId 是唯一的。后3 字節就是一個自動增加的計數器,確保相同進程同一秒產生的ObjectId 也是不一樣的。同一秒鐘最多允許每個進程擁有2563(16 777 216)個不同的ObjectId。 ### 5\. Twitter的snowflake算法 snowflake是Twitter開源的分布式ID生成算法,結果是一個long型的ID。其核心思想是:使用41bit作為毫秒數,10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID),12bit作為毫秒內的流水號(意味著每個節點在每毫秒可以產生 4096 個 ID),最后還有一個符號位,永遠是0。![](https://box.kancloud.cn/4f49804e02d591599ae3aac8f1f10e32_1021x346.png) | 分段 | 作用 | 說明 | | --- | --- | --- | | 1bit | 保留 | — | | 41bit | 時間戳,精確到毫秒 | 可以支持69年的跨度 | | 5bit | DatacenterId | 可以最多支持32個節點 | | 5bit | WorkerId | 可以最多支持32個節點 | | 12bit | 毫秒內的計數 | 支持每個節點每毫秒產生4096個ID | 理論上單機每秒400W+,最多每秒可以生成41億+的ID * 優點 * ID趨勢遞增 * 生成效率高,單機每秒400W+ * 支持線性擴充 * 穩定性高,不依賴DB等服務 * 缺點 * 依賴服務器時間,如果服務器時間發生回撥,可能導致生成重復ID * 在單機上是遞增的,但是由于涉及到分布式環境,每臺機器上的時鐘不可能完全同步,也許有時候也會出現不是全局遞增的情況
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看