1. 程式人生 > 程式設計 >分散式ID生成方案彙總

分散式ID生成方案彙總


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作為毫秒內序列號。 snowflake.png

優點
  • 毫秒數在高位,自增序列在低位,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