亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

上兩篇講到了我們的系統(tǒng)在面臨大并發(fā)讀取的時(shí)候,采用了讀寫分離主從復(fù)制(數(shù)據(jù)庫(kù)讀寫分離方案,實(shí)現(xiàn)高性能數(shù)據(jù)庫(kù)集群)的方案去應(yīng)對(duì),后來(lái)又面臨了大并發(fā)寫入的時(shí)候,系統(tǒng)數(shù)據(jù)庫(kù)采用了分庫(kù)分表的方案(數(shù)據(jù)庫(kù)分庫(kù)分表方案,優(yōu)化大量并發(fā)寫入所帶來(lái)的性能問(wèn)題),通過(guò)垂直拆分以及水平拆分的方式,將數(shù)據(jù)分到多個(gè)庫(kù)和多個(gè)表中去應(yīng)對(duì)的,即現(xiàn)在是這樣的一套分布式存儲(chǔ)結(jié)構(gòu)。

數(shù)據(jù)庫(kù)分庫(kù)分表后,我們?cè)趺幢WCID全局唯一

 

數(shù)據(jù)庫(kù)分庫(kù)分表那篇也講到了,使用了分庫(kù)分表勢(shì)必會(huì)帶來(lái)和我們之前使用不大相同的問(wèn)題。今天,我將其中一個(gè)和我們開發(fā)息息相關(guān)的問(wèn)題提出來(lái)進(jìn)行講解,也就是我們開發(fā)中所使用的的主鍵的問(wèn)題。我們知道,以前我們單庫(kù)的時(shí)候,主鍵唯一ID是自增的,現(xiàn)在好了,我們的數(shù)據(jù)被分到多個(gè)庫(kù)的多個(gè)表里面了,如果我們還是使用之前的主鍵自增策略,那么這樣就會(huì)出現(xiàn)兩個(gè)數(shù)據(jù)插入到了兩個(gè)不同的表會(huì)出現(xiàn)相同的ID值,這時(shí)我們?cè)撛趺慈ナ褂媚兀?/p>

對(duì)于什么是主鍵,主鍵該怎么選,今天不做講解,我相信大家可能比我還精通,我們今天主要是講唯一主鍵ID在分布式存儲(chǔ)系統(tǒng)下怎么生成,保證ID的唯一性且符合我們業(yè)務(wù)需要,才是我們開發(fā)人員最關(guān)心的實(shí)戰(zhàn)。

UUID

這個(gè)時(shí)候,你可能會(huì)說(shuō),自增用不了,那我就是用UUID嘛,這個(gè)UUID生成出來(lái)的就是唯一的。的確,在我以前在一個(gè)公司中的確接觸到是使用UUID來(lái)生成唯一主鍵ID的,而且性能還可以。但是,我想提一點(diǎn)的就是,當(dāng)這個(gè)ID和我們業(yè)務(wù)交集不相關(guān)的時(shí)候是可以使用UUID生成主鍵的。比如,一般我們業(yè)務(wù)是需要用來(lái)做查詢的,而且最好是單調(diào)遞增的,這樣我們的UUID就很不適合了。

主鍵ID單調(diào)遞增有什么好處呢?

1,就拿我們用戶關(guān)注航班這個(gè)模塊來(lái)說(shuō),我們查看某個(gè)航班關(guān)注用戶按照時(shí)間的先后進(jìn)行排序。因?yàn)楝F(xiàn)在的ID是時(shí)間上有序的,所以現(xiàn)在我們就可以按照ID來(lái)進(jìn)行排序了,同時(shí)這樣對(duì)于有些并不是要存儲(chǔ)時(shí)間的業(yè)務(wù)來(lái)說(shuō),會(huì)減少不少的存儲(chǔ)空間。

2,有序的ID可以提升數(shù)據(jù)寫入的性能

我們知道主鍵其實(shí)在數(shù)據(jù)庫(kù)中就是一種索引,而索引在MySQL數(shù)據(jù)庫(kù)的B+數(shù)據(jù)結(jié)構(gòu)中是順序存儲(chǔ)的,所以每次插入的時(shí)候就是遞增排序的,直接追加到后面就行。如果是無(wú)序的話,則每次插入數(shù)據(jù)之前還得查找它應(yīng)該所在的位置,這無(wú)疑就會(huì)增加數(shù)據(jù)的異動(dòng)等相關(guān)的開銷,如下圖:

數(shù)據(jù)庫(kù)分庫(kù)分表后,我們?cè)趺幢WCID全局唯一

 

如上圖所示,如果我們生成的ID是有序的,那這個(gè) 50 就直接插在尾部就行了,如果是無(wú)序的話,突然生成了一個(gè) 26,我們還得先找到 26 需要存放的位置,然后還要對(duì)其后面數(shù)據(jù)進(jìn)行挪位置。

3,UUID不具備業(yè)務(wù)相關(guān)性

我們現(xiàn)在開發(fā)的項(xiàng)目都是依據(jù)公司業(yè)務(wù)開展的,而我們的唯一ID一般都是和業(yè)務(wù)有關(guān)系的,比如,有些訂單ID中帶上了時(shí)間的維度、機(jī)房的維度以及業(yè)務(wù)類型等維度。也就是為了我方便進(jìn)行定位是那種業(yè)務(wù)的訂單,才會(huì)這么設(shè)計(jì)的,是不是。

而UUID是由32位的16進(jìn)制數(shù)字組成的字符串,不僅在存儲(chǔ)空間上造成浪費(fèi),更不具備我們業(yè)務(wù)相關(guān)性。那我們?cè)撛趺唇鉀Q呢?其實(shí)twitter提出來(lái)的Snowflake 算法就能很好滿足我們現(xiàn)在的要求,滿足了主鍵ID的全局唯一性、單調(diào)遞增性,也可以滿足我們的業(yè)務(wù)相關(guān)。所以,我們現(xiàn)在使用的唯一ID生成方式就是使用Snowflake算法,這個(gè)算法其實(shí)很簡(jiǎn)單。下面我們來(lái)對(duì)其進(jìn)行講解,并對(duì)其相應(yīng)改造使其能用到我們的開發(fā)業(yè)務(wù)中來(lái)。

Snowflake 算法原理

Snowflake 是由 64 比特bit二進(jìn)制數(shù)字組成的,一共分為4大部分:

  • 1位默認(rèn)不使用
  • 41位時(shí)間戳
  • 10位機(jī)器ID
  • 12位序列號(hào)
數(shù)據(jù)庫(kù)分庫(kù)分表后,我們?cè)趺幢WCID全局唯一

 

  1. 我們從上圖中可以看出snowflake算法的第二部分的41位時(shí)間戳,大概可以支撐2^41/1000/60/60/24/365 年,也就是大約有69年。我們?cè)O(shè)計(jì)一個(gè)系統(tǒng)用69年應(yīng)該是足夠了吧。
  2. 10位的機(jī)器ID我們可以怎么使用呢?我們可以劃分成大概2到3位IDC,也就是可以支撐4到8個(gè)IDC機(jī)房;然后劃分7到 8 位的機(jī)器ID,即可以支撐128~256臺(tái)機(jī)器。
  3. 12位的序號(hào),就代表每個(gè)節(jié)點(diǎn)每毫秒可以生成4096個(gè)ID序號(hào)。

如何改造

我們現(xiàn)在已經(jīng)知道了Snowflake 算法的核心原理,并且知道了其有64位的二進(jìn)制數(shù)據(jù),那我們就可以根據(jù)自己業(yè)務(wù)進(jìn)行改造以更好的來(lái)為我們業(yè)務(wù)服務(wù)。一般不同的公司對(duì)其進(jìn)行改造的方式都不盡相同,但是道理都是一樣的。我們可以這么做:

  1. 我們是減少序列號(hào)的位數(shù),增加機(jī)器ID的位數(shù),是為了用來(lái)支撐我們單IDC的更多機(jī)器。
  2. 將我們業(yè)務(wù)ID加入進(jìn)去用來(lái)區(qū)分我們不同的業(yè)務(wù)。比如,1位0 + 41位時(shí)間戳 + 6位IDC(64個(gè)IDC) + 6位業(yè)務(wù)信息(支撐64種業(yè)務(wù)) + 10位自增序列(每毫秒1024個(gè)ID)
數(shù)據(jù)庫(kù)分庫(kù)分表后,我們?cè)趺幢WCID全局唯一

 

如此,我們就可以在單機(jī)房部署這么一個(gè)統(tǒng)一ID發(fā)號(hào)器,然后用Keeplive 保證高可用(對(duì)于高可用不熟悉的回去看看哈「高可用」你們服務(wù)器掛了怎么辦,我們是這樣做的)可以將不同的業(yè)務(wù)模塊ID加入進(jìn)去,這樣的好處是即使哪個(gè)業(yè)務(wù)出問(wèn)題了,我只看ID號(hào)我就分析出來(lái),比如,我看到現(xiàn)在ID號(hào)有我的訂單ID業(yè)務(wù),我就去看訂單模塊。

開發(fā)如何使用

現(xiàn)在我們知道Snowflake 算法原理了,還知道了我們可以進(jìn)行改造了。那我們開發(fā)人員該怎么去使用,來(lái)為我們業(yè)務(wù)生成統(tǒng)一的唯一ID呢?

1,直接嵌入到業(yè)務(wù)代碼

嵌入業(yè)務(wù)代碼的意思就是,這個(gè)snowflake算法就部署在和我們業(yè)務(wù)相同的服務(wù)器上,這樣我們代碼使用的時(shí)候,就不用了跨網(wǎng)絡(luò)調(diào)用,性能相對(duì)比較好。但是也是有缺點(diǎn)的,因?yàn)槲覀兊臉I(yè)務(wù)機(jī)器肯定是很多的,這就意味著我們發(fā)號(hào)器算法需要更多的機(jī)器ID位數(shù)。同時(shí),太多的業(yè)務(wù)服務(wù)器我們會(huì)很難保證業(yè)務(wù)機(jī)器id的唯一性,這里就需要引用zookeeper一致性組件來(lái)保證每次機(jī)器重啟都能能獲得唯一的機(jī)器ID。

2,獨(dú)立部署成發(fā)號(hào)器服務(wù)

也就是說(shuō),我們將其作為單獨(dú)的服務(wù)部署到單獨(dú)的機(jī)器上,已對(duì)外提供服務(wù)。這樣就是多了網(wǎng)絡(luò)的傳輸,不過(guò)影響不大,比如,我可以將其部署成一個(gè)主備的方式對(duì)外提供發(fā)號(hào)服務(wù),機(jī)器ID可以用作序列號(hào)使用,這樣也就是會(huì)有更多的自增序號(hào),有部分大廠就是以這樣單獨(dú)的服務(wù)提供出來(lái)的。

開發(fā)中避坑大法

1,雖然snowflake很優(yōu)秀,但是它是基于系統(tǒng)時(shí)間的,萬(wàn)一我們系統(tǒng)的時(shí)間不準(zhǔn)怎么辦,就會(huì)造成我們的ID會(huì)重復(fù)。那我們的做法就是,要利用系統(tǒng)的對(duì)時(shí)功能,一旦發(fā)現(xiàn)時(shí)間不一致,就暫停發(fā)號(hào)器,等到時(shí)鐘準(zhǔn)了在啟用。

2,還有一個(gè)坑比較關(guān)鍵,也是常發(fā)生的,就是當(dāng)我們的QPS并發(fā)不高的時(shí)候,比如每毫秒只生成一個(gè)ID號(hào),這樣就是直接結(jié)果是,每次生成的ID末尾都是1,這樣我們分庫(kù)分表就會(huì)出現(xiàn)問(wèn)題呀對(duì)吧,因?yàn)槲覀冇眠@個(gè)ID去分庫(kù)分表呀,會(huì)造成數(shù)據(jù)不均勻,是吧,忘記了去復(fù)習(xí)哈(數(shù)據(jù)庫(kù)分庫(kù)分表方案,優(yōu)化大量并發(fā)寫入所帶來(lái)的性能問(wèn)題)那我們?cè)趺唇鉀Q呢?

我們可以將時(shí)間戳記錄從毫秒記錄改為秒記錄,這樣我一秒可以發(fā)好多個(gè)號(hào)了

生成的序列號(hào)起始號(hào)隨機(jī)啟動(dòng),比如這一秒起始號(hào)是10,我下一秒隨機(jī)了變成了28,這樣就更加分散開了。

總結(jié),今天我們針對(duì)分庫(kù)分表之后帶來(lái)的第一個(gè)直接影響我們開發(fā)的問(wèn)題,就是主鍵ID唯一性的問(wèn)題,然后說(shuō)到了使用Snowflake算法去解決,并且對(duì)其原理和使用進(jìn)行了詳細(xì)的講解,同時(shí),還將其在使用中遇到的坑給講出來(lái)了,也對(duì)其進(jìn)行了填坑分析,讓大家直接避免遇到同樣的問(wèn)題。當(dāng)然生成唯一ID有多種,我們根據(jù)業(yè)務(wù)選擇合適我們自己的就好,你們是基于什么方式生成的可以也可以告訴大家。

分享到:
標(biāo)簽:分庫(kù)分表
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定