java 唯一id生成算法_分布式全局唯一ID生成方案之snowflake算法
已有的方案:
可大致分為:
完全依賴關(guān)系/非關(guān)系型數(shù)據(jù)庫遞增的方案
完全不依賴數(shù)據(jù)源作為生成因子的UUID
半依賴數(shù)據(jù)源作為生成因子的snowflake
為什么推薦snowflake?
這個(gè)問題,可以從前兩個(gè)方案的缺點(diǎn)來講。
完全依賴關(guān)系/非關(guān)系型數(shù)據(jù)庫遞增的方案:
關(guān)系/非關(guān)系的區(qū)別細(xì)節(jié)就不展開了,只說說關(guān)系型。它最大的缺點(diǎn)是并發(fā)的瓶頸,其次是拓展性的問題,再就是還需要考慮數(shù)據(jù)庫的可用性。
噢對(duì)了高可用也挺難搞的,不是說難度哈,只是這玩意是真滴麻煩啊,因?yàn)橐话銇碚f也得雙寫部署,不然掛掉一個(gè)master怎么辦,對(duì)吧?那雙寫之后還需要給master配上中間件吧?噢中間件也需要高可用吧?好吧那最后還需要上個(gè)nginx或者keepalived…到了這里回頭一看“完了我只想生成一個(gè)ID而已為什么還要增加那么多東西,需要額外考慮那么多東西?真蛋疼”。所以斃掉這個(gè)方案!
UUID:
UUID,神奇的東西(我沒仔細(xì)研究,所以用“神奇”這個(gè)詞來蒙混過去),無需數(shù)據(jù)源作為生成因子卻能生成全球唯一ID。屌哇!但是用它作為ID的話還是太大了,16個(gè)字節(jié)啊,浪費(fèi)空間不說還影響索引的效率。
不過最大的缺點(diǎn)還不是它的大小,而是它是生成的ID是無序的,但是主流的數(shù)據(jù)庫的索引數(shù)據(jù)結(jié)構(gòu)都是B+樹結(jié)構(gòu),所以你明白了吧。(這里不懂的朋友請(qǐng)自行搜索 B+樹分裂問題 ,我沒有能力在三言兩語內(nèi)解釋清楚)
所以什么是snowflake?
snowflake 算法是 twitter 開源的分布式 id 生成算法,采用 Scala 語言實(shí)現(xiàn),是把一個(gè) 64 位的 long 型的 id,1 個(gè) bit 是不用的,用其中的 41 bits 作為毫秒數(shù),用 10 bits 作為工作機(jī)器 id,12 bits 作為序列號(hào)。(這句話是復(fù)制來的)
snowflake算法生成的ID的結(jié)構(gòu):
總共64bit,剛好是一個(gè)long類型的大小
符號(hào)位:符號(hào)位是不用的,因?yàn)镮D只考慮正數(shù)。
時(shí)間戳:注意是精度為毫秒級(jí)的,而不是秒級(jí)的。
區(qū)域ID:也叫數(shù)據(jù)中心ID,標(biāo)識(shí)機(jī)器所屬的數(shù)據(jù)中心。
機(jī)器ID:配合區(qū)域ID,用作定位某區(qū)域的機(jī)房里的其中一臺(tái)機(jī)器。
序列號(hào):看到這里你可能已經(jīng)明白了,時(shí)間戳標(biāo)記了時(shí)間,區(qū)域和機(jī)器ID標(biāo)記了機(jī)器所屬,那么在一個(gè)時(shí)間單位里,同一臺(tái)機(jī)器請(qǐng)求多個(gè)ID怎么辦?對(duì),所以需要序列號(hào)的遞增作為ID的遞增生成因子。
算法思路:
如果是在同一時(shí)間單位內(nèi),則遞增序列號(hào)作為ID生成因子,直至0 ~ 2^12-1 (0到4095)所有數(shù)字用完了,或者檢測(cè)到時(shí)間戳更新了的時(shí)候,才將序列號(hào)歸零重新遞增。按照這個(gè)思路就可以做出理論上并發(fā)為 (2^12-1)(2^10)≈4,200,000 的ID生成算法了。很簡(jiǎn)單吧。我感覺就并發(fā)能力而言,這個(gè)算法可以用到死了。
(注意,區(qū)域/機(jī)器ID不是由snowflake生成的,而是讓各個(gè)機(jī)器在需要時(shí)主動(dòng)調(diào)用該生成算法,在調(diào)用時(shí)傳入?yún)^(qū)域/機(jī)器ID作為分布式全局唯一ID的生成因子之一。)
算法的實(shí)現(xiàn)
測(cè)試結(jié)果
我的機(jī)器性能不足,加上目前只是單線程測(cè)試,所以你會(huì)看到圖一開頭就幾個(gè)sequenceID都是0,那是因?yàn)闀r(shí)間戳更新后sequenceID歸零了。
圖二可以看到,單位時(shí)間內(nèi)我機(jī)子的性能最多疊加到29。改天再做個(gè)多線程測(cè)試。完
總結(jié)
以上是生活随笔為你收集整理的java 唯一id生成算法_分布式全局唯一ID生成方案之snowflake算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql sql乱码怎么解决_MYSQ
- 下一篇: win10 配置 maven_home