分布式ID生成器的解决方案总结
轉載自?分布式ID生成器的解決方案總結
在互聯(lián)網(wǎng)的業(yè)務系統(tǒng)中,涉及到各種各樣的ID,如在支付系統(tǒng)中就會有支付ID、退款ID等。那一般生成ID都有哪些解決方案呢?特別是在復雜的分布式系統(tǒng)業(yè)務場景中,我們應該采用哪種適合自己的解決方案是十分重要的。下面我們一一來列舉一下,不一定全部適合,這些解決方案僅供你參考,或許對你有用。
一個ID一般來說有下面幾種要素:
唯一性:確保生成的ID是全網(wǎng)唯一的。
有序遞增性:確保生成的ID是對于某個用戶或者業(yè)務是按一定的數(shù)字有序遞增的。
高可用性:確保任何時候都能正確的生成ID。
帶時間:ID里面包含時間,一眼掃過去就知道哪天的交易。
系統(tǒng)時間毫秒數(shù)
我們可以使用當前系統(tǒng)時間精確到毫秒數(shù)+業(yè)務屬性+用戶屬性+隨機數(shù)+...等參數(shù)組合形式來確保ID的唯一性,缺點是ID的有序性難以保證,要保證有序性就要依賴數(shù)據(jù)庫或者其他中間存儲媒介。
UUID
Java自帶的生成UUID的方式就能生成一串唯一隨機32位長度數(shù)據(jù),而且夠我們用N億年,保證唯一性肯定是不用說的了,但缺點是它不包含時間、業(yè)務數(shù)據(jù)可讀性太差了,而且也不能ID的有序遞增。
這是一種簡單的生成方式,簡單,高效,但在一般業(yè)務系統(tǒng)中我還沒見過有這種生成方式。
數(shù)據(jù)庫自增ID
我們都知道為數(shù)據(jù)庫主鍵設置自增序號,以一定的趨勢自增,以保證主鍵ID的唯一性。
這個方案很簡單,但最主要的問題在于依賴數(shù)據(jù)庫本身,這就無形增加了對數(shù)據(jù)庫的訪問壓力和依賴,一旦對單庫進行分庫分表或者數(shù)據(jù)遷移就尷尬了。
所以,這也不是合適的ID生成方法。
批量生成ID
一次按需批量生成多個ID,每次生成都需要訪問數(shù)據(jù)庫,將數(shù)據(jù)庫修改為最大的ID值,并在內(nèi)存中記錄當前值及最大值。這樣就避免了每次生成ID都要訪問數(shù)據(jù)庫并帶來壓力。
這種方案服務就是單點了,如果服務重啟勢必會造成ID丟失不連續(xù)的情況,而且這種方式也不利于水平擴展。
中間件
Redis的所有命令操作都是單線程的,本身提供像incr這樣的自增命令,所以能保證生成的ID肯定是唯一有序的。
這種方式不依賴關系數(shù)據(jù)庫,而且速度快。但系統(tǒng)要引入Redis這一中間件,增加維護成本,而且編碼和配置工作量比較大。即使已經(jīng)有了Redis組件,但生成ID的高頻率訪問對單線程的Redis性能勢必也會造成影響。
還可以利用像Zookeeper中的znode數(shù)據(jù)版本來生成序列號,及MongoDB的ObjectId等,這種利用中間件的做法不是很推薦。
snowflake算法
如上圖的所示,Twitter的snowflake算法下面幾部分組成:
41位的時間序列,精確到毫秒,可以使用69年
10位的機器標識,最多支持部署1024個節(jié)點
12位的序列號,支持每個節(jié)點每毫秒產(chǎn)生4096個ID序號,最高位是符號位始終為0。
這種方案性能好,在單機上是遞增的,但是由于涉及到分布式環(huán)境,每臺機器上的時鐘不可能完全同步,也許有時候也會出現(xiàn)不是全局遞增的情況。
而且這個項目在2010就停止維護了,但這個設計思路還是應用于其他各個ID生成器及變種。
UidGenerator
UidGenerator是百度開源的分布式ID生成器,基于于snowflake算法的實現(xiàn),看起來感覺還行。不過,國內(nèi)開源的項目維護性真是擔憂。
大家可以參考具體使用:
https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md
Leaf
Leaf是美團開源的分布式ID生成器,能保證全局唯一性、趨勢遞增、單調(diào)遞增、信息安全,里面也提到了幾種分布式方案的對比,但也需要依賴關系數(shù)據(jù)庫、Zookeeper等中間件。
具體可以參考官網(wǎng)說明:
https://tech.meituan.com/MT_Leaf.html
總結
以上是生活随笔為你收集整理的分布式ID生成器的解决方案总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音游《BanG Dream!少女乐团派对
- 下一篇: 什么是CPU密集型、IO密集型?