深圳手機(jī)網(wǎng)站制作公司全網(wǎng)搜索軟件
為了保證全局唯一性可以用時(shí)間作為區(qū)分點(diǎn)一部分,時(shí)間盡可能細(xì)化,可以精確到毫秒,甚至是微秒和納秒。如果是分布式系統(tǒng)有多態(tài)機(jī)器,可以根據(jù)機(jī)器ID再進(jìn)行以下區(qū)分。如哦機(jī)器運(yùn)行的特別快,1毫秒有大量ID生成,可以結(jié)合實(shí)際限制下實(shí)際生成的ID數(shù)目。
如果N臺(tái)機(jī)器去ID生成服務(wù)器的服務(wù)端得到全局ID,很容易保證全局唯一切自增的,但是存在單點(diǎn)失效的問(wèn)題,不滿(mǎn)足高可用。
雪花算法
生成的結(jié)果是一個(gè)int64
的數(shù)據(jù)。核心思想是:使用41bit作為毫秒數(shù),10bit作為機(jī)器的ID(5個(gè)bit是數(shù)據(jù)中心,5個(gè)bit的機(jī)器ID),12bit作為毫秒內(nèi)的流水號(hào),意味著每個(gè)節(jié)點(diǎn)再每毫秒可以產(chǎn)生 4096 個(gè) ID, 最后還有一個(gè)符號(hào)位,永遠(yuǎn)是0.
優(yōu)點(diǎn): 優(yōu)點(diǎn)是毫秒書(shū)在高位,自增序列在低位,整個(gè)ID是趨勢(shì)遞增的。不依賴(lài)數(shù)據(jù)庫(kù)等第三方系統(tǒng),一服務(wù)的方式部署,穩(wěn)定性更高,生成ID的性能也是非常高的。可以根據(jù)自身業(yè)務(wù)特性分配bit位,非常靈活。
缺點(diǎn): 強(qiáng)依賴(lài)機(jī)器時(shí)鐘,如果機(jī)器上時(shí)鐘回?fù)?#xff0c;會(huì)導(dǎo)致號(hào)重復(fù)或者服務(wù)會(huì)處于不可用狀態(tài)。
Redis生成ID
因?yàn)?Redis 是單線(xiàn)程的,也可以用來(lái)生成全局唯一ID??梢杂肦edis的原子操作INCR和INCRBY來(lái)實(shí)現(xiàn)。使用Redis集群來(lái)獲取更高的吞吐量。假如一個(gè)集群中有5臺(tái)Redis,可以初始化每臺(tái)Redis的值分別是1,2,3,4,5,步長(zhǎng)都是5,各Redis生成的ID如下:A: 1,6,11,16; B: 2,7,12,17; C: 3,8,13,18; D: 4,9,14,19; E: 5,10,15,29。負(fù)載到哪臺(tái)機(jī)器提前定好,未來(lái)很難做修改。3-5臺(tái)服務(wù)器基本能安祖需求,但步長(zhǎng)和初始值一定需要事先確定,使用Redis集群也可以解決單點(diǎn)故障問(wèn)題。
**優(yōu)點(diǎn):**不依賴(lài)數(shù)據(jù)庫(kù),靈活方便,且性能優(yōu)于數(shù)據(jù)庫(kù),數(shù)字ID天然排序,對(duì)分頁(yè)或需要排序的結(jié)果很有幫助。
**缺點(diǎn):**如果系統(tǒng)中沒(méi)有Redis,需要引入新的組件,增加系統(tǒng)復(fù)雜度;需要編碼和配置的工作量比較大。
UUID
可以利用數(shù)據(jù)庫(kù)也可以利用程序生成,一般全球唯一。UUID是由32個(gè)16進(jìn)制數(shù)字組成,所以每個(gè)UUID的長(zhǎng)度是128位(16^32 = 2 ^128)。UUID有多個(gè)實(shí)現(xiàn)版本,影響它的因素包括時(shí)間,網(wǎng)卡MAC地址,自定義Namespace等等。
優(yōu)點(diǎn):簡(jiǎn)單,代碼方便;生成ID性能非常好,基本不會(huì)有性能問(wèn)題;全球唯一,在遇見(jiàn)數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫(kù)變更情況下,可以從容應(yīng)對(duì)。
缺點(diǎn):沒(méi)有排序,無(wú)法保證確實(shí)遞增;UUID往往是使用字符串存儲(chǔ),查詢(xún)的效率比較低;存儲(chǔ)空間比較大,如果是海量數(shù)據(jù)庫(kù),就需要哦考慮存儲(chǔ)量的問(wèn)題;傳輸數(shù)據(jù)量大;不可讀。
美團(tuán)Leaf
Leaf-segment
直接用數(shù)據(jù)庫(kù)自增ID充當(dāng)分布式ID,減少對(duì)數(shù)據(jù)庫(kù)的頻繁操作。過(guò)程是從數(shù)據(jù)庫(kù)批量的獲取自增ID,每次從數(shù)據(jù)庫(kù)取出一個(gè)號(hào)段范圍,例如(1,10000]代表10000個(gè)ID,業(yè)務(wù)服務(wù)將號(hào)段生成1~10000的自增ID并加載在內(nèi)存,在當(dāng)前號(hào)段消費(fèi)到某個(gè)點(diǎn)時(shí),就異步的把下一個(gè)號(hào)段加載到內(nèi)存中。而不需要等到號(hào)段用盡的時(shí)候才去更新號(hào)段。這樣做很大程度上的降低了系統(tǒng)的風(fēng)險(xiǎn)。Leaf-segment采用雙buffer的發(fā)過(guò)誓,他的服務(wù)內(nèi)部有兩個(gè)號(hào)段緩存qusegment.當(dāng)前號(hào)段已消耗10%時(shí),還沒(méi)能拿到下一個(gè)號(hào)段,則會(huì)另啟一個(gè)更新線(xiàn)程去更新下一個(gè)號(hào)段。Leaf保證了總是會(huì)多緩存兩個(gè)號(hào)段,即便那一時(shí)刻數(shù)據(jù)庫(kù)掛了,也會(huì)保證發(fā)號(hào)服務(wù)可以正常工作一段時(shí)間。通常推薦號(hào)段(segment)長(zhǎng)度設(shè)置為服務(wù)高峰期發(fā)號(hào)QPS的600倍(10分鐘),這樣即使DB宕機(jī),Leaf仍能持續(xù)發(fā)號(hào)10-20分鐘不受影響。
tip biz_tag
針對(duì)不同業(yè)務(wù)需求,用biz_tag字段來(lái)隔離,如果以后需要擴(kuò)容時(shí),只需要對(duì)biz_tag分庫(kù)分表即可
優(yōu)點(diǎn): Leaf服務(wù)可以很方便的線(xiàn)性擴(kuò)展,性能完全能夠支持大多數(shù)業(yè)務(wù)場(chǎng)景;容災(zāi)行=性高;Leaf服務(wù)內(nèi)部有號(hào)段緩存,即使DB宕機(jī),短時(shí)間內(nèi)Leaf仍能正常對(duì)外提供服務(wù)。
缺點(diǎn): ID號(hào)碼不夠隨機(jī),能夠泄漏發(fā)號(hào)數(shù)量的信息,不太安全;DB宕機(jī)會(huì)造成整個(gè)系統(tǒng)不可用(用到數(shù)據(jù)庫(kù)的都有可能)
Leaf-snowflake
Leaf-snowflake基本上就是沿用了snowflake的設(shè)計(jì),ID組成結(jié)構(gòu):正數(shù)位(占1比特)+時(shí)間戳(占41比特)+機(jī)器ID(占5bit)+機(jī)房ID(占5 bit) + 自增值(占12bit), 總共54比特組成的一個(gè)int64類(lèi)型。不同點(diǎn)主要是在workId的生成上,Leaf-snowflake依靠Zookeerper生成workId。Leaf中workId時(shí)基于Zookeeper中生成一個(gè)順序Id,相當(dāng)于一臺(tái)機(jī)器對(duì)應(yīng)一個(gè)順序節(jié)點(diǎn)。
啟動(dòng)服務(wù)的過(guò)程大致如下:啟動(dòng)Leaf-snowflake服務(wù),連接Zookeeper, 在leaf_foever父節(jié)點(diǎn)下檢查自己是否已經(jīng)注冊(cè)過(guò);如果有注冊(cè)過(guò)直接取回自己的workerId(zk順序節(jié)點(diǎn)生成的int類(lèi)型ID號(hào))。啟動(dòng)服務(wù);如果沒(méi)有注冊(cè)過(guò),就在該父節(jié)點(diǎn)下面創(chuàng)建一個(gè)持久順序節(jié)點(diǎn),創(chuàng)建成功后取回順序號(hào)當(dāng)作自己的workerID號(hào),啟動(dòng)服務(wù)。Leaf-snowflake對(duì)Zookeeper是一種弱依賴(lài)關(guān)系,除了每次會(huì)去ZK拿數(shù)據(jù)以外,也會(huì)在本機(jī)文件系統(tǒng)上緩存一個(gè)workerID文件。一旦Zookeeper出現(xiàn)問(wèn)題,敲好機(jī)器出現(xiàn)故障需重啟時(shí),依然能夠保證服務(wù)正常啟動(dòng)。
優(yōu)點(diǎn): ID號(hào)碼是趨勢(shì)遞增的8 byte的64位數(shù)據(jù),滿(mǎn)足上述數(shù)據(jù)庫(kù)存儲(chǔ)的主鍵要求。
缺點(diǎn): 依賴(lài)Zookeeper, 存在服務(wù)不可用風(fēng)險(xiǎn)