一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>CosId分布式系統(tǒng)ID生成器

CosId分布式系統(tǒng)ID生成器

2022-06-10 | zip | 5.48 MB | 次下載 | 2積分

資料介紹

授權(quán)協(xié)議 Apache

開(kāi)發(fā)語(yǔ)言 Kotlin Java Lua

操作系統(tǒng) 跨平臺(tái)

軟件類型 開(kāi)源軟件

所屬分類 服務(wù)器軟件、 分布式應(yīng)用/網(wǎng)格

軟件簡(jiǎn)介

CosId?通用、靈活、高性能的分布式ID生成器

English Document

簡(jiǎn)介

CosId?旨在提供通用、靈活、高性能的分布式 ID 生成器。 目前提供了倆類 ID 生成器:

SnowflakeId?:?單機(jī) TPS 性能:409W/s?JMH 基準(zhǔn)測(cè)試?, 主要解決?時(shí)鐘回?fù)軉?wèn)題?、機(jī)器號(hào)分配問(wèn)題?并且提供更加友好、靈活的使用體驗(yàn)。

SegmentId: 每次獲取一段 (Step) ID,來(lái)降低號(hào)段分發(fā)器的網(wǎng)絡(luò)IO請(qǐng)求頻次提升性能。

IdSegmentDistributor: 號(hào)段分發(fā)器(號(hào)段存儲(chǔ)器)

RedisIdSegmentDistributor: 基于?Redis?的號(hào)段分發(fā)器。

JdbcIdSegmentDistributor: 基于?Jdbc?的號(hào)段分發(fā)器,支持各種關(guān)系型數(shù)據(jù)庫(kù)。

SegmentChainId(推薦):SegmentChainId?(lock-free) 是對(duì)?SegmentId?的增強(qiáng)。性能可達(dá)到近似?AtomicLong?的?TPS 性能:12743W+/s?JMH 基準(zhǔn)測(cè)試?。

PrefetchWorker?維護(hù)安全距離(safeDistance), 并且支持基于饑餓狀態(tài)的動(dòng)態(tài)safeDistance擴(kuò)容/收縮。

快速開(kāi)始

背景(為什么需要分布式ID)

在軟件系統(tǒng)演進(jìn)過(guò)程中,隨著業(yè)務(wù)規(guī)模的增長(zhǎng),我們需要進(jìn)行集群化部署來(lái)分?jǐn)傆?jì)算、存儲(chǔ)壓力,應(yīng)用服務(wù)我們可以很輕松做到無(wú)狀態(tài)、彈性伸縮。 但是僅僅增加服務(wù)副本數(shù)就夠了嗎?顯然不夠,因?yàn)樾阅芷款i往往是在數(shù)據(jù)庫(kù)層面,那么這個(gè)時(shí)候我們就需要考慮如何進(jìn)行數(shù)據(jù)庫(kù)的擴(kuò)容、伸縮、集群化,通常使用分庫(kù)、分表的方式來(lái)處理。 那么我如何分片(水平分片,當(dāng)然還有垂直分片不過(guò)不是本文需要討論的內(nèi)容)呢,分片得前提是我們得先有一個(gè)ID,然后才能根據(jù)分片算法來(lái)分片。(比如比較簡(jiǎn)單常用的ID取模分片算法,這個(gè)跟Hash算法的概念類似,我們得先有key才能進(jìn)行Hash取得插入槽位。)

當(dāng)然還有很多分布式場(chǎng)景需要分布式ID,這里不再一一列舉。

分布式ID方案的核心指標(biāo)

全局(相同業(yè)務(wù))唯一性:唯一性保證是ID的必要條件,假設(shè)ID不唯一就會(huì)產(chǎn)生主鍵沖突,這點(diǎn)很容易可以理解。

通常所說(shuō)的全局唯一性并不是指所有業(yè)務(wù)服務(wù)都要唯一,而是相同業(yè)務(wù)服務(wù)不同部署副本唯一。 比如 Order 服務(wù)的多個(gè)部署副本在生成t_order這張表的Id時(shí)是要求全局唯一的。至于t_order_item生成的ID與t_order是否唯一,并不影響唯一性約束,也不會(huì)產(chǎn)生什么副作用。 不同業(yè)務(wù)模塊間也是同理。即唯一性主要解決的是ID沖突問(wèn)題。

有序性:有序性保證是面向查詢的數(shù)據(jù)結(jié)構(gòu)算法(除了Hash算法)所必須的,是二分查找法(分而治之)的前提。

MySq-InnoDB B+樹(shù)是使用最為廣泛的,假設(shè) Id 是無(wú)序的,B+ 樹(shù) 為了維護(hù) ID 的有序性,就會(huì)頻繁的在索引的中間位置插入而挪動(dòng)后面節(jié)點(diǎn)的位置,甚至導(dǎo)致頻繁的頁(yè)分裂,這對(duì)于性能的影響是極大的。那么如果我們能夠保證ID的有序性這種情況就完全不同了,只需要進(jìn)行追加寫操作。所以 ID 的有序性是非常重要的,也是ID設(shè)計(jì)不可避免的特性。

吞吐量/性能(ops/time):即單位時(shí)間(每秒)能產(chǎn)生的ID數(shù)量。生成ID是非常高頻的操作,也是最為基本的。假設(shè)ID生成的性能緩慢,那么不管怎么進(jìn)行系統(tǒng)優(yōu)化也無(wú)法獲得更好的性能。

一般我們會(huì)首先生成ID,然后再執(zhí)行寫入操作,假設(shè)ID生成緩慢,那么整體性能上限就會(huì)受到限制,這一點(diǎn)應(yīng)該不難理解。

穩(wěn)定性(time/op):穩(wěn)定性指標(biāo)一般可以采用每個(gè)操作的時(shí)間進(jìn)行百分位采樣來(lái)分析,比如?CosId?百分位采樣?P9999=0.208 us/op,即?0% ~ 99.99%?的單位操作時(shí)間小于等于?0.208 us/op

百分位數(shù) WIKI?:統(tǒng)計(jì)學(xué)術(shù)語(yǔ),若將一組數(shù)據(jù)從小到大排序,并計(jì)算相應(yīng)的累計(jì)百分點(diǎn),則某百分點(diǎn)所對(duì)應(yīng)數(shù)據(jù)的值,就稱為這百分點(diǎn)的百分位數(shù),以Pk表示第k百分位數(shù)。百分位數(shù)是用來(lái)比較個(gè)體在群體中的相對(duì)地位量數(shù)。

為什么不用平均每個(gè)操作的時(shí)間:馬老師的身價(jià)跟你的身價(jià)能平均么?平均后的值有意義不?

可以使用最小每個(gè)操作的時(shí)間、最大每個(gè)操作的時(shí)間作為參考嗎?因?yàn)樽钚?、最大值只說(shuō)明了零界點(diǎn)的情況,雖說(shuō)可以作為穩(wěn)定性的參考,但依然不夠全面。而且百分位數(shù)已經(jīng)覆蓋了這倆個(gè)指標(biāo)。

自治性(依賴):主要是指對(duì)外部環(huán)境有無(wú)依賴,比如號(hào)段模式會(huì)強(qiáng)依賴第三方存儲(chǔ)中間件來(lái)獲取NexMaxId。自治性還會(huì)對(duì)可用性造成影響。

可用性:分布式ID的可用性主要會(huì)受到自治性影響,比如SnowflakeId會(huì)受到時(shí)鐘回?fù)苡绊?,?dǎo)致處于短暫時(shí)間的不可用狀態(tài)。而號(hào)段模式會(huì)受到第三方發(fā)號(hào)器(NexMaxId)的可用性影響。

可用性 WIKI?:在一個(gè)給定的時(shí)間間隔內(nèi),對(duì)于一個(gè)功能個(gè)體來(lái)講,總的可用時(shí)間所占的比例。

MTBF:平均故障間隔

MDT:平均修復(fù)/恢復(fù)時(shí)間

Availability=MTBF/(MTBF+MDT)

假設(shè)MTBF為1年,MDT為1小時(shí),即Availability=(365*24)/(365*24+1)=0.999885857778792≈99.99%,也就是我們通常所說(shuō)對(duì)可用性4個(gè)9。

適應(yīng)性:是指在面對(duì)外部環(huán)境變化的自適應(yīng)能力,這里我們主要說(shuō)的是面對(duì)流量突發(fā)時(shí)動(dòng)態(tài)伸縮分布式ID的性能,

SegmentChainId可以基于饑餓狀態(tài)進(jìn)行安全距離的動(dòng)態(tài)伸縮。

SnowflakeId常規(guī)位分配方案性能恒定409.6W,雖然可以通過(guò)調(diào)整位分配方案來(lái)獲得不同的TPS性能,但是位分配方法的變更是破壞性的,一般根據(jù)業(yè)務(wù)場(chǎng)景確定位分配方案后不再變更。

存儲(chǔ)空間:還是用MySq-InnoDB B+樹(shù)來(lái)舉例,普通索引(二級(jí)索引)會(huì)存儲(chǔ)主鍵值,主鍵越大占用的內(nèi)存緩存、磁盤空間也會(huì)越大。Page頁(yè)存儲(chǔ)的數(shù)據(jù)越少,磁盤IO訪問(wèn)的次數(shù)會(huì)增加??傊跐M足業(yè)務(wù)需求的情況下,盡可能小的存儲(chǔ)空間占用在絕大多數(shù)場(chǎng)景下都是好的設(shè)計(jì)原則。

不同分布式ID方案核心指標(biāo)對(duì)比

分布式ID 全局唯一性 有序性 吞吐量 穩(wěn)定性(1s=1000,000us) 自治性 可用性 適應(yīng)性 存儲(chǔ)空間
UUID/GUID 完全無(wú)序 3078638(ops/s) P9999=0.325(us/op) 完全自治 100% 128-bit
SnowflakeId 本地單調(diào)遞增,全局趨勢(shì)遞增(受全局時(shí)鐘影響) 4096000(ops/s) P9999=0.244(us/op) 依賴時(shí)鐘 時(shí)鐘回?fù)軙?huì)導(dǎo)致短暫不可用 64-bit
SegmentId 本地單調(diào)遞增,全局趨勢(shì)遞增(受Step影響) 29506073(ops/s) P9999=46.624(us/op) 依賴第三方號(hào)段分發(fā)器 受號(hào)段分發(fā)器可用性影響 64-bit
SegmentChainId 本地單調(diào)遞增,全局趨勢(shì)遞增(受Step、安全距離影響) 127439148(ops/s) P9999=0.208(us/op) 依賴第三方號(hào)段分發(fā)器 受號(hào)段分發(fā)器可用性影響,但因安全距離存在,預(yù)留ID段,所以高于SegmentId 64-bit

有序性(要想分而治之·二分查找法,必須要維護(hù)我)

剛剛我們已經(jīng)討論了ID有序性的重要性,所以我們?cè)O(shè)計(jì)ID算法時(shí)應(yīng)該盡可能地讓ID是單調(diào)遞增的,比如像表的自增主鍵那樣。但是很遺憾,因全局時(shí)鐘、性能等分布式系統(tǒng)問(wèn)題,我們通常只能選擇局部單調(diào)遞增、全局趨勢(shì)遞增的組合(就像我們?cè)诜植际较到y(tǒng)中不得不的選擇最終一致性那樣)以獲得多方面的權(quán)衡。下面我們來(lái)看一下什么是單調(diào)遞增與趨勢(shì)遞增。

有序性之單調(diào)遞增

pYYBAGKgnBeAG1qWAAD9EHVSZiQ881.png

單調(diào)遞增:T表示全局絕對(duì)時(shí)點(diǎn),假設(shè)有Tn+1>Tn(絕對(duì)時(shí)間總是往前進(jìn)的,這里不考慮相對(duì)論、時(shí)間機(jī)器等),那么必然有F(Tn+1)>F(Tn),數(shù)據(jù)庫(kù)自增主鍵就屬于這一類。 另外需要特別說(shuō)明的是單調(diào)遞增跟連續(xù)性遞增是不同的概念。 連續(xù)性遞增:F(n+1)=(F(n)+step)即下一次獲取的ID一定等于當(dāng)前ID+Step,當(dāng)Step=1時(shí)類似于這樣一個(gè)序列:1->2->3->4->5。

擴(kuò)展小知識(shí):數(shù)據(jù)庫(kù)的自增主鍵也不是連續(xù)性遞增的,相信你一定遇到過(guò)這種情況,請(qǐng)思考一下數(shù)據(jù)庫(kù)為什么這樣設(shè)計(jì)?

有序性之趨勢(shì)遞增

poYBAGKgnBmAKOLdAAFHwqg3GHE901.png

趨勢(shì)遞增:Tn>Tn-s,那么大概率有F(Tn)>F(Tn-s)。雖然在一段時(shí)間間隔內(nèi)有亂序,但是整體趨勢(shì)是遞增。從上圖上看,是有上升趨勢(shì)的(趨勢(shì)線)。

SnowflakeId中n-s受到全局時(shí)鐘同步影響。

在號(hào)段模式(SegmentId)中n-s受到號(hào)段可用區(qū)間(Step)影響。

分布式ID分配方案

UUID/GUID

poYBAGKgnBqAShgBAAAUD6TdlbU428.png不依賴任何第三方中間件

poYBAGKgnBqAShgBAAAUD6TdlbU428.png性能高

poYBAGKgnB2ALU4-AAAUCT5wcFs177.png完全無(wú)序

poYBAGKgnB2ALU4-AAAUCT5wcFs177.png空間占用大,需要占用128位存儲(chǔ)空間。

UUID最大的缺陷是隨機(jī)的、無(wú)序的,當(dāng)用于主鍵時(shí)會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的主鍵索引效率低下(為了維護(hù)索引樹(shù),頻繁的索引中間位置插入數(shù)據(jù),而不是追加寫)。這也是UUID不適用于數(shù)據(jù)庫(kù)主鍵的最為重要的原因。

SnowflakeId

pYYBAGKgnB-AbqkFAABdWAFysLo914.png

SnowflakeId使用Long(64-bit)位分區(qū)來(lái)生成ID的一種分布式ID算法。 通用的位分配方案為:timestamp(41-bit)+machineId(10-bit)+sequence(12-bit)=63-bit。

41-bittimestamp=(1L<<41)/(1000/3600/365),約可以存儲(chǔ)69年的時(shí)間戳,即可以使用的絕對(duì)時(shí)間為EPOCH+69年,一般我們需要自定義EPOCH為產(chǎn)品開(kāi)發(fā)時(shí)間,另外還可以通過(guò)壓縮其他區(qū)域的分配位數(shù),來(lái)增加時(shí)間戳位數(shù)來(lái)延長(zhǎng)可用時(shí)間。

10-bitmachineId=(1L<<10)=1024,即相同業(yè)務(wù)可以部署1024個(gè)副本(在Kubernetes概念里沒(méi)有主從副本之分,這里直接沿用Kubernetes的定義)。一般情況下沒(méi)有必要使用這么多位,所以會(huì)根據(jù)部署規(guī)模需要重新定義。

12-bitsequence=(1L<<12)*1000=4096000,即單機(jī)每秒可生成約409W的ID,全局同業(yè)務(wù)集群可產(chǎn)生4096000*1024=419430W=41.9億(TPS)。

從?SnowflakeId?設(shè)計(jì)上可以看出:

poYBAGKgnBqAShgBAAAUD6TdlbU428.pngtimestamp在高位,單實(shí)例SnowflakeId是會(huì)保證時(shí)鐘總是向前的(校驗(yàn)本機(jī)時(shí)鐘回?fù)埽?,所以是本機(jī)單調(diào)遞增的。受全局時(shí)鐘同步/時(shí)鐘回?fù)苡绊慡nowflakeId是全局趨勢(shì)遞增的。

poYBAGKgnBqAShgBAAAUD6TdlbU428.pngSnowflakeId不對(duì)任何第三方中間件有強(qiáng)依賴關(guān)系,并且性能也非常高。

poYBAGKgnBqAShgBAAAUD6TdlbU428.png位分配方案可以按照業(yè)務(wù)系統(tǒng)需要靈活配置,來(lái)達(dá)到最優(yōu)使用效果。

poYBAGKgnB2ALU4-AAAUCT5wcFs177.png強(qiáng)依賴本機(jī)時(shí)鐘,潛在的時(shí)鐘回?fù)軉?wèn)題會(huì)導(dǎo)致ID重復(fù)、處于短暫的不可用狀態(tài)。

poYBAGKgnB2ALU4-AAAUCT5wcFs177.pngmachineId需要手動(dòng)設(shè)置,實(shí)際部署時(shí)如果采用手動(dòng)分配machineId,會(huì)非常低效。

SnowflakeId之機(jī)器號(hào)分配問(wèn)題

SnowflakeId中根據(jù)業(yè)務(wù)設(shè)計(jì)的位分配方案確定了基本上就不再有變更了,也很少需要維護(hù)。但是machineId總是需要配置的,而且集群中是不能重復(fù)的,否則分區(qū)原則就會(huì)被破壞而導(dǎo)致ID唯一性原則破壞,當(dāng)集群規(guī)模較大時(shí)machineId的維護(hù)工作是非常繁瑣,低效的。

有一點(diǎn)需要特別說(shuō)明的,SnowflakeIdMachineId是邏輯上的概念,而不是物理概念。 想象一下假設(shè)MachineId是物理上的,那么意味著一臺(tái)機(jī)器擁有只能擁有一個(gè)MachineId,那會(huì)產(chǎn)生什么問(wèn)題呢?

目前?CosId?提供了以下三種?MachineId?分配器。

ManualMachineIdDistributor: 手動(dòng)配置machineId,一般只有在集群規(guī)模非常小的時(shí)候才有可能使用,不推薦。

StatefulSetMachineIdDistributor: 使用Kubernetes的StatefulSet提供的穩(wěn)定的標(biāo)識(shí)ID(HOSTNAME=service-01)作為機(jī)器號(hào)。

RedisMachineIdDistributor: 使用Redis作為機(jī)器號(hào)的分發(fā)存儲(chǔ),同時(shí)還會(huì)存儲(chǔ)MachineId的上一次時(shí)間戳,用于啟動(dòng)時(shí)時(shí)鐘回?fù)?/strong>的檢查。

pYYBAGKgnCeAL67bAABjo1ZI74w586.png

SnowflakeId之時(shí)鐘回?fù)軉?wèn)題

時(shí)鐘回?fù)艿闹旅鼏?wèn)題是會(huì)導(dǎo)致ID重復(fù)、沖突(這一點(diǎn)不難理解),ID重復(fù)顯然是不能被容忍的。 在SnowflakeId算法中,按照MachineId分區(qū)ID,我們不難理解的是不同MachineId是不可能產(chǎn)生相同ID的。所以我們解決的時(shí)鐘回?fù)軉?wèn)題是指當(dāng)前MachineId的時(shí)鐘回?fù)軉?wèn)題,而不是所有集群節(jié)點(diǎn)的時(shí)鐘回?fù)軉?wèn)題。

MachineId時(shí)鐘回?fù)軉?wèn)題大體可以分為倆種情況:

運(yùn)行時(shí)時(shí)鐘回?fù)埽杭丛谶\(yùn)行時(shí)獲取的當(dāng)前時(shí)間戳比上一次獲取的時(shí)間戳小。這個(gè)場(chǎng)景的時(shí)鐘回?fù)苁呛苋菀滋幚淼?,一?strong>SnowflakeId代碼實(shí)現(xiàn)時(shí)都會(huì)存儲(chǔ)lastTimestamp用于運(yùn)行時(shí)時(shí)鐘回?fù)艿臋z查,并拋出時(shí)鐘回?fù)墚惓!?/p>

時(shí)鐘回?fù)軙r(shí)直接拋出異常是不太好地實(shí)踐,因?yàn)橄掠问褂梅綆缀鯖](méi)有其他處理方案(噢,我還能怎么辦呢,等吧),時(shí)鐘同步是唯一的選擇,當(dāng)只有一種選擇時(shí)就不要再讓用戶選擇了。

ClockSyncSnowflakeId是SnowflakeId的包裝器,當(dāng)發(fā)生時(shí)鐘回?fù)軙r(shí)會(huì)使用ClockBackwardsSynchronizer主動(dòng)等待時(shí)鐘同步來(lái)重新生成ID,提供更加友好的使用體驗(yàn)。

啟動(dòng)時(shí)時(shí)鐘回?fù)埽杭丛趩?dòng)服務(wù)實(shí)例時(shí)獲取的當(dāng)前時(shí)鐘比上次關(guān)閉服務(wù)時(shí)小。此時(shí)的lastTimestamp是無(wú)法存儲(chǔ)在進(jìn)程內(nèi)存中的。當(dāng)獲取的外部存儲(chǔ)的機(jī)器狀態(tài)大于當(dāng)前時(shí)鐘時(shí)鐘時(shí),會(huì)使用ClockBackwardsSynchronizer主動(dòng)同步時(shí)鐘。

LocalMachineStateStorage:使用本地文件存儲(chǔ)MachineState(機(jī)器號(hào)、最近一次時(shí)間戳)。因?yàn)槭褂玫氖潜镜匚募灾挥挟?dāng)實(shí)例的部署環(huán)境是穩(wěn)定的,LocalMachineStateStorage才適用。

RedisMachineIdDistributor:將MachineState存儲(chǔ)在Redis分布式緩存中,這樣可以保證總是可以獲取到上次服務(wù)實(shí)例停機(jī)時(shí)機(jī)器狀態(tài)

SnowflakeId之JavaScript數(shù)值溢出問(wèn)題

JavaScript的Number.MAX_SAFE_INTEGER只有53-bit,如果直接將63位的SnowflakeId返回給前端,那么會(huì)產(chǎn)生值溢出的情況(所以這里我們應(yīng)該知道后端傳給前端的long值溢出問(wèn)題,遲早會(huì)出現(xiàn),只不過(guò)SnowflakeId出現(xiàn)得更快而已)。 很顯然溢出是不能被接受的,一般可以使用以下倆種處理方案:

將生成的63-bitSnowflakeId轉(zhuǎn)換為String類型。

直接將long轉(zhuǎn)換成String。

使用SnowflakeFriendlyId將SnowflakeId轉(zhuǎn)換成比較友好的字符串表示:{timestamp}-{machineId}-{sequence} -> 20210623131730192-1-0

自定義SnowflakeId位分配來(lái)縮短SnowflakeId的位數(shù)(53-bit)使?ID?提供給前端時(shí)不溢出

使用SafeJavaScriptSnowflakeId(JavaScript?安全的?SnowflakeId)

號(hào)段模式(SegmentId)

pYYBAGKgnCiAKqqjAACwOv7UAlo811.png

從上面的設(shè)計(jì)圖中,不難看出號(hào)段模式基本設(shè)計(jì)思路是通過(guò)每次獲取一定長(zhǎng)度(Step)的可用ID(Id段/號(hào)段),來(lái)降低網(wǎng)絡(luò)IO請(qǐng)求次數(shù),提升性能。

poYBAGKgnB2ALU4-AAAUCT5wcFs177.png強(qiáng)依賴第三方號(hào)段分發(fā)器,可用性受到第三方分發(fā)器影響。

poYBAGKgnB2ALU4-AAAUCT5wcFs177.png每次號(hào)段用完時(shí)獲取NextMaxId需要進(jìn)行網(wǎng)絡(luò)IO請(qǐng)求,此時(shí)的性能會(huì)比較低。

單實(shí)例ID單調(diào)遞增,全局趨勢(shì)遞增。

從設(shè)計(jì)圖中不難看出Instance 1每次獲取的NextMaxId,一定比上一次大,意味著下一次的號(hào)段一定比上一次大,所以從單實(shí)例上來(lái)看是單調(diào)遞增的。

多實(shí)例各自持有的不同的號(hào)段,意味著同一時(shí)刻不同實(shí)例生成的ID是亂序的,但是整體趨勢(shì)的遞增的,所以全局趨勢(shì)遞增。

ID亂序程度受到Step長(zhǎng)度以及集群規(guī)模影響(從趨勢(shì)遞增圖中不難看出)。

假設(shè)集群中只有一個(gè)實(shí)例時(shí)號(hào)段模式就是單調(diào)遞增的。

Step越小,亂序程度越小。當(dāng)Step=1時(shí),將無(wú)限接近單調(diào)遞增。需要注意的是這里是無(wú)限接近而非等于單調(diào)遞增,具體原因你可以思考一下這樣一個(gè)場(chǎng)景:

號(hào)段分發(fā)器T1時(shí)刻給Instance 1分發(fā)了ID=1,T2時(shí)刻給Instance 2分發(fā)了ID=2。因?yàn)闄C(jī)器性能、網(wǎng)絡(luò)等原因,Instance 2網(wǎng)絡(luò)IO寫請(qǐng)求先于Instance 1到達(dá)。那么這個(gè)時(shí)候?qū)τ跀?shù)據(jù)庫(kù)來(lái)說(shuō),ID依然是亂序的。

號(hào)段鏈模式(SegmentChainId)

分布式ID(CosId)之號(hào)段鏈模式性能(1.2億/s)解析

pYYBAGKgnCyAFe3KAAByOvBEDZ8078.png

SegmentChainIdSegmentId增強(qiáng)版,相比于SegmentId有以下優(yōu)勢(shì):

穩(wěn)定性:SegmentId的穩(wěn)定性問(wèn)題(P9999=46.624(us/op))主要是因?yàn)樘?hào)段用完之后同步進(jìn)行NextMaxId的獲取導(dǎo)致的(會(huì)產(chǎn)生網(wǎng)絡(luò)IO)。

SegmentChainId?(P9999=0.208(us/op))引入了新的角色PrefetchWorker用以維護(hù)和保證安全距離,理想情況下使得獲取ID的線程幾乎完全不需要進(jìn)行同步的等待NextMaxId獲取,性能可達(dá)到近似?AtomicLong?的?TPS 性能:12743W+/s?JMH 基準(zhǔn)測(cè)試?。

適應(yīng)性:從SegmentId介紹中我們知道了影響ID亂序的因素有倆個(gè):集群規(guī)模、Step大小。集群規(guī)模是我們不能控制的,但是Step是可以調(diào)節(jié)的。

Step應(yīng)該近可能小才能使得ID單調(diào)遞增的可能性增大。

Step太小會(huì)影響吞吐量,那么我們?nèi)绾魏侠碓O(shè)置Step呢?答案是我們無(wú)法準(zhǔn)確預(yù)估所有時(shí)點(diǎn)的吞吐量需求,那么最好的辦法是吞吐量需求高時(shí),Step自動(dòng)增大,吞吐量低時(shí)Step自動(dòng)收縮。

SegmentChainId引入了饑餓狀態(tài)的概念,PrefetchWorker會(huì)根據(jù)饑餓狀態(tài)檢測(cè)當(dāng)前安全距離是否需要膨脹或者收縮,以便獲得吞吐量與有序性之間的權(quán)衡,這便是SegmentChainId的自適應(yīng)性。

集成

CosIdPlugin(MyBatis 插件)

Kotlin DSL

?

    implementation("me.ahoo.cosid:cosid-mybatis:${cosidVersion}")

?

?

public class Order {

    @CosId(value = "order")
    private Long orderId;
    private Long userId;

    public Long getOrderId() {
        return orderId;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }
}

?

ShardingSphere 插件

CosIdKeyGenerateAlgorithm、CosIdModShardingAlgorithm、CosIdIntervalShardingAlgorithm?已合并至?ShardingSphere?官方,未來(lái)?cosid-shardingsphere?模塊的維護(hù)可能會(huì)以官方為主。

Kotlin DSL

?

    implementation("me.ahoo.cosid:cosid-shardingsphere:${cosidVersion}")

?

CosIdKeyGenerateAlgorithm (分布式主鍵)

?

spring:
  shardingsphere:
    rules:
      sharding:
        key-generators:
          cosid:
            type: COSID
            props:
              id-name: __share__

?

基于間隔的時(shí)間范圍分片算法

poYBAGKgnC2AKX92AACRRyKU3dw434.png

易用性: 支持多種數(shù)據(jù)類型 (Long/LocalDateTime/DATE/?String?/?SnowflakeId),而官方實(shí)現(xiàn)是先轉(zhuǎn)換成字符串再轉(zhuǎn)換成LocalDateTime,轉(zhuǎn)換成功率受時(shí)間格式化字符影響。

性能 : 相比于?org.apache.shardingsphere.sharding.algorithm.sharding.datetime.IntervalShardingAlgorithm?性能高出?1200~4000?倍。

PreciseShardingValue RangeShardingValue
poYBAGKgnC-ABtFQAAL_WlazhhU038.png pYYBAGKgnDCAOIShAALcECgX5Kg006.png

?

gradle cosid-shardingsphere:jmh

?

?

# JMH version: 1.29
# VM version: JDK 11.0.13, OpenJDK 64-Bit Server VM, 11.0.13+8-LTS
# VM options: -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/work/CosId/cosid-shardingsphere/build/tmp/jmh -Duser.country=CN -Duser.language=zh -Duser.variant
# Blackhole mode: full + dont-inline hint
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
Benchmark                                                         (days)   Mode  Cnt         Score   Error  Units
IntervalShardingAlgorithmBenchmark.cosid_precise_local_date_time      10  thrpt       53279788.772          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_local_date_time     100  thrpt       38114729.365          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_local_date_time    1000  thrpt       32714318.129          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_local_date_time   10000  thrpt       22317905.643          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_timestamp            10  thrpt       20028091.211          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_timestamp           100  thrpt       19272744.794          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_timestamp          1000  thrpt       17814417.856          ops/s
IntervalShardingAlgorithmBenchmark.cosid_precise_timestamp         10000  thrpt       12384788.025          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_local_date_time        10  thrpt       18716732.080          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_local_date_time       100  thrpt        8436553.492          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_local_date_time      1000  thrpt        1655952.254          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_local_date_time     10000  thrpt         185348.831          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_timestamp              10  thrpt        9410931.643          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_timestamp             100  thrpt        5792861.181          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_timestamp            1000  thrpt        1585344.761          ops/s
IntervalShardingAlgorithmBenchmark.cosid_range_timestamp           10000  thrpt         196663.812          ops/s
IntervalShardingAlgorithmBenchmark.office_precise_timestamp           10  thrpt          72189.800          ops/s
IntervalShardingAlgorithmBenchmark.office_precise_timestamp          100  thrpt          11245.324          ops/s
IntervalShardingAlgorithmBenchmark.office_precise_timestamp         1000  thrpt           1339.128          ops/s
IntervalShardingAlgorithmBenchmark.office_precise_timestamp        10000  thrpt            113.396          ops/s
IntervalShardingAlgorithmBenchmark.office_range_timestamp             10  thrpt          64679.422          ops/s
IntervalShardingAlgorithmBenchmark.office_range_timestamp            100  thrpt           4267.860          ops/s
IntervalShardingAlgorithmBenchmark.office_range_timestamp           1000  thrpt            227.817          ops/s
IntervalShardingAlgorithmBenchmark.office_range_timestamp          10000  thrpt              7.579          ops/s

?

SmartIntervalShardingAlgorithm

type: COSID_INTERVAL

DateIntervalShardingAlgorithm

type: COSID_INTERVAL_DATE

LocalDateTimeIntervalShardingAlgorithm

type: COSID_INTERVAL_LDT

TimestampIntervalShardingAlgorithm

type: COSID_INTERVAL_TS

TimestampOfSecondIntervalShardingAlgorithm

type: COSID_INTERVAL_TS_SECOND

SnowflakeIntervalShardingAlgorithm

type: COSID_INTERVAL_SNOWFLAKE

?

spring:
  shardingsphere:
    rules:
      sharding:
        sharding-algorithms:
          alg-name:
            type: COSID_INTERVAL_{type_suffix}
            props:
              logic-name-prefix: logic-name-prefix
              id-name: cosid-name
              datetime-lower: 2021-12-08 22:00:00
              datetime-upper: 2022-12-01 00:00:00
              sharding-suffix-pattern: yyyyMM
              datetime-interval-unit: MONTHS
              datetime-interval-amount: 1

?

取模分片算法

poYBAGKgnDKAOtReAACXh9IEZT8429.png

性能 : 相比于?org.apache.shardingsphere.sharding.algorithm.sharding.mod.ModShardingAlgorithm?性能高出?1200~4000?倍。并且穩(wěn)定性更高,不會(huì)出現(xiàn)嚴(yán)重的性能退化。

PreciseShardingValue RangeShardingValue
pYYBAGKgnDOAIAfsAAMjQ3P4DEw075.png pYYBAGKgnDWATO2rAAOrwT7q6Sw079.png

?

gradle cosid-shardingsphere:jmh

?

?

# JMH version: 1.29
# VM version: JDK 11.0.13, OpenJDK 64-Bit Server VM, 11.0.13+8-LTS
# VM options: -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/work/CosId/cosid-shardingsphere/build/tmp/jmh -Duser.country=CN -Duser.language=zh -Duser.variant
# Blackhole mode: full + dont-inline hint
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
Benchmark                                     (divisor)   Mode  Cnt          Score   Error  Units
ModShardingAlgorithmBenchmark.cosid_precise          10  thrpt       121431137.111          ops/s
ModShardingAlgorithmBenchmark.cosid_precise         100  thrpt       119947284.141          ops/s
ModShardingAlgorithmBenchmark.cosid_precise        1000  thrpt       113095657.321          ops/s
ModShardingAlgorithmBenchmark.cosid_precise       10000  thrpt       108435323.537          ops/s
ModShardingAlgorithmBenchmark.cosid_precise      100000  thrpt        84657505.579          ops/s
ModShardingAlgorithmBenchmark.cosid_range            10  thrpt        37397323.508          ops/s
ModShardingAlgorithmBenchmark.cosid_range           100  thrpt        16905691.783          ops/s
ModShardingAlgorithmBenchmark.cosid_range          1000  thrpt         2969820.981          ops/s
ModShardingAlgorithmBenchmark.cosid_range         10000  thrpt          312881.488          ops/s
ModShardingAlgorithmBenchmark.cosid_range        100000  thrpt           31581.396          ops/s
ModShardingAlgorithmBenchmark.office_precise         10  thrpt         9135460.160          ops/s
ModShardingAlgorithmBenchmark.office_precise        100  thrpt         1356582.418          ops/s
ModShardingAlgorithmBenchmark.office_precise       1000  thrpt          104500.125          ops/s
ModShardingAlgorithmBenchmark.office_precise      10000  thrpt            8619.933          ops/s
ModShardingAlgorithmBenchmark.office_precise     100000  thrpt             629.353          ops/s
ModShardingAlgorithmBenchmark.office_range           10  thrpt         5535645.737          ops/s
ModShardingAlgorithmBenchmark.office_range          100  thrpt           83271.925          ops/s
ModShardingAlgorithmBenchmark.office_range         1000  thrpt             911.534          ops/s
ModShardingAlgorithmBenchmark.office_range        10000  thrpt               9.133          ops/s
ModShardingAlgorithmBenchmark.office_range       100000  thrpt               0.208          ops/s

?

?

spring:
  shardingsphere:
    rules:
      sharding:
        sharding-algorithms:
          alg-name:
            type: COSID_MOD
            props:
              mod: 4
              logic-name-prefix: t_table_

?

性能測(cè)試報(bào)告

SegmentChainId-吞吐量 (ops/s)

RedisChainIdBenchmark-Throughput

poYBAGKgnDaAXkTZAACR6lKLLw8735.png

MySqlChainIdBenchmark-Throughput

poYBAGKgnDiAOnmwAACQOxmf-YU983.png

SegmentChainId-每次操作耗時(shí)的百分位數(shù)(us/op)

RedisChainIdBenchmark-Percentile

pYYBAGKgnDmAY3O8AADQDUROmK4578.png

MySqlChainIdBenchmark-Percentile

poYBAGKgnDuAXFypAADWyvxlO1Q131.png

基準(zhǔn)測(cè)試報(bào)告運(yùn)行環(huán)境說(shuō)明

基準(zhǔn)測(cè)試運(yùn)行環(huán)境:筆記本開(kāi)發(fā)機(jī)(MacBook-Pro-(M1))

所有基準(zhǔn)測(cè)試都在開(kāi)發(fā)筆記本上執(zhí)行。

?

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
  2. 1.06 MB  |  532次下載  |  免費(fèi)
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費(fèi)
  5. 3TC358743XBG評(píng)估板參考手冊(cè)
  6. 1.36 MB  |  330次下載  |  免費(fèi)
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費(fèi)
  9. 5元宇宙深度解析—未來(lái)的未來(lái)-風(fēng)口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費(fèi)
  11. 6迪文DGUS開(kāi)發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費(fèi)
  13. 7元宇宙底層硬件系列報(bào)告
  14. 13.42 MB  |  182次下載  |  免費(fèi)
  15. 8FP5207XR-G1中文應(yīng)用手冊(cè)
  16. 1.09 MB  |  178次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)