當前位置:
首頁 > 最新 > 聊聊全局服務ID-Snowflake

聊聊全局服務ID-Snowflake

團隊文化:進取,分享,快樂,責任!

團隊願景:做最好的產品,打造有影響力的團隊!

一:前言

很多業務系統,都有生成一個記錄標示的需求,例如

1) 訂單標示:order-id

2) 醫生標示:doctor-id

3) 消息標示:message-id

業務往往都會根據這個記錄標示去查詢一條記錄信息。這就要求這個標示要就具有唯一性。如果作為MySql資料庫主鍵(針對大部分業務團隊資料庫MySql 引擎InnoDB)又要求這個唯一ID具有有序性(原因在此不贅述)。 由此可以看出全局服務ID的兩大核心要素:

1)全局唯一性

2)趨勢有序性(分散式系統中嚴格有序代價大)

二:常見做法

1.UUID

優點:

1)無需遠程調用,生成性能高

不足:

1) 無序、結構無規則

2) 長字元串作為主鍵、索引效率低下

這種做法基本上不被推薦(也因使用場景而定)

2.使用資料庫auto_increment 來生成全局唯一遞增ID

優點:

1) 利用資料庫自帶功能,簡單

2) 能保證唯一性、遞增性

不足:

1) 結構形式單一

例如:起始值 0,步長 1,產生id依次為0,1,2,3,4,5等,會暴露數據量(訂單量等)一些敏感信息。

2) 不易擴容

例如剛開始單庫,後期擴容為雙庫,那奇數或者偶數的id(或者取模,方式很多)會被移動到另一個庫中,如果以後在擴容,還要移動。

很多業務團隊也會在此思路基礎上進行變種改進

A)設置不同步長來進行資料庫水平擴容提高系統的高可用、高性能;

B)對ID進行結構規劃,前x位為時間戳,後y位為遞增數等等;

C)「一次提取多次使用」,在資料庫中只設置當前遞增數,讀取後可用遞增數保存到內存中。

團隊中的一些業務也在使用這種方式。

3.redis、zk、mongoDB等也可以生產全局ID,再此不詳細介紹。

4.Snowflake(雪花演算法,本文我想重點介紹的內容)

大部分開發者應該都知道Snowflake,它是Twitter開源的分散式ID生成演算法,結果是一個Long型的ID。其核心思想是:

除最高位可以不用外(以後可用來擴展),其他位均可自由浮動,自由組合。

我們團隊負責京東醫藥、互聯網醫療業務,業務中需要大量使用到唯一ID這種業務標示。年初的時候團隊一直想做一個統一的全局ID生成服務,後期經過調研,選擇了snowflake開發了GSI(global service id)系統,目前醫療業務(血糖儀項目)在嘗試使用中。

下圖為GSI設計思路:

9bit業務號能支持512種業務

4bit機器號能支持16台伺服器(GSI以JSF(京東內部RPC)形式對外提供服務)

20bit自增序列理論上單位時間內支持產生1048576個自增序列號

30bit秒級時間戳支持使用34年

① 內部採用JDK CAS演算法秒級單位內生成自增序列(棄用了synchronize,ReentrantLock(jdk1.8中對synchronize優化的也很好));

② 支持一次生成多個ID,業務調用方可以自己存在內存或緩存中;

③ 支持反解,

【備註:business表示業務號,machine表示機器號(注意機器號非機器ip),seq表示單位時間內自增序列號,time表示秒級時間戳】

不足:依賴機器時鐘,如果對機器時鐘回撥,會導致產生相同ID(正常情況不會出現此種情況)

技術服務於業務,只有最適合業務的技術才能體現出它的意義,我們不必糾結於那種更好,只要能滿足你的業務就ok,關於GSI的介紹就到這裡(後續考慮將GSI開源)


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 我就是程序員 的精彩文章:

閑談軟體開發

TAG:我就是程序員 |