分布式ID生成器

1. 背景

最近項(xiàng)目需要有分布式ID生成器這樣的組件,利用生成的ID作為表的主鍵而不是mysql的自增ID
查閱了一些網(wǎng)上的一些資料,針對(duì)性的思考,整理成文。

2. 組件要求

高可用

工業(yè)生產(chǎn)需要,比如單機(jī)掛了影響服務(wù)可不行

2.1 全局唯一

作為ID的特性

2.2 盡量保證ID遞增(并無(wú)嚴(yán)格要求)

查詢的時(shí)候有分頁(yè)或者排序類似的需求,如果主鍵ID本身能體現(xiàn)出時(shí)序效率會(huì)更

查詢的時(shí)候,往往有分頁(yè)或者排序的需求
1.可以給添加一個(gè)時(shí)間字段,并在其上建立普通索引
2.ID按照時(shí)間粗略有序

但是普通索引的訪問效率比聚集索引慢,所以傾向于方案2
但是做不到嚴(yán)格排序,因?yàn)橥蟾鱾€(gè)機(jī)器以master-slave形式交互,影響可用性以及QPS

2.3 其他

1.ID盡可能的短
減少存儲(chǔ)的空間以及增加查詢的效率,但是往往都按照64位來(lái)算就足夠
2.可用的時(shí)間足夠久
一些類SNOWFLAKE的算法會(huì)在64位的ID中利用部分位數(shù)(如41)代表時(shí)間戳,當(dāng)這部分時(shí)間戳的空間用完了,這個(gè)服務(wù)就不work了
3.容錯(cuò)性
假如一臺(tái)機(jī)器的時(shí)間機(jī)器被人工往前調(diào)了怎么辦
4.允許批量生成
允許業(yè)務(wù)方batch請(qǐng)求一次拿多個(gè)ID,提高效率
5.QPS盡可能高
類SNOWFLAKE算法會(huì)在64位ID中利用部分位數(shù)(如12)表示單位時(shí)間內(nèi)生成的ID序號(hào),這部分序號(hào)用完了,這個(gè)單位時(shí)間就不能再生成序號(hào)了

3.思路

3.1幾種方案

1.利用mysql表 主鍵ID auto_increment的特性
缺點(diǎn):主從同步,受限于主庫(kù)的寫入性能
2.UUID
缺點(diǎn):完全不保證遞增
3.獲取當(dāng)前時(shí)間
缺點(diǎn):不管時(shí)間是精確到秒還是微秒,都代表一個(gè)單位時(shí)間只能生成一個(gè)ID,無(wú)法滿足批量的請(qǐng)求
4.類SNOWFLAKE算法
本文主要針對(duì)該類算法進(jìn)行講解

3.2 SNOWFLAKE算法

先對(duì)SNOWFLAKE算法簡(jiǎn)單講解,參照下面的refer講解的


圖是抄來(lái)的

思路如下:

1.一個(gè)ID由64位生成
2.41bit作為時(shí)間戳,記錄當(dāng)前時(shí)間到標(biāo)記的起始時(shí)間(如到2018.1.1)差,精確到毫秒,那么服務(wù)可用時(shí)長(zhǎng)為(1<<41)/(1000* 60 * 60 * 24 *365) = 69.73年
3.10bit作為機(jī)器ID,也就是可以有1024臺(tái)機(jī)器
4.12bit作為序列號(hào),代表單位時(shí)間(這里是毫秒)內(nèi)允許生成的ID總數(shù),也就是1ms內(nèi)允許生成4096個(gè)ID

代碼可以直接參考refer

如何滿足分布式ID生成器的要求

高可用:1024臺(tái)機(jī)器互不影響的工作,單臺(tái)掛就掛
全局唯一:省略
盡量保證ID遞增:時(shí)間戳放在高位
可用時(shí)間長(zhǎng)度:69.73年
容錯(cuò)性:下面再探討
允許批量生成:同一單位時(shí)間(ms)內(nèi),最多允許生成4096個(gè)ID,支持批量
QPS盡可能高:在ID設(shè)計(jì)上,只能代表1ms最多允許有4096個(gè)ID生成,但實(shí)際用起來(lái),其實(shí)看代碼的設(shè)計(jì),并發(fā),鎖控制等等,

3.3 類SNOWFLAKE算法

SNOWFLAKE給出的主要是一個(gè)思想,把ID劃分為多個(gè)段,有不同的含義,可以結(jié)合自己的要求進(jìn)行重新劃分。按照個(gè)人理解,時(shí)間戳位數(shù)少了,機(jī)器位數(shù)多了,序列號(hào)位數(shù)多了。

3.3.1 時(shí)間 or 時(shí)間差

上面SNOWFLAKE算法是時(shí)間差來(lái)算的,也就是67.93年,換種思路,用絕對(duì)時(shí)間,要求位數(shù)開大一點(diǎn),不用每次都減去初始時(shí)間。
假設(shè)開到42位,精確到ms,那么就是 2^42=4398046511104,去https://currentmillis.com/ 查詢,夠用到2109年

3.3.2 單位時(shí)間的序號(hào)上限

SNOWFLAKE算法里面1ms最多允許有4096個(gè)ID生成。但是代碼實(shí)際執(zhí)行過(guò)程中,性能瓶頸以及現(xiàn)實(shí)場(chǎng)景要求,往往不會(huì)要求這么高的位數(shù),可以改成256個(gè),這樣就是QPS上限256000了(空間上允許,真正執(zhí)行還是取決于代碼效率),基本不會(huì)要求這么高。也就是序號(hào)需要8位就夠

3.3.3 工作機(jī)器個(gè)數(shù)

原算法支持1024臺(tái),當(dāng)然看各業(yè)務(wù)需求了,個(gè)人感覺4臺(tái)都?jí)蛄?,想?*256000=100w,1s生成100w個(gè)ID(還是那句話,QPS取決于代碼執(zhí)行效率),考慮機(jī)器掛掉以及代碼執(zhí)行性能,32臺(tái)也滿足大部分公司要求了。也就是5位ID給機(jī)器

3.3.4 拓展字段

上面一共42位(時(shí)間戳) + 8位(序列號(hào)) + 5位(機(jī)器ID) =55位,還有9位可以作為其他用途

標(biāo)志業(yè)務(wù)線
比如公司有A業(yè)務(wù)線,B業(yè)務(wù)線,xx,更有甚者是兩級(jí)的業(yè)務(wù)線A.a1業(yè)務(wù),A.a2業(yè)務(wù)。反正根據(jù)要求進(jìn)行一個(gè)映射,適合要求即可,假定這里分配32個(gè)業(yè)務(wù)線(5位)

3.3.5 保留字段

還剩下4位不知道有啥用,保留用吧。
有的文檔寫可以標(biāo)明機(jī)房ID,有的寫可以為后續(xù)業(yè)務(wù)拓展預(yù)留,比如32臺(tái)機(jī)器不夠用了要64臺(tái),比如1ms要512個(gè)ID了而不是256個(gè)ID
保留字段是用于這些未來(lái)發(fā)展可能要用的

4.方案討論

4.1 ID為何不能嚴(yán)格有序

因?yàn)楦鱾€(gè)機(jī)器保證不了時(shí)間同步,即使有NTP server,也保證不了ms內(nèi)各個(gè)機(jī)器同步

4.2 時(shí)間回退了怎么辦,比如人為修改了系統(tǒng)時(shí)間

每個(gè)機(jī)器記錄生成的最后一個(gè)ID,新生成ID的時(shí)候,拿當(dāng)前時(shí)間和最后一個(gè)ID解析出來(lái)的時(shí)間(高42位)進(jìn)行對(duì)比,不合理就報(bào)錯(cuò)

4.3 其他優(yōu)化

比如并發(fā)控制,CAS,鎖等,這里不展開代碼細(xì)節(jié)的討論

4.4 單機(jī)能生成全局唯一id嗎

不能,因?yàn)闆]有單機(jī)標(biāo)識(shí),無(wú)論時(shí)間戳,隨機(jī)數(shù),所有機(jī)器都是等價(jià)的
MAC地址有用嗎?有,但是MAC地址可以偽造,無(wú)法保證唯一
所以一定要有一個(gè)分布式集群統(tǒng)一分配機(jī)器編號(hào)來(lái)保證

5.總結(jié)

本文主要介紹了ID生成器的一些思路,并且對(duì)SNOWFLAKE方法進(jìn)行簡(jiǎn)單講解,從64位的構(gòu)成方式上進(jìn)行調(diào)整,進(jìn)行針對(duì)性的改動(dòng),適合自己的要求。來(lái)達(dá)到分布式ID生成器組件的各個(gè)要求。對(duì)于方案設(shè)計(jì)提出一些思路

refer

http://www.lxweimin.com/p/955909e1bd71 對(duì)于各種背景都有介紹
https://tech.meituan.com/MT_Leaf.html 美團(tuán)的實(shí)現(xiàn)
https://soulmachine.gitbooks.io/system-design/content/cn/distributed-id-generator.html
https://blog.csdn.net/u010372981/article/details/68924830 類snowflake的算法,代碼直白易懂

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,530評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,407評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,759評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,204評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,415評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,955評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,675評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

  • 這篇文章總結(jié)了分布式主鍵或者唯一鍵的生成算法,文章最后有我們基于snowflow算法的思考和實(shí)踐。 分布式主鍵的生...
    彥幀閱讀 2,709評(píng)論 0 5
  • MVC(Model-View-Controller)是最常見的軟件架構(gòu)之一,業(yè)界有著廣泛應(yīng)用。它本身很容易理解,但...
    鄭軍紅閱讀 357評(píng)論 0 0
  • 稻盛先生說(shuō),他也認(rèn)為具有何種“人格理念”,應(yīng)該屬于個(gè)人自由,人們可以自由地選擇自己的價(jià)值觀或“人格理念”。然而,你...
    武敬南閱讀 495評(píng)論 0 0
  • aaaa
    海闊天空_9fa0閱讀 321評(píng)論 0 0