還在用數(shù)據(jù)庫自增ID做主鍵壳嚎?建議了解一下雪花算法生成的分布式ID

前言

隨著業(yè)務的發(fā)展毫胜,單一數(shù)據(jù)庫的自增ID已經(jīng)不能滿足我們的需求,使用全局唯一ID的場景必然會出現(xiàn)诬辈,比如海量的訂單號酵使,檔案號等等。我們初始可能會選擇使用36位的UUID焙糟,配合機器id和時間戳口渔,基本可以滿足需求。

但是UUID的缺點也很明顯穿撮,由于其完全無序缺脉,對MySQL的B+樹結(jié)構(gòu)特別不友好。另外UUID的長度也會造成數(shù)據(jù)庫索引空間的浪費悦穿。

由此產(chǎn)生的需求

  1. 全局唯一:不能重復攻礼,這是最基本的要求。
  2. 趨勢遞增:生成的ID是有序遞增的栗柒,這樣數(shù)據(jù)庫存儲索引數(shù)據(jù)時可以保證寫入性能礁扮。
  3. 信息安全:生成的ID不能是簡單連續(xù)遞增的,必須是大致遞增。如果是連續(xù)的太伊,那么惡意用戶可以很簡單地爬取我們的數(shù)據(jù)雇锡;而對于訂單號這種敏感的數(shù)據(jù),競爭對手更是可以輕松推算出我們一天的單量僚焦。

解決方案:雪花算法

雪花算法(Snowflake)是Twitter開源的一種生成分布式全局唯一ID的算法锰提,產(chǎn)生的背景是為了滿足Twitter每秒上萬條消息的請求,這些消息為了不重復必須有一個全局唯一的ID芳悲,并且還需要有大致的順序立肘,以滿足存儲性能要求及客戶端排序。

其默認生成結(jié)果是一個64bit的long型數(shù)值名扛,組成部分包含時間戳谅年,并且保持了大致遞增。

雪花算法核心結(jié)構(gòu)

image

如圖所示罢洲,組成一共包含4個部分:

  1. 不使用:1bit踢故,最高位bit默認為0,不使用惹苗;
  2. 時間戳:41bit殿较,毫秒級的時間戳,可以支持該算法使用到2082年桩蓉;建議使用64位Linux系統(tǒng)機器淋纲,通過vdso,gettimeofday()在用戶態(tài)就可以完成操作院究,減少了進入內(nèi)核態(tài)的損耗洽瞬。
  3. 機器標識:10bit可以支持1024臺機器,通常會將其拆分為兩部分业汰,5bit代表數(shù)據(jù)中心ID伙窃,5bit代表工作機器ID。
  4. 序列號:12bit遞增序列號样漆,就是一系列的自增id为障,每秒最多生成4096個不重復的ID。

通過這4部分放祟,雪花算法可以在1秒內(nèi)生成約409萬個ID鳍怨,已經(jīng)基本滿足絕大部分的業(yè)務需求署咽。

由于雪花算法生成的ID是大致遞增的客扎,非常契合MySQL中B+樹的結(jié)構(gòu),應用到數(shù)據(jù)庫的主鍵時卧蜓,可以極大的提升插入效率眉撵。

另外由于其是大致遞增侦香,而不是順序遞增落塑,直接將生成結(jié)果作為如訂單號這樣的業(yè)務字段也沒問題,可以保證第三方無法推斷出真實的訂單量鄙皇。

雪花算法生成ID重復的問題及解決方案

雖然雪花算法通過不同的組成盡量避免了ID重復芜赌,但是在某些極限情況下仰挣,依然無法排除ID重復的發(fā)生伴逸。

  • 情況1:時鐘回撥,雪花算法強依賴機器時鐘膘壶,如果機器上時鐘回撥错蝴,會造成發(fā)號重復。
  • 情況2:在某一毫秒內(nèi)颓芭,某些節(jié)點上的機器標識一致顷锰,并且產(chǎn)生了同一個序列號。

針對情況1亡问,我們可以維護一個上次生產(chǎn)ID的時間戳lastTimestamp官紫,每次發(fā)號后更新lastTimestamp,發(fā)號前則對比當前時間戳和lastTimestamp州藕,當前時間戳比lastTimestamp小束世,就強制等待兩者時間差后再發(fā)號,但這會造成發(fā)號服務處于不可用的狀態(tài)床玻。

針對情況2毁涉,既然時間戳和序列號我們無法保證不重復,那就從機器標識下手锈死。只要機器標識不重復贫堰,生成的ID自然也不會重復了。如果我們的項目部署是機器級別待牵,即一臺機器上部署一套服務其屏,那以機器MAC地址作為機器標識就可以。如果是進程級別缨该,即一臺機器上部署多套相同的服務偎行,僅僅是PID不同,這種情況下可以通過引入Redis压彭、Zookeeper或者MySQL來保證機器標識位的唯一性睦优。

國內(nèi)開源的分布式ID框架

對于雪花算法可能重復的問題,國內(nèi)也有一些開源的框架作為替代壮不,比如MT的leaf汗盘、BD的Uid。

總得來說询一,雪花算法已經(jīng)可以滿足絕大部分場景隐孽,如果沒有十分必要的話癌椿,還是不建議引入開源方案,畢竟會大大增加我們系統(tǒng)的復雜度菱阵。

總結(jié)

本文主要講解了什么是雪花算法踢俄,雪花算法適用的場景以及如何解決雪花算法沖突的問題。

當然雪花算法也不是萬能的晴及,不能適用所有的場景都办,建議大家根據(jù)實際的業(yè)務進行評估,然后選擇合適的方案虑稼。

?

學習技術(shù)琳钉,分享技術(shù),期待與大家共同進步蛛倦,也感謝您的點贊與關(guān)注歌懒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市溯壶,隨后出現(xiàn)的幾起案子及皂,更是在濱河造成了極大的恐慌,老刑警劉巖且改,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件验烧,死亡現(xiàn)場離奇詭異,居然都是意外死亡钾虐,警方通過查閱死者的電腦和手機噪窘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來效扫,“玉大人倔监,你說我怎么就攤上這事【剩” “怎么了浩习?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長济丘。 經(jīng)常有香客問我谱秽,道長,這世上最難降的妖魔是什么摹迷? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任疟赊,我火速辦了婚禮,結(jié)果婚禮上峡碉,老公的妹妹穿的比我還像新娘近哟。我一直安慰自己,他們只是感情好鲫寄,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布吉执。 她就那樣靜靜地躺著疯淫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戳玫。 梳的紋絲不亂的頭發(fā)上熙掺,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音咕宿,去河邊找鬼币绩。 笑死,一個胖子當著我的面吹牛荠列,可吹牛的內(nèi)容都是我干的类浪。 我是一名探鬼主播载城,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肌似,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诉瓦?” 一聲冷哼從身側(cè)響起川队,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睬澡,沒想到半個月后固额,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡煞聪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年斗躏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔脯。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡啄糙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出云稚,到底是詐尸還是另有隱情隧饼,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布静陈,位于F島的核電站燕雁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鲸拥。R本人自食惡果不足惜拐格,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刑赶。 院中可真熱鬧捏浊,春花似錦、人聲如沸角撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至热康,卻和暖如春沛申,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姐军。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工铁材, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奕锌。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓著觉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惊暴。 傳聞我的和親對象是個殘疾皇子饼丘,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

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