全局唯一ID生成服務設計

一般在一些支撐大規模複雜業務中,都會有生成全局唯一的業務ID的訴求,本文就此ID生成服務的訴求來展開

業務訴求

在實際業務系統中,一般會對ID生成服務有哪些要求,下面我們簡單介紹幾點

全局唯一:在限制周內必須保證不能重複
系統高可用:在特殊情況下 盡最大可能保證系統可用
高併發高性能:此類基礎服務,支持業務衆多,一般調用量都比較大,同時要求性能很高
使用簡單:在當下的大環境中一般提供一個RPC服務輸出
可讀性: 比如是否需要攜帶業務含義,是否遞增,是否需要控制增長步長(指定週期根據首尾值若步長固定則可以推算業務量)等待

設計方案

1、自然遞增
2、隨機數+重複檢驗
3、分段組裝 把一段ID分成多段,每一段代表不同的含義,如設備 時間等等

實施落地

自然遞增

這種方式實現簡單在實際業務中應用相對比較少。 實現簡單,可以支持一些要求較少的業務,無法攜帶任何指定含義,且容易被利用推斷業務規模等

最簡單,風險也最高的實現 啓動一臺服務器 使用AtomicInteger 的incrementAndGet生成自增ID,單機內存級,性能最好,效率最高,但是這類方式缺點也多例如 每次系統重啓之後都要重新開始
基於上面的情況,我們可以考慮,記錄下來最後生成的數據,以此作爲系統重啓初始化的起點。記錄的方式有很多種比如不斷更新redis的同一個KEY 等,但是這種情況下 記錄失敗後是快速失敗呢還是默認成功呢。這個就要看具體情況而定了,個人傾向於快速失敗,默認成功會肯會造成全局不唯一的情況發生。
當然了上面描述的這類的方案的話的性能可能會被本次操作中記錄最大生成ID的方式所影響,也有可能會因此降低吞吐量 ,使得支持的瓶頸變大
另外一種方式就是簡單粗暴的依賴數據庫的自增ID來搞,這種情況100%保證了數據的持久化,但過於依賴數據庫,性能和災備等方面比較差

隨機數+重複檢驗

這種方式是我剛開始在內心吐槽自然遞增會有被動暴露業務規則等的一系列不足的時候,思考的一種方式, 簡單聊聊此類方案的落地實現設想。看完之後你會發現 設想也就是個設想
分三步走 首先 引擎隨機生成一個新的ID ,然後在存儲介質如數據庫中檢查當前ID是否存在,如果存在則重頭開始,如果不存在則進度第三步 把生成的ID存儲到數據庫中ID排他設計,防止系統併發插入同一個ID。
這種系統有個致命的缺點就是要存儲所有已生成的有效ID,這就造成了存存ID的數據量過於龐大。以JD商城交易業務爲例,我們假設一分鐘發生的總交易量爲5000單,我們可以計算下一年的總單量爲50006024365≈26億 ,另外同比我們大概預算下物流單量以一旦2件物品兩個物流單號來說 ,本年度需要支持的業務量就將近80億,假如隨着業務發展每年的單量翻倍 ,業務上線三年之後,我們的支持的總量將480億 這麼看,這真的不是一個小數字呀。 另外假如我們隨機生成一個ID需要1ns,檢查一次需要0.1ms 這種性能在我看來絕對是相當好了,但是我們再做一個假設,我們ID的有1000億的總量 這大概是10位的純數字組合的極限了吧,在已生成量將近500億的時候,我們的ID重複率也將近50%了 ,也就是說我們運氣不好的時候有可能要檢查250億次,才能生產出一個新的ID ,250億0.1ms =250WS≈29天 這個性能估計能讓任何一個研發人員目瞪口呆了吧 而且這還不算數據量過大之後對存儲介質的性能影響
想想也就僅僅存在於想想了,在上面算了一筆賬之後,我簡直驚呆了,突然意識到,任何時候都要有一顆敬畏的心啊,如上的方案假如真的在某個地方的生產環境運行了,如果沒有一些配套的方式來控制ID重複率和已產出ID總量的話,那麼隨着時間的推移,這無疑是一種災難。

分段組裝

這種方式據我瞭解,應該在業界使用相對比較廣泛比如經典的snowflake算法生成64位的ID,我們先簡單聊一下這類設計的思想,我個人感覺這類設計與現在互聯網中廣泛使用的IP地址類似,均採用分段設計,分層次管理,自上而下,只要高位不同,那地位可以隨意組合,基於不同的高位組合出來的ID必然不會相同,利用這一特性,我們可以更爲靈活的按需設計。

簡單設計一個16位的ID生成器,來支撐QPS 1W TP99 1MS 的一個服務
使用1-3 前三位標記提供服務的集羣中的機器所在編碼 實際使用10臺
使用4-9 中間6位標記作爲年度的分鐘計數器 3652460=525600
餘下10-16 餘下6位 使用自增漲格式化000001 單服務提供QPS 1000 使用RateLimit 等限流工具控制系統的流量情況在日常流量的5倍作爲閾值即可

每臺機器的自增漲均使用該機器的集羣分配編號作爲啓動步長理論上 改設計默認可以支持集羣規模爲000-999 1000臺機器
以最大集羣我們可以推斷單機增長量爲999999/999=1001 單機每分鐘 自增漲1000以內就不會重複

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章