日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

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

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

在分布式系統(tǒng)中,通常會(huì)用到分布式ID來標(biāo)注數(shù)據(jù)的唯一性,而分布式ID的生成方式又多種多樣,今天我們就來討論一下主流的分布式ID生成策略。

分布式ID基本需求

  • 全局唯一
  • 趨勢遞增
  • 信息安全

全局唯一

這是基本要求,不必解釋

趨勢遞增

為什么要趨勢遞增呢?

第一,由于我們的分布式ID,是用來標(biāo)識(shí)數(shù)據(jù)唯一性的,所以多數(shù)時(shí)候會(huì)被定義為主鍵或者唯一索引。

第二,并且絕大多數(shù)互聯(lián)網(wǎng)公司使用的數(shù)據(jù)庫是:MySQL,存儲(chǔ)引擎為innoDB。

對于 B+Tree這個(gè)數(shù)據(jù)結(jié)構(gòu)來講,數(shù)據(jù)以自增順序來寫入的話,b+tree的結(jié)構(gòu)不會(huì)時(shí)常被打亂重塑,存取效率是最高的。

信息安全

由于數(shù)據(jù)是遞增的,所以,惡意用戶的可以根據(jù)當(dāng)前ID推測出下一個(gè),非常危險(xiǎn),所以,我們的分布式ID盡量做到不易被破解。

數(shù)據(jù)庫主鍵自增(Flicker)

基于數(shù)據(jù)庫主鍵自增的方案,名為 Flicker。

主要是利用MySQL的自增主鍵來實(shí)現(xiàn)分布式ID。

以下為 Flicker實(shí)現(xiàn)分布式ID的主流做法:

1、需要單獨(dú)建立一個(gè)數(shù)據(jù)庫實(shí)例:flicker

create database `flicker`;

2、創(chuàng)建一張表:sequence_id

create table sequence_id(
 id bigint(20) unsigned NOT NULL auto_increment, 
 stub char(10) NOT NULL default '',
 PRIMARY KEY (id),
 UNIQUE KEY stub (stub)
) ENGINE=MyISAM;

為什么用 MyISAM?不用 InnoDB?個(gè)人推測原因是: flicker算法出來的時(shí)候,MySQL的默認(rèn)引擎還依舊是 MyISAM而不是 InnoDB,作者只是想用默認(rèn)引擎而已,并無其他原因。

  • stub: 票根,對應(yīng)需要生成 Id 的業(yè)務(wù)方編碼,可以是項(xiàng)目名、表名甚至是服務(wù)器 IP 地址。
  • stub 要設(shè)置為唯一索引

3、使用以下SQL來獲取ID

REPLACE INTO ticket_center (stub) VALUES ('test'); 
SELECT LAST_INSERT_ID(); 

Replaceinto 先嘗試插入數(shù)據(jù)到表中,如果發(fā)現(xiàn)表中已經(jīng)有此行數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷)則先刪除此行數(shù)據(jù),然后插入新的數(shù)據(jù), 否則直接插入新數(shù)據(jù)。

一般 stub為特殊的相同的值。

這樣,一個(gè)分布式ID系統(tǒng)算是可以搭建運(yùn)行了。但是,有人要問:“這是一個(gè)單實(shí)例、單點(diǎn)的系統(tǒng),萬一掛了,豈不是影響所有關(guān)聯(lián)的業(yè)務(wù)方?”

改進(jìn)升華

是的。確實(shí)如此,因此又有人說:“可以利用MySQL主從模式,主庫掛了,使用從庫。”

這只能算是一種比較low的策略,因?yàn)槿绻鲙鞉炝耍瑥膸鞗]來得及同步,就會(huì)生成重復(fù)的ID。

有沒有更好的方法呢?

我們可以使用“雙主模式“,也就是有兩個(gè)MySQL實(shí)例,這兩個(gè)都能生成ID。

如圖所示,我們原來的模式:

圖解各路分布式ID生成算法

 

雙主模式是該怎么樣呢?如何保持唯一性?

我們可以讓一臺(tái)實(shí)例生成奇數(shù)ID,另一臺(tái)生成偶數(shù)ID。

奇數(shù)那一臺(tái):

set auto_increment_offset=1;--起始值
set auto_increment_increment=2;--步長

偶數(shù)那一臺(tái):

set auto_increment_offset=2;--起始值
set auto_increment_increment=2;--步長

當(dāng)兩臺(tái)都OK的時(shí)候,隨機(jī)取其中的一臺(tái)生成ID;若其中一臺(tái)掛了,則取另外一臺(tái)生成ID。

如圖所示:

圖解各路分布式ID生成算法

 

細(xì)心會(huì)發(fā)現(xiàn),N個(gè)節(jié)點(diǎn),只要起始值為1,2,...N,然后步長為N,就會(huì)生成各不相同的ID。(PS:后文有推導(dǎo)公式)

總結(jié)

優(yōu)點(diǎn):

  • 簡單。充分利用了數(shù)據(jù)庫自增 ID 機(jī)制,生成的 ID 有序遞增。
  • ID遞增

缺點(diǎn):

  • 并發(fā)量不大。
  • 水平擴(kuò)展困難,系統(tǒng)定義好了起始值、步長和機(jī)器臺(tái)數(shù),跑起來之后,添加額外的機(jī)器困難。
  • 安全系數(shù)低

redis

Redis為單線程的,所以操作為原子操作,利用 incrby命令可以生成唯一的遞增ID。

原理

圖解各路分布式ID生成算法

 

單機(jī)單點(diǎn),吞吐不夠,加集群

圖解各路分布式ID生成算法

 

假設(shè)N個(gè)節(jié)點(diǎn),則步長為N,節(jié)點(diǎn)起始值為1,2,…… N。則三個(gè)節(jié)點(diǎn)生成的ID一定不同!

想想為什么?

以上信息條件可以轉(zhuǎn)化為數(shù)學(xué)推理: 1+x*N=2+y*N且x、y、N都為整成數(shù)且N不為1,試問等式存不存在?

答:
假設(shè)存在在起始值是1的節(jié)點(diǎn)上疊加x次之后等于起始值為2、疊加y次的值,
既 “1 + x * N = 2 + y * N” 等式成立
則:
x * N = 1 + y * N
x * N - y * N = 1
(x - y) * N = 1
(x - y) = 1 / N
又因?yàn)?x、y都為整成數(shù);
所以x - y 必為整成數(shù);
又因?yàn)橹挥蠳等于1的時(shí)候,1/N才為整成數(shù);
與條件N為1不符合,所以不存在。

同理可證 1+x*N=3+y*N和 2+x*N=3+y*N也是如此。

優(yōu)點(diǎn)

  • 性能顯然高于基于數(shù)據(jù)庫的 Flicker方案
  • ID遞增

缺點(diǎn)

  • 水平擴(kuò)展困難
  • Redis集群宕機(jī)可能會(huì)產(chǎn)生重復(fù)的id
  • 易破解

UUID

想必這個(gè)大家都熟悉。 UUID是通用唯一識(shí)別碼(Universally Unique Identifier)的縮寫,是一種軟件建構(gòu)的標(biāo)準(zhǔn),亦為開放軟件基金會(huì)組織在分布式計(jì)算環(huán)境領(lǐng)域的一部分。

原理

圖解各路分布式ID生成算法

 

UUID是由一組32位數(shù)的16進(jìn)制數(shù)字所構(gòu)成,是故UUID理論上的總數(shù)為16^32 = 2^128,約等于3.4 x 10^38。也就是說若每納秒產(chǎn)生1兆個(gè)UUID,要花100億年才會(huì)將所有UUID用完。

UUID是利用同一時(shí)空中的所有機(jī)器都是唯一的這一規(guī)則來確保唯一性的。

圖解各路分布式ID生成算法

 

具體外形為:

圖解各路分布式ID生成算法

 

通常由以下幾部分組成:

  • 系統(tǒng)時(shí)間
  • 時(shí)鐘序列
  • 全局唯一的IEEE機(jī)器識(shí)別,如網(wǎng)卡mac、機(jī)器SN等

生成方式多種多樣,業(yè)界公認(rèn)的是五種,分別是uuid1,uuid2,uuid3,uuid4,uuid5。

目前使用最廣泛的UUID是微軟的 GUID。

優(yōu)點(diǎn)

  • 本地生成,性能極佳。無網(wǎng)絡(luò)消耗
  • 全局唯一

缺點(diǎn)

  • 存儲(chǔ)麻煩。16字節(jié)128位,通常以36長度的字符串表示,很多場景不適用
  • 通常是字符串,非自增,無序,不利于做主鍵。每次插入都會(huì)對B+tree結(jié)構(gòu)進(jìn)行修改
  • 破解相對困難,但是也不安全。參考"梅麗莎病毒事件,病毒作者制作的UUID包含Mac地址,被警方破解后,直接定位,抓捕歸案"

snowflake

snowflake即雪花算法,Twitter發(fā)明的。

原理

外形長這樣:

圖解各路分布式ID生成算法

 

  • 1位不用。二進(jìn)制中最高位為1的都是負(fù)數(shù),但是我們生成的id一般都使用整數(shù),所以這個(gè)最高位固定是0。
  • 41位,用來記錄毫秒的時(shí)間戳。41位可以表示的數(shù)值范圍是:0 至 2^{41}-1,減1是因?yàn)榭杀硎镜臄?shù)值范圍是從0開始算的,而不是1,轉(zhuǎn)化為年則是 2^{41}-1)/(1000*60*60*24*365)=69年。
  • 10位,用來記錄工作機(jī)器id。最多可以部署在2^{10} = 1024個(gè)節(jié)點(diǎn),我們可以根據(jù)具體的業(yè)務(wù)來定制具體分配的機(jī)器數(shù)量和每臺(tái)機(jī)器1毫秒產(chǎn)生的id序號(hào)number數(shù)。例如可以把10bit分5bit給IDC,分5bit給工作機(jī)器。這樣就可以表示32個(gè)IDC,每個(gè)IDC下可以有32臺(tái)機(jī)器,可以將內(nèi)容配置在配置文件中,服務(wù)去獲取。
  • 12位。用來表示單臺(tái)機(jī)器每毫秒生成的id序號(hào),12位bit可以表示的最大正整數(shù)為2^12 - 1 = 4096,若超過4096,則重新從0開始。即,每臺(tái)機(jī)器1毫秒內(nèi)最多產(chǎn)生4096個(gè)ID,足夠用了。

最后將上述4段bit通過位運(yùn)算拼接起來組成64位bit.

由于是64位bit,所以完全可以用數(shù)字來表示ID。

基本是根據(jù):

圖解各路分布式ID生成算法

 

優(yōu)點(diǎn)

  • ID為數(shù)字且時(shí)間位在高位,整個(gè)ID都是趨勢遞增的。
  • 不依賴任何第三方庫,完全可以自己寫,且性能非常高。
  • 可根據(jù)業(yè)務(wù)定制分配bit位,非常靈活。得益于 10位機(jī)器IDbit位。
  • 不太容易破解

缺點(diǎn)

  • 依賴機(jī)器的時(shí)間,如果機(jī)器時(shí)間不準(zhǔn)或者回?fù)埽赡軐?dǎo)致重復(fù)

總結(jié)

在國內(nèi)也得到了比較普遍的應(yīng)用,各大廠根據(jù)其基本原理,生成了自己的規(guī)則:

  • 百度的uid-generator:https://github.com/baidu/uid-generator
  • 美團(tuán)Leaf:https://github.com/zhuzhong/idleaf

請關(guān)注我的微信公眾號(hào) 互聯(lián)網(wǎng)技術(shù)窩,問題直接在公眾號(hào)內(nèi)留言即可

參考文獻(xiàn):

[flicker算法原文] http://code.flickr.com/blog/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/

[分布式唯一ID極簡教程] https://mp.weixin.qq.com/s/cqIK5Bv1U0mT97C7EOxmnA

[分布式 ID 生成策略] https://mp.weixin.qq.com/s/UAvSUDFJ8Fr0a-Na2Vr22g

[分布式ID系列(2)——UUID適合做分布式ID嗎] https://mp.weixin.qq.com/s/kZAnYzJj4aBrtsk8Q9wA

https://segmentfault.com/a/1190000011282426

https://juejin.im/post/5d6fc8eff265da03ef7a324b#comment

https://segmentfault.com/a/1190000010978305

[Leaf——美團(tuán)點(diǎn)評分布式ID生成系統(tǒng)] https://tech.meituan.com/2017/04/21/mt-leaf.html

[UUID的含義及實(shí)現(xiàn)原理]https://blog.csdn.net/reggergdsg/article/details/92091404

[通用唯一標(biāo)識(shí)碼UUID的介紹及使用] https://mp.weixin.qq.com/s/BjCL076USuhLj9GjhXDaTA

[UUID簡史] https://www.infoq.cn/article/talk-about-the-history-of-uuid/?utmsource=tuicool&utmmedium=referral

分享到:
標(biāo)簽:分布式 算法 ID
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

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

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

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

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

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

答題星2018-06-03

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

全階人生考試2018-06-03

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

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

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

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

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

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定