溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于Ignite的分布式ID生成器怎么實現(xiàn)

發(fā)布時間:2021-12-16 16:16:31 來源:億速云 閱讀:164 作者:iii 欄目:云計算

本篇內(nèi)容介紹了“基于Ignite的分布式ID生成器怎么實現(xiàn)”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1.Apache Ignite的分布式原子化類型

JDK在1.5版本之后,提供了java.util.concurrent包,其中java.util.concurrent.atomic子包中包含了對于單一變量的線程安全的支持lock-free的編程實現(xiàn)。該包中的類,比如AtomicLong,提供了和Long類型相對應(yīng)的原子化操作,比如一些increment方法,基于這些功能,是可以開發(fā)出單JVM的序列生成器這樣的功能的,但是對于分布式環(huán)境,則無能為力。 在Ignite中,除了提供標(biāo)準(zhǔn)的基于鍵-值的類似于Map的存儲以外,還提供了一種分布式數(shù)據(jù)結(jié)構(gòu)的實現(xiàn),其中包括:IgniteAtomicLong,IgniteSet,IgniteQueue,IgniteAtomicReference,IgniteAtomicSequence,IgniteCountDownLatch,IgniteSemaphore,這些類除了提供和JDK相同的功能外,就是增加了對分布式環(huán)境的支持,也就是支持集群范圍內(nèi)的原子化操作。 鑒于本文重點是討論分布式ID生成器,所以下文的重點在于IgniteAtomicSequence。

2.IgniteAtomicSequence

IgniteAtomicSequence接口提供了分布式的原子性序列,類似于分布式原子性的Long類型,但是他的值只能增長,他特有的功能是支持預(yù)留一定范圍的序列值,來避免每次序列獲取下一個值時都需要的昂貴的網(wǎng)絡(luò)消耗和緩存更新,也就是,當(dāng)在一個原子性序列上執(zhí)行了incrementAndGet()(或者任何其他的原子性操作),數(shù)據(jù)結(jié)構(gòu)會往前預(yù)留一定范圍的序列值,他會保證對于這個序列實例來說跨集群的唯一性。 這個類型的使用是非常簡單的,相關(guān)代碼如下:

Ignite ignite = Ignition.start();
IgniteAtomicSequence seq = ignite.atomicSequence("seqName",//序列名
 0, //初始值
true//如果序列不存在則創(chuàng)建
);
for (int i = 0; i < 20; i++) {
  long currentValue = seq.get();//獲取當(dāng)前值
  long newValue = seq.incrementAndGet();//先加1再取值
  ...
}

這個樣例中創(chuàng)建的seq,初始值從0開始,然后遞增,看上去很完美,但是當(dāng)系統(tǒng)不管什么原因重啟后,就又會從0開始,這顯然是無法保證唯一性的,因此這個方法還是不能在生產(chǎn)環(huán)境下使用。

3.基于IgniteAtomicSequence的分布式ID生成器

按照前述,直接按照初始值0創(chuàng)建IgniteAtomicSequence,是有很大風(fēng)險的,無法在生產(chǎn)環(huán)境下使用,而且存在長度不固定問題,所以還需要進(jìn)一步想辦法,研究的重點在于解決初始值的問題。 因為IgniteAtomicSequence的值為long型,而在Java中l(wèi)ong類型的最大值是9223372036854775807,這個數(shù)值長度為19位,對于實際應(yīng)用來說,是一個很大的值,但是對于常見的沒有環(huán)境依賴的ID生成器來說,還是比較短的。因此我們打算在這方面做文章。 因為系統(tǒng)重置的一個重要指標(biāo)就是時間,那么我們以時間作為參照,然后加上一個擴(kuò)展,可能是一個比較理想的選擇,我們以如下的規(guī)則作為初始值: 時間的yyyyMMddHHmmss+00000 這個長度正好是19位,然后每次加1,因為現(xiàn)在是2016年,這個規(guī)則在常規(guī)應(yīng)用場景中,是不會超過long類型的最大值的。 但是,這個規(guī)則存在一個風(fēng)險,就是假設(shè)不考慮實際應(yīng)用和實際性能,如果增加操作業(yè)務(wù)量特別大,會使這個序列值快速進(jìn)位,如果某個時間節(jié)點宕機(jī)后瞬間重啟,是有可能存在重啟后的初始值小于原來的最大值的,這時就無法保證唯一性了。下面就對這個理論情況下的最大值做一個計算,然后開發(fā)者就會知道在自己的應(yīng)用中如何改進(jìn)這個規(guī)則以滿足個性化需求了。

4.理論極限和性能

假定不考慮實際性能,我們以最簡單的情況為例,就是啟動后一秒鐘內(nèi)訪問達(dá)到峰值,然后宕機(jī)后瞬間重啟這種情況,這個很容易就能看出來,不需要計算,就是5個0對應(yīng)的最大值10萬,以此類推,考慮到時間的進(jìn)位和十進(jìn)制進(jìn)位的不同,我們可以計算出一分鐘后、一小時后、一天后、一月后、一年后宕機(jī)換算出的交易量的極大值,如下:

 每秒每分每小時每天每月每年
1秒10萬-----
1分16.6萬1000萬----
1小時27.7萬1666萬10億---
1天115萬6944萬41.66億1000億--
1月165萬9920萬59.5億3571.43億10萬億-
1年3215萬19億1157億2.7萬億83萬億1000萬億

以1分鐘為例進(jìn)行說明,假設(shè)初始值為2016011815341200000,一分鐘后宕機(jī)瞬間重啟,對應(yīng)的初始值為2016011815351200000,這個差額是10000000,對應(yīng)的每秒交易量為16.6萬。 從上圖來看,對于這樣的規(guī)則,能承載的交易量還是很大的,當(dāng)今世界最繁忙的交易系統(tǒng),也不會超過這個極限情況下的極值,也就是說,這個規(guī)則就目前來說,具有普遍適用性。 而在實際生產(chǎn)中,瞬間重啟是不存在的,隨著重啟時間向后推移,新的初始值會和原來的最大值拉開差距,更不可能出現(xiàn)沖突了。 關(guān)于性能,我在一臺2011年的舊筆記本上進(jìn)行測試,很容易就能達(dá)到50K/s的序列生成速度,這個還是可以的,但是這是在開啟預(yù)留的前提下實現(xiàn)的,如果不開啟預(yù)留,性能可能下降到13K/s。在一個具體的集群環(huán)境下,通常不會拿Ignite單獨建立服務(wù)做ID分發(fā)中心,所以實際環(huán)境下性能能不能滿足需求,開發(fā)者需要自行進(jìn)行測試,評估然后做選擇。另外,開啟了預(yù)留會導(dǎo)致最終生成的ID可能不是隨時間線性增長的,這個也需要注意。

5.常見分布式ID生成器對比

前述的基于Ignite的分布式ID生成器,優(yōu)點是實現(xiàn)簡單,將一個jar包嵌入應(yīng)用后ID生成系統(tǒng)和應(yīng)用生命周期一致,設(shè)置了備份后不存在單點故障,數(shù)值線性遞增可比較大小,規(guī)則按照業(yè)務(wù)定制后可以做得更短,如果轉(zhuǎn)成十六進(jìn)制后,會非常短,不依賴數(shù)據(jù)庫,不對數(shù)據(jù)庫產(chǎn)生壓力,缺點可能就是性能以及一些特定的業(yè)務(wù)需求了。 生成全局唯一ID的需求是剛性的,尤其是分布式環(huán)境中,問題顯得尤為復(fù)雜。當(dāng)前,這方面的實現(xiàn)方案非常多,通用的不通用的,本文不做詳細(xì)的論述,只做簡單的列舉:

  1. UUID 優(yōu)點是性能好,缺點是比較長,128位,無規(guī)則,無法比較大小。

  2. ID分發(fā)中心 比如twitter的snowflake服務(wù),可以做到高性能,高可用,低延遲,時間上有序,缺點就是使整個系統(tǒng)變得復(fù)雜,維護(hù)工作量加大。

  3. MongoDB的ObjectID(類似UUID) MongoDB的驅(qū)動中提供了objectId的生成功能,優(yōu)點是相對于UUID要短些,時間上有序,而且這個id包含了很多有用的信息,解碼后就可以獲得。

  4. 數(shù)據(jù)庫生成 有很多的基于數(shù)據(jù)庫的方案,比如基于Oracle和PostgreSQL的序列,F(xiàn)lickr和Instagram也有基于數(shù)據(jù)庫的比較復(fù)雜的方案。

  5. 其他 根據(jù)不同的業(yè)務(wù)場景,可以做出各種各樣的、滿足各種需求的ID生成方案,需求越多,實現(xiàn)也會越復(fù)雜。

“基于Ignite的分布式ID生成器怎么實現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI