Tinyid分佈式億級別ID生成系統-JAVA

Hello 同學們,在GitHub發現滴滴用Java開發的一款分佈式id生成系統,很實用集合了多種類型,支持多種場景,適用於中大型項目。已經測試過&發佈在個人測試平臺


喜歡的研究的同學可以看看
Demo:ShowDoc接口文檔
訪問密碼:tinyid
訪問地址:https://id.qekang.com

Tinyid簡介

Tinyid是用Java開發的一款分佈式id生成系統,基於數據庫號段算法實現,關於這個算法可以參考美團leaf或者tinyid原理介紹。Tinyid擴展了leaf-segment算法,支持了多db(master),同時提供了java-client(sdk)使id生成本地化,獲得了更好的性能與可用性。Tinyid在滴滴客服部門使用,均通過tinyid-client方式接入,每天生成億級別的id。

性能與可用性

性能

http方式訪問,性能取決於http server的能力,網絡傳輸速度
java-client方式,id爲本地生成,號段長度(step)越長,qps越大,如果將號段設置足夠大,則qps可達1000w+

可用性

依賴db,當db不可用時,因爲server有緩存,所以還可以使用一段時間,如果配置了多個db,則只要有1個db存活,則服務可用
使用tiny-client,只要server有一臺存活,則理論上可用,server全掛,因爲client有緩存,也可以繼續使用一段時間

Tinyid的特性

全局唯一的long型id
趨勢遞增的id,即不保證下一個id一定比上一個大
非連續性
提供http和java client方式接入
支持批量獲取id
支持生成1,3,5,7,9…序列的id
支持多個db的配置,無單點
適用場景:只關心id是數字,趨勢遞增的系統,可以容忍id不連續,有浪費的場景
不適用場景:類似訂單id的業務(因爲生成的id大部分是連續的,容易被掃庫、或者測算出訂單量)

依賴

JDK1.7+,maven,mysql, java client目前僅依賴jdk

示例

請參考getting start

推薦使用方式

tinyid-server推薦部署到多個機房的多臺機器
多機房部署可用性更高,http方式訪問需使用方考慮延遲問題
推薦使用tinyid-client來獲取id,好處如下:
id爲本地生成(調用AtomicLong.addAndGet方法),性能大大增加
client對server訪問變的低頻,減輕了server的壓力
因爲低頻,即便client使用方和server不在一個機房,也無須擔心延遲
即便所有server掛掉,因爲client預加載了號段,依然可以繼續使用一段時間 注:使用tinyid-client方式,如果client機器較多頻繁重啓,可能會浪費較多的id,這時可以考慮使用http方式
推薦db配置兩個或更多:
db配置多個時,只要有1個db存活,則服務可用 多db配置,如配置了兩個db,則每次新增業務需在兩個db中都寫入相關數據

tinyid的原理

tinyid是基於數據庫發號算法實現的,簡單來說是數據庫中保存了可用的id號段,tinyid會將可用號段加載到內存中,之後生成id會直接內存中產生。
可用號段在第一次獲取id時加載,如當前號段使用達到一定量時,會異步加載下一可用號段,保證內存中始終有可用號段。
(如可用號段11000被加載到內存,則獲取id時,會從1開始遞增獲取,當使用到一定百分比時,如20%(默認),即200時,會異步加載下一可用號段到內存,假設新加載的號段是10012000,則此時內存中可用號段爲2001000,10012000),當id遞增到1000時,當前號段使用完畢,下一號段會替換爲當前號段。依次類推。
tinyid系統架構圖
Code架構
在這裏插入圖片描述
下面是一些關於這個架構圖的說明:

  • nextId和getNextSegmentId是tinyid-server對外提供的兩個http接口
  • nextId是獲取下一個id,當調用nextId時,會傳入bizType,每個bizType的id數據是隔離的,生成id會使用該bizType類型生成的IdGenerator。
  • getNextSegmentId是獲取下一個可用號段,tinyid-client會通過此接口來獲取可用號段
    IdGenerator是id生成的接口
  • IdGeneratorFactory是生產具體IdGenerator的工廠,每個biz_type生成一個IdGenerator實例。通過工廠,我們可以隨時在db中新增biz_type,而不用重啓服務
  • IdGeneratorFactory實際上有兩個子類IdGeneratorFactoryServer和IdGeneratorFactoryClient,區別在於,getNextSegmentId的不同,一個是DbGet,一個是HttpGet
  • CachedIdGenerator則是具體的id生成器對象,持有currentSegmentId和nextSegmentId對象,負責nextId的核心流程。nextId最終通過AtomicLong.andAndGet(delta)方法產生。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章