首選,不論是不是分佈式系統,都有 ID 惟一的使用場景。而在分佈式場景下,對 ID 的惟一性要求更嚴格!數據庫
常見的,咱們上淘寶買東西的訂單 ID,就是一種分佈式 ID。淘寶,前期的訂單 id 好像是 14 位,如今好像已是 16 位,或者 18 位了吧。安全
以咱們公司的訂單 ID 爲例,它有這幾個特色。微信
ID 全局惟一,不會重複 網絡
ID 的增加支持分佈式使用 架構
ID 要方便好記,而且經過 ID 能大概看出是什麼時間建立的訂單 app
訂單 ID 最好還能追蹤到銷售員,或下單用戶的 ID 等 框架
增加的訂單 ID 還不能讓競爭對手發現你天天的業務量 分佈式
針對第五項,淺顯的問題就是不能讓非核心運營者知道天天的訂單量等信息。若是 ID 是連續的,惡意用戶的扒取工做就很是容易作了,直接按照順序下載指定 URL 便可;若是是訂單號就更危險了,競對能夠直接知道咱們一天的訂單量。因此在一些應用場景下,會須要 ID 無規則、不規則。
因此,設計一個好的分佈式 ID 生成器並非那麼容易的。因而網上也有不少大公司開源這類分佈式 ID 生成器。我今天就抽個時間,扯一扯它們之間的不一樣點吧。
說到,分佈式 ID,咱們首選想到的可能就是 UUID 了。
UUID (Universally Unique Identifier) 的標準型式包含 32 個 16 進制數字,以連字號分爲五段,形式爲 8-4-4-4-12 的 36 個字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前爲止業界一共有 5 種方式生成 UUID。
UUID 的優勢:性能很是高:本地生成,沒有網絡消耗。
UUID 的缺點:
不易於存儲:UUID 太長,16 字節 128 位,一般以 36 長度的字符串表示,不少場景不適用。
信息不安全:基於 MAC 地址生成 UUID 的算法可能會形成 MAC 地址泄露,這個漏洞曾被用於尋找梅麗莎病毒的製做者位置。
ID 做爲主鍵時在特定的環境會存在一些問題,好比作 DB 主鍵的場景下,UUID 就很是不適用。MySQL 官方有明確的建議主鍵要儘可能越短越好,36 個字符長度的 UUID 不符合要求;UUID 還對 MySQL 索引不利,若是做爲數據庫主鍵,在 InnoDB 引擎下,UUID 的無序性可能會引發數據位置頻繁變更,嚴重影響性能。
snowflake 我就不在介紹了,我直接說它的優勢:
毫秒數在高位,自增序列在低位,整個ID都是趨勢遞增的。
不依賴數據庫等第三方系統,以服務的方式部署,穩定性更高,生成ID的性能也是很是高的。
能夠根據自身業務特性分配bit位,很是靈活。
缺點:
強依賴機器時鐘,若是機器上時鐘回撥,會致使發號重複或者服務會處於不可用狀態。
MongDB 的 ObjectID 能夠算做是和snowflake相似方法,經過「時間+機器碼+pid+inc」共12個字節,經過4+3+2+3的方式最終標識成一個24長度的十六進制字符。
支持多種不一樣模式的生成策略
號段模式:該模式須要建 DB 表, 須要有專門的服務來提供獲取 id 的接口, 存在網絡延遲
Snowflake 模式:爲了追求更高的性能,須要經過 RPC Server 來部署 Leaf 服務,那僅須要引入 leaf-core 的包,把生成 ID 的 API 封裝到指定的 RPC 框架中便可
缺點,可能就是相對來講比較複雜。
sharding-jdbc 是一個開源的主鍵生成組件。它的特色是簡單易用,能夠指定 workerId 或者不指定, 直接經過 jar 的方式引入便可。看它的名字就知道,它須要 DB 支持。
uid-generator 是百度開源的一個分佈式 ID 生成器。須要建 DB 表, 須要有專門的服務來提供獲取 id 的接口, 存在網絡延遲。
推薦閱讀:
分佈式事務之如何基於RocketMQ的事務消息特性實現分佈式系統的最終一致性?