你想了解一線大廠的分布式唯一ID生成方案嗎

2021-09-25 03:00:49 字數 3740 閱讀 3353

前言uuid

mysql主鍵自增

mysql多例項主鍵自增

雪花演算法

redis生成方案

總結懸念

分布式系統中我們會對一些資料量大的業務進行分拆,如:使用者表,訂單表。因為資料量巨大一張表無法承接,就會對其進行分庫分表。小夥伴們可以去看一下老顧的以前的文章你知道怎麼分庫分表嗎?如何做到永不遷移資料和避免熱點嗎?

如何永不遷移資料和避免熱點? 根據伺服器指標分配資料量(揭秘篇)

但一旦涉及到分庫分表,就會引申出分布式系統中唯一主鍵id的生成問題永不遷移資料和避免熱點的文章中要求需要唯一id的特性

1、整個系統id唯一

2、id是數字型別,而且是趨勢遞增的

3、id簡短,查詢效率快

什麼是趨勢遞增?如:在一段時間內,生成的id是遞增的趨勢。如:再一段時間內生成的id在【0,1000】之間,過段時間生成的id在【1000,2000】之間。但在【0-1000】區間內的時候,id生成有可能第一次是12,第二次是10,第三次是14。

那有什麼方案呢?往下看

這個方案是小夥伴們第乙個能過考慮到的方案

優點:

1、**實現簡單。

2、本機生成,沒有效能問題

3、因為是全球唯一的id,所以遷移資料容易

缺點:

1、每次生成的id是無序的,無法保證趨勢遞增

2、uuid的字串儲存,查詢效率慢

3、儲存空間大

4、id本事無業務含義,不可讀

應用場景:

1、類似生成token令牌的場景

2、不適用一些要求有趨勢遞增的id場景

此uuid方案是不適用老顧的需求

這個方案就是利用了mysql的主鍵自增auto_increment,預設每次id加1。

優點:

1、數位化,id遞增

2、查詢效率高

3、具有一定的業務可讀

缺點:

1、存在單點問題,如果mysql掛了,就沒法生成id了

2、資料庫壓力大,高併發抗不住

這個方案就是解決mysql的單點問題,在auto_increment基本上面,設定step步長

每台的初始值分別為1,2,3...n,步長為n(這個案例步長為4)

優點:解決了單點問題

缺點:一旦把步長定好後,就無法擴容;而且單個資料庫的壓力大,資料庫自身效能無法滿足高併發

應用場景:資料不需要擴容的場景

此方案也不滿足老顧的需求,因為不方便擴容(記住這個方案,嘿嘿)

這個演算法網上介紹了很多,老顧這裡就不詳細介紹。雪花演算法生成64位的二進位制正整數,然後轉換成10進製的數。64位二進位制數由如下部分組成:

優點:

1、此方案每秒能夠產生409.6萬個id,效能快

2、時間戳在高位,自增序列在低位,整個id是趨勢遞增的,按照時間有序遞增

3、靈活度高,可以根據業務需求,調整bit位的劃分,滿足不同的需求

缺點:

1、依賴機器的時鐘,如果伺服器時鐘回撥,會導致重複id生成

在分布式場景中,伺服器時鐘回撥會經常遇到,一般存在10ms之間的回撥;小夥伴們就說這點10ms,很短可以不考慮吧。但此演算法就是建立在毫秒級別的生成方案,一旦回撥,就很有可能存在重複id。

此方案暫不符合老顧的需求(嘿嘿,看看怎麼優化這個方案,小夥伴們先記住)

利用redis的incr原子性操作自增,一般演算法為:

年份 + 當天距當年第多少天 + 天數 + 小時 + redis自增

優點:有序遞增,可讀性強

缺點:占用頻寬,每次要向redis進行請求

整體測試了這個效能如下:

需求:同時10萬個請求獲取id

1、併發執行完耗時:9s左右

2、單任務平均耗時:74ms

3、單執行緒最小耗時:不到1ms

4、單執行緒最大耗時:4.1s

效能還可以,如果對效能要求不是太高的話,這個方案基本符合老顧的要求

但不完全符合業務老顧希望id從 1 開始趨勢遞增。(當然演算法可以調整為 就乙個 redis自增,不需要什麼年份,多少天等)。

如果今天老顧就介紹以上幾個方案,其實沒有必要,網上多的是

一線大廠的分布式id方案絕沒有這個簡單,他們對高併發,高可用的要求很高

如redis方案中,每次都要去redis去請求,有網路請求耗時,併發強依賴了redis。這個設計是有風險的,一旦redis掛了,整個系統不可用

這樣的話競爭對手 第一天中午12點下個訂單,就可以看到平台的訂單id是多少,第二天中午12點再下一單,又平台訂單id到多少。這樣就可以猜到平台1天能產生多少訂單了,這個是絕對不允許的,公司絕密啊。

老顧提示一下,很多方案的實現,一線大廠的設計思路其實和小夥伴們思路差不多,只是多想了1~2層,設計上面多了1~2個環節

redis自增,但是怕redis掛了丟失一秒的持久化,重啟redjs就會重複。 我們用的是當前毫秒值乘以10000,再去redis中自增,有效期1秒。加這個毫秒值就是了。 缺點就是一秒只能併發9999個。但是用於我們的系統來說足夠了

Redis原子計數器incr分布式唯一id生成器

在複雜分布式系統中,往往需要對大量的資料和訊息進行唯一標識。如在美團點評的金融 支付 餐飲 酒店 貓眼電影等產品的系統中,資料日漸增長,對資料庫的分庫分表後需要有乙個唯一id來標識一條資料或訊息,資料庫的自增id顯然不能滿足需求 特別一點的如訂單 騎手 優惠券也都需要有唯一id做標識。此時乙個能夠生...

常見的分布式唯一ID方案

最近看乙個新系統,發現裡面有很多場景用到唯一id,便蒐羅了一下常見的方案。對於分布式id,需要滿足下面的基本要求 全域性唯一 趨勢遞增 uuid universally unique identifier 全域性唯一識別符號,定義為乙個字串主鍵,採用32位數字組成,編碼採用16進製制,定義了在時間和...

js生成唯一id 常見的分布式系統唯一ID生成方案

系統唯一id是我們在設計乙個系統的時候常常會遇見的問題,也常常為這個問題而糾結。生成id的方法有很多,適應不同的場景 需求以及效能要求。所以有些比較複雜的系統會有多個id生成的策略。下面就介紹一些常見的id生成策略。最常見的方式。利用資料庫,全資料庫唯一。優點 1 簡單,方便,效能可以接受。2 數字...