問題 如何在分布式集群中生成全域性唯一的ID?

2021-09-25 03:38:38 字數 982 閱讀 8632

方法一:uuid

uuid是通用唯一識別碼 (universally unique identifier),在其他語言中也叫guid,可以生成乙個長度32位的全域性唯一識別碼。

//e493a18e-61d0-499a-87c1-650d03735edb

string uuid = uuid.randomuuid().tostring()12

uuid可以保證全域性唯一,但是占用32位有些太長,而且是無序的,入庫時效能較差。

眾所周知,關係型資料庫的索引大都是b+樹的結構,拿id欄位來舉例,索引樹的每乙個節點都儲存著若干個id。 

如果我們的id按遞增的順序來插入,比如陸續插入8,9,10,新的id都只會插入到最後乙個節點當中。當最後乙個節點滿了,會裂變出新的節點。這樣的插入是效能比較高的插入,因為這樣節點的**次數最少,而且充分利用了每乙個節點的空間。 

但是,如果我們的插入完全無序,不但會導致一些中間節點產生**,也會白白創造出很多不飽和的節點,這樣大大降低了資料庫插入的效能。

方法二:資料庫自增主鍵

為了提高效能,在分布式系統中可以用db proxy請求不同的分庫,每個分庫設定不同的初始值,步長和分庫數量相等:這樣一來,db1生成的id是1,4,7,10,13….,db2生成的id是2,5,8,11,14…..

id的生成對資料庫嚴重依賴,不僅影響效能,而且資料庫一旦掛掉,服務不可用。

方法三:snowflake演算法

snowflake所生成的id一共分成四部分:

第一位:占用1bit,其值始終是0,沒有實際作用。

時間戳:占用41bit,精確到毫秒,總共可以容納約140年的時間。

工作機器id:占用10bit,其中高位5bit是資料中心id(datacenterid),低位5bit是工作節點id(workerid),做多可以容納1024個節點。

序列號:占用12bit,這個值在同一毫秒同一節點上從0開始不斷累加,最多可以累加到4095。

同一毫秒可以生成1024*4096個id。

面試官 如何在分布式場景下生成全域性唯一 ID?

在分布式系統中,有一些場景需要使用全域性唯一 id 可以和業務場景有關,比如支付流水號,也可以和業務場景無關,比如分庫分表後需要有乙個全域性唯一 id,或者用作事務版本號 分布式鏈路追蹤等等,好的全域性唯一 id 需要具備這些特點 那麼分布式場景下有哪些生成唯一 id 的方案呢?先說最容易理解的方案...

分布式系統全域性id生成策略

1 不能有單點故障 2 全域性id生成服務不能成為整個系統效能瓶頸 3 全域性id要和shardingid有對映關係,根據全域性主鍵id能算出資料在哪個分片 4 不能太長,否則,作為主鍵建立索引查詢效率低 flickr開發團隊在2010年撰文介紹了flickr使用的一種主鍵生成策略,flickr這一...

分布式全域性ID生成方案

1 背景 分布式架構下,唯一序列號生成是我們在設計乙個系統,尤其是資料庫使用分庫分表的時候常常會遇見的問題。當分成若干sharding表後,如何能夠快速拿到乙個唯一序列號,是經常遇到的問題。在網際網路的業務系統中,涉及到各種各樣的id,如在支付系統中就會有支付id 退款id等。那一般生成id都有哪些...