服務化、分布式已成為當下系統開發的首選,高並行作業在資料存放區時,需要一套id產生器服務,來保證分布式情況下全域唯一性,以確保系統的訂單建立、交易支付等情境下資料的唯一性,否則將造成不可估量的損失。 基於時間戳記
比如流水號規則如下:XX-YYYYMMDD-N位隨機數,這也是企業級應用開發常用的規則。此流水號對人比較友好,可識別性高,但容量受後面隨機數的限制,且資料量越大,產生時難度越高。前三部分每天的流水號基本固定,後面的N位隨機數產生後,需要校正此前不存在,可依賴redis的set機制,每天的隨機數都寫到一個set集合中[set容易達42億之多,完全夠用],重建後要與set集合作比對,以確保其唯一性。一天內不重複,再結合確定日期來保證其唯一性。
N位隨機數產生時,可基於系統時間戳,再與一個大數模數產生。 UUID/GUID
最簡單直接暴力的方式,雖然能夠保證ID的唯一性,但是,它無法滿足業務系統需要的很多其他特性,例如:時間粗略有序性,可反解和可製造型。另外,UUID產生的時候使用完全的時間資料,效能比較差,並且UUID比較長,佔用空間大,間接導致資料庫效能下降,更重要的是,UUID並不具有有序性。系統容量較小的時候可以採用,變大後不建議採用此方式。 Vesta
GitHub 地址:https://github.com/robertleepeak/vesta-id-generator
Vesta是一款通用的ID產生器,互連網俗稱統一發號器,它具有全域唯一、粗略有序、可反解和可製造等特性,它支援三種發布模式:嵌入發布模式、中心伺服器發布模式、REST發布模式,根據業務的效能需求,它可以產生最大峰值型和最小粒度型兩種類型的ID,它的實現架構使其具有高效能,高可用和可伸縮等互連網產品需要的品質屬性,是一款通用的高效能的發號器產品。 提供4種應用部署方式,具體使用依情境而定: REST發布模式(Netty) REST發布模式(Tomcat) 中心伺服器發布模式 嵌入式發布模式 Twitter-Snowflake
GitHub 地址:https://github.com/twitter/snowflake
Twitter-Snowflake演算法產生的背景相當簡單,為了滿足Twitter每秒上萬條訊息的請求,每條訊息都必須分配一條唯一的id,這些id還需要一些大致的順序(方便用戶端排序),並且在分布式系統中不同機器產生的id必須不同。
snowflake的結構如下(用-分開): 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位為未使用,接下來的41位為毫秒級時間(41位的長度可以使用69年),然後是5位datacenterId和5位workerId(10位的長度最多支援部署1024個節點) ,最後12位是毫秒內的計數(12位的計數順序號支援每個節點每毫秒產生4096個ID序號)
一共加起來剛好64位,為一個Long型。(轉換成字串長度為18)
snowflake產生的ID整體上按照時間自增排序,並且整個分布式系統內不會產生ID碰撞(由datacenter和workerId作區分),並且效率較高。據說:snowflake每秒能夠產生26萬個ID。 基於redis的分布式ID產生器
GitHub 地址:https://github.com/hengyunabc/redis-id-generator
依賴redis的EVAL,EVALSHA兩個命令,利用redis的lua指令碼執行功能,在每個節點上通過lua指令碼產生唯一ID。 產生的ID是64位的: 使用41 bit來存放時間,精確到毫秒,可以使用41年。 使用12 bit來存放邏輯分區ID,最大分區ID是4095 使用10 bit來存放自增長ID,意味著每個節點,每毫秒最多可以產生1024個ID
Redis提供了TIME命令,可以取得redis伺服器上的秒數和微秒數。因些lua指令碼返回的是一個四元組。 second, microSecond, partition, seq
用戶端要自己處理,產生最終ID。 ((second * 1000 + microSecond / 1000) << (12 + 10)) + (shardId << 10) + seq;
在redis-id-generator-java目錄下,有example和benchmark代碼,提供了 Java用戶端產生模式,其它語言只要支援redis evalsha命令就可以了。 MongoDB的ObjectId
Mongodb集合中的每個document中都必須有一個"_id"鍵,這個鍵的值可以是任何類型的,在預設的情況下是個Objectid對象。mongodb的ObejctId生產思想在很多方面挺值得我們借鑒的,特別是在大型分布式的開發,如何構建輕量級的生產,如何將生產的負載進行轉移,如何以空間換取時間提高生產的最大最佳化等等。
網上有篇文章分析的還可以推薦給大家http://www.blogjava.net/dongbule/archive/2011/06/12/352138.html。