分散式ID生成方案彙總
阿新 • • 發佈:2020-06-24
1、目標
1.1、全域性唯一
不能出現重複的ID,全域性唯一是最基本的要求。
1.2、趨勢有序
業務上分頁查詢需求,排序需求,如果ID直接有序,則不必建立更多的索引,增加查詢條件。 而且Mysql InnoDB儲存引擎主鍵使用聚集索引,主鍵有序則寫入效能更高。
1.3、高可用
ID是一條資料的唯一標識,如果ID生成失敗,則影響很大,業務執行不下去。所以好的ID方案需要有高可用。
1.4、資訊保安
ID雖然趨勢有序,但是不可以被看出規則,免得被爬取資訊。 瞭解到一個有意思的事情:基於MAC地址生成UUID的演演算法造成的MAC地址洩露,這個漏洞曾被用於尋找梅麗莎病毒的製作者位置。
2、常見方案介紹
2.1、UUID
UUID(Universally Unique Identifier)是最簡單的生成方案了:
UUID.randomUUID().toString()
複製程式碼
生成形如:e811b49b-9ac1-47dc-8ab9-98fa7dd861d0的8-4-4-4-12的字串。
優點
- 簡單
- 效能好
- 全球唯一
缺點
- 無序
- 不能標識出此ID的含義,不可讀。
- 字串太長且無序,作為MySQL主鍵,影響效能。
2.2、snowflake方案
snowflake是twitter開源的分散式ID生成演演算法,核心思想是:一個Long型別的ID,其中41bit作為毫秒數,10bit作為機器碼,12bit作為毫秒內序列號。
優點
- 毫秒數在高位,自增序列在低位,ID趨勢遞增。
- 以服務方式部署,可以做高可用。
- 根據業務分配bit位,靈活。
缺點
- 每臺機器的時鐘不同,當時鍾回撥可能會發生重複ID。
- 當資料量大時,需要對ID取模分庫分表,在跨毫秒時,序列號總是歸0,會發生取模後分佈不均衡。
2.3、基於資料庫Flickr方案
這個方案的思路時採用了MySQL自增長ID的機制(auto_increment auto_increment_offset)。
通過使用以下SQL獲取不同的ID:
begin;
REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
commit;
複製程式碼
在分散式系統中,多部署幾臺Mysql,每臺機器的初始值不同,步數與機器數量相等。 假設部署N臺機器,步數為N,每臺機器初始值依次為:0、1、2