中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

生成全局唯一 ID 的 3 個(gè)思路

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

標(biāo)識(shí)(ID / Identifier)是無處不在的,生成標(biāo)識(shí)的主體是人,那么它就是一個(gè)命名過程,如果是計(jì)算機(jī),那么它就是一個(gè)生成過程。如何保證分布式系統(tǒng)下,并行生成標(biāo)識(shí)的唯一與標(biāo)識(shí)的命名空間有著密不可分的關(guān)系。在世界里,「潛意識(shí)下的命名空間里,相對的唯一標(biāo)識(shí)」是普遍存在的,例如:

  1. 每個(gè)人出生的時(shí)候,就獲得了一個(gè)「相對的唯一標(biāo)識(shí)」——姓名。

  2. 城市的道路,都基本上采用了唯一的命名(當(dāng)然這也需要一個(gè) 過程 )。

顯然,對于每個(gè)標(biāo)識(shí),都需要有一個(gè)命名空間(namespace),來保證其相對唯一性。

可以說,在人的意識(shí)里,對于的實(shí)體的描述是基于名字進(jìn)行的,人們并不希望同名的出現(xiàn)太多,這會(huì)在溝通過程中的產(chǎn)生理解困難。

對于人來說,在家庭里會(huì)有小名,在社會(huì)中會(huì)有正式名字,在社交過程中還會(huì)產(chǎn)生綽號(hào)。

在中國,對于企業(yè)來說,除了企業(yè)有名稱之外,還有組織機(jī)構(gòu)代碼證、有稅務(wù)登記證、有工商營業(yè)執(zhí)照,并分別對應(yīng)三個(gè)編號(hào)。(當(dāng)然,目前五證合一也在進(jìn)行中)。

回到計(jì)算機(jī)領(lǐng)域,圍繞主機(jī)在網(wǎng)絡(luò)上的地址,在不同的命名空間中,都會(huì)存在一個(gè)「相對的唯一標(biāo)識(shí)」用來描述一個(gè)實(shí)體:

  1. 每個(gè)以太網(wǎng)網(wǎng)卡,都有一個(gè)48-bit 的MAC地址

  2. 每個(gè)MAC地址,可能有一個(gè)或者多個(gè)IP地址

  3. 每個(gè)網(wǎng)卡,都可能有一個(gè)或者多個(gè)IP地址

  4. 每個(gè)IP地址,都可能有多個(gè)域名

  5. 當(dāng)然,每個(gè)主機(jī),都會(huì)有一個(gè)主機(jī)名

接續(xù)上面的例子,事實(shí)上,MAC地址是由 IEEE Standards Association Registration Authority 完成地址段的分配。

對于目前的 1530 個(gè)頂級根域(gTLD),以及 IPv4 / IPv6 地址,都由IANA對其進(jìn)行管理。

上面我通過類比的方式簡單介紹了標(biāo)識(shí),總結(jié)來說它是無處不在的。我們在理解技術(shù)里的ID的同時(shí),一定要聯(lián)系生活中的場景,對比著琢磨和分析。

  • 標(biāo)識(shí)是從一個(gè)典型的場景,對客觀事物進(jìn)行統(tǒng)一編碼的過程。

  • 采用 半集中與半自主相結(jié)合 的方法,是一種實(shí)現(xiàn)「分而治之」十分普遍和有效的設(shè)計(jì)模式。

  • 標(biāo)識(shí)的唯一性是根據(jù)命名空間緊密相關(guān)的。

標(biāo)識(shí)的使用

在不同命名空間中實(shí)現(xiàn)標(biāo)識(shí)的轉(zhuǎn)換

在中國,對于人名,通常是由公安局出入境管理局完成中文至英文的翻譯,同時(shí),他們會(huì)把翻譯結(jié)果寫到數(shù)據(jù)庫中,印到護(hù)照上。 這中間的翻譯規(guī)則,通常是根據(jù)中文與漢語拼音、漢語拼音與英文字母的兩次轉(zhuǎn)換關(guān)系完成的。

對于計(jì)算機(jī)網(wǎng)絡(luò),則會(huì)有 NAT完成IP地址間的轉(zhuǎn)換,RAP/RARP完成IP地址與MAC地址的雙向轉(zhuǎn)換,DNS完成域名至IP地址的轉(zhuǎn)換。

可是,為什么需要那么多不同命名空間的標(biāo)識(shí)標(biāo)識(shí)一個(gè)實(shí)體?可能最直觀的回答通常是這樣:

  • 域名為了方便人的記憶與使用

  • IP地址是為了更廣范圍的計(jì)算機(jī)互聯(lián)

  • MAC則是為了在物理上保證唯一

  • OSI開放系統(tǒng)互聯(lián)7層模型決定的

人們會(huì)在不同的領(lǐng)域(也是命名空間)中定義自己的命名規(guī)范,這可以認(rèn)為是領(lǐng)域主權(quán)的體現(xiàn),同時(shí)伴生的會(huì)是一套與相關(guān)領(lǐng)域標(biāo)識(shí)的轉(zhuǎn)換協(xié)議。

結(jié)構(gòu)化與別名效應(yīng)

結(jié)構(gòu)化是把數(shù)據(jù)的元信息以位置的方式固化是數(shù)據(jù)中。也就是說,代表某個(gè)意義的信息,一定會(huì)出現(xiàn)在一個(gè)約定好的位置上。

由于標(biāo)識(shí)是被人經(jīng)常使用的,那么在使用過程中會(huì)對大腦形成一定的訓(xùn)練。

人在看到了010-XXXXXXXX,021-XXXXXXXX號(hào)碼之后,自然而言會(huì)產(chǎn)生條件反射,認(rèn)為兩者分別代表了北京和上海;同樣的人在看到了139和186之后,分別產(chǎn)生了中國移動(dòng)以及中國聯(lián)通的運(yùn)營商聯(lián)想。

對于使用者,這種場景,數(shù)字類似是一個(gè)名稱別名。對于程序員,這十分接近「數(shù)據(jù)字典」的設(shè)計(jì)模式。

標(biāo)識(shí)轉(zhuǎn)換過程的兩面性

別名和正名,同樣是來自于兩個(gè)不同命名空間的標(biāo)識(shí),之間自然而然的會(huì)進(jìn)行轉(zhuǎn)換。

當(dāng)然,人們也不會(huì)忘記去Hack這些轉(zhuǎn)換協(xié)議的設(shè)計(jì)。

一些是有益的,是實(shí)現(xiàn)了更為便利的應(yīng)用場景。例如:將不同的域名指向相同的IP地址(使用A或者CNAME記錄),并結(jié)合相關(guān)軟硬件實(shí)現(xiàn)「虛擬主機(jī)」,達(dá)到資源復(fù)用的目的。

一些卻是有害的,例如,詐騙電話也經(jīng)常采用改號(hào)的方法,讓接聽者誤以為那是來自某個(gè)官方的外呼電話。

同樣的,在計(jì)算機(jī)領(lǐng)域,一樣有DNS劫持、DNS污染。

有矛就有盾,進(jìn)行安全性擴(kuò)展的 DNSSEC 就是為了對DNS結(jié)果,驗(yàn)證不存在性和校驗(yàn)數(shù)據(jù)完整性驗(yàn)證,不過依然沒有實(shí)現(xiàn)全面部署。

小結(jié)

  • 在關(guān)注如何生成標(biāo)識(shí)的同時(shí),還需要關(guān)注標(biāo)識(shí)的易用性和直觀性

    不同命名空間的標(biāo)識(shí),在互通時(shí)需要進(jìn)行轉(zhuǎn)換

  • 轉(zhuǎn)換的過程,可能是一個(gè)簡單的規(guī)則,也可能是一個(gè)獨(dú)立第三方服務(wù)

  • 標(biāo)識(shí)的唯一性是基本訴求,同時(shí)嵌入其他維度的信息是減少實(shí)時(shí)關(guān)聯(lián)查詢的有效手段

思路一:基于數(shù)據(jù)庫生成

標(biāo)識(shí)的生成方法有很多,有集中式的,分布式的;有后端的,前端的,當(dāng)然還有人工的。 并沒有一種通用的生成方法來適應(yīng)各種應(yīng)用場景。

人工生成的確是一種方式,比如電子郵箱,微信ID,各種論壇的賬號(hào)。在人想出標(biāo)識(shí)的那一刻,是無法判斷是否是唯一的,對這種生成方式的結(jié)果,顯然在錄入時(shí)都需要進(jìn)行唯一性校驗(yàn)。所以,下面描述的幾種生成方式,是在生成的那一刻就在一個(gè)命名空間內(nèi)唯一,而不再需要進(jìn)行唯一性校驗(yàn)。

而基于數(shù)據(jù)庫生成,一般包含以下幾種:

  • MySQL(5.6) AUTO_INCREMENT 特性

  • Postgres(REL 9.6 Stable) SEQUENCE 特性

  • Oracle 數(shù)據(jù)庫的 SEQUENCE 特性,有知道這一特性如何實(shí)現(xiàn)的,可以在 知乎 做一下解答。

  • Flickr Ticket Servers ,同時(shí)支持Sharding (文章發(fā)表于2010年2月8日,算法上線于2006年1月13日)。

一般地,這種類型的生成方案,都可以設(shè)置其實(shí)初始值,以及增量步長。

思路二:基于分布式集群協(xié)調(diào)器生成

在不使用數(shù)據(jù)庫的情況下,通過一個(gè)后臺(tái)服務(wù)對外提供高可用的、固定步長標(biāo)識(shí)生成,則需要分布式的集群協(xié)調(diào)器進(jìn)行。

一般的,主流協(xié)調(diào)器有兩類:

  • 以強(qiáng)一致性為目標(biāo)的:ZooKeeper為代表

  • 以最終一致性為目標(biāo)的:Consul為代表

ZooKeeper的強(qiáng)一致性,是由Paxos協(xié)議保證的;Consul的最終一致性,是由Gossip協(xié)議保證的。

在步長累計(jì)型生成算法中,最核心的就是保持一個(gè)累計(jì)值在整個(gè)集群中的「強(qiáng)一致性」。同時(shí),這也會(huì)為唯一性標(biāo)識(shí)的生成帶來新的形成瓶頸。

思路三:劃分命名空間并行生成

似乎對于分布式的ID生成,以Twitter Snowflake為代表的, Flake 系列算法,經(jīng)?梢员凰阉饕嬲业,但似乎MongoDB的ObjectId算法,更早地采用了這種思路。MongoDB 1.0 是在2009年8月27日 發(fā)布 的,并且0.9.10(2009年8月24日發(fā)布)和1.0兩個(gè)版本沒有差異。

在StackOverflow上,最早的一個(gè)關(guān)于ObjectId的問題( http://stackoverflow.com/questions/2138687/whats-mongodb-hashs-size/2146071 ),時(shí)間是2010年1月27日。不知道Twitter的同學(xué),是不是受此啟發(fā)呢?

MongoDB ObjectId

12-byte MongoDB ObjectId 的結(jié)構(gòu)是:

  • a 4-byte value representing the seconds since the Unix epoch,

  • a 3-byte machine identifier,

  • a 2-byte process id, and

  • a 3-byte counter, starting with a random value.

可以看出,這個(gè)方案所支持的最小劃分粒度是「秒 * 進(jìn)程實(shí)例」,單進(jìn)程實(shí)例的每秒容量是 3-byte (24-bit),也就是接近16777216個(gè)ID。

有興趣的,還可以進(jìn)一步 看代碼(MonogoDB 3.3.x Java Driver) 研究:Timestamp, Machine Identifier、Process Identifier、計(jì)數(shù)器的初始值分別是如何獲得的:

1. Timestamp

2. Machine Identifier

3. Process ID

4. COUNTER

此處需要注意的是MongoDB的 NEXT_COUNTER 其初始值是一個(gè)隨機(jī)數(shù),這是有利于分庫分表的。因?yàn)樵谛〔l(fā)的條件下,非隨機(jī)數(shù)的初始值,容易產(chǎn)生 偏庫偏表, 不均勻的現(xiàn)象。

Twitter Snowflake

Twitter在2010年6月1日(在Flickr那篇文章發(fā)布不到4個(gè)月之后),Ryan King 在Twitter的Blog 撰文 寫道:

  • Ticket Servers方案缺乏順序的保證

  • 考慮過采用UUID,不過128-bit太長了

  • 也考慮過采用ZooKeeper所提供的 *Unique Naming* Seuence Nodes 所提供的 Unique Naming 特性,但是性能不能滿足。(個(gè)人認(rèn)為,Sequence Nodes的設(shè)計(jì)目標(biāo)是解決分布式鎖的問題,但不解決性能要求極高的ID生成問題,直接應(yīng)用是一種Hack行為)

在這種情況下,Twitter給出了 64-bit 長的 Snowflake ,它的結(jié)構(gòu)是:

  • 1-bit reserved

  • 41-bit timestamp

  • 10-bit machine id

  • 12-bit sequence

在過了不到4年,2014年的5月31日,Twitter 更新了 Snowflake 的 README,其中陳述了兩個(gè)容易被忽視的事實(shí):

  • "We have retired the initial release of Snowflake ..."

  • "... heavily relies on existing infrastructure at Twitter to run. "

可以看出,這個(gè)方案所支持的最小劃分粒度是「毫秒 * 線程」,單線程(Snowflake 里對應(yīng)的概念是 Worker)的每秒容量是12-bit,也就是接近4096。

翻一下Snowflake的 歸檔代碼 (Scala),可以看到:

1. 關(guān)于初始化Sequence的處理

可以看到此處Snowflake對于 sequence 的賦值為0。

2. 關(guān)于每秒超過4096個(gè)ID生成請求的處理

noeqd

2011年11月23日,用Go語言實(shí)現(xiàn)的,基于Snowflake的 neoqd 出現(xiàn)了。

它的特點(diǎn)是,除了使用Go語言進(jìn)行了實(shí)現(xiàn),更是把ID生成做成了一個(gè)網(wǎng)絡(luò)服務(wù)。支持客戶端向ID生成服務(wù)申請ID。它還支持:

  • 簡單預(yù)共享Token的客戶端身份證認(rèn)證(只是加強(qiáng)了那么一點(diǎn)點(diǎn)的安全性,可以忽略)

  • 支持批量獲取ID,最多256個(gè)(因?yàn)槭褂靡粋(gè)byte表示申請個(gè)數(shù))

同時(shí),作者還建議使用 Doozerd 一個(gè)用Go語言寫的 -- a highly-available, completely consistent store for small amounts of extremely important data. 進(jìn)行Machine ID的分配。

(關(guān)于 ZooKeeper / Etcd / Consul / Doozerd 的比較,也是可以期待下)

Boundary Flake

2012年1月, Boundary Flake 同樣的,用Erlang語言把Snowflake,變成了一個(gè)網(wǎng)絡(luò)服務(wù),提供128-bit長的ID生成服務(wù)。

不過,根據(jù)其RoadMap的描述,這個(gè)項(xiàng)目并沒100%完成。例如,批量的ID生成,HTTP 接口,客戶端Library都列在里面待實(shí)現(xiàn)。

CruftFlake

2012年7月, CruftFlake 更顯然的,是想以一個(gè)PHP變種身份出現(xiàn)。

它在結(jié)構(gòu)上與Snowflake基本一致,存在兩個(gè)區(qū)別:

  • 在timestamp上的取值略有區(qū)別

  • 可以自行決定是否采用ZooKeeper作為協(xié)調(diào)器

基于LableOrg/java-uniqueid

2014年7月18日,LableOrg 寫了一個(gè)通過ZooKeeper進(jìn)行協(xié)調(diào)的,128-bit長的算法 java-uniqueid。其 結(jié)構(gòu)組成 依然十分相似:

  • Timestamp

  • Sequence counter

  • Generator IDs

  • Cluster IDs

前臺(tái)瀏覽器生成

這里的前臺(tái),主要是指以「瀏覽器」為代表的客戶端。

2015年2月16日,Sudhanshu Yadav (看面相像印度人),用Javascript寫了Flake的又一個(gè)變種實(shí)現(xiàn) FlakeId 。其核心代碼是:

它的Machine Identifier則是作為構(gòu)造函數(shù)的選項(xiàng)參數(shù) options.mid 傳入。

沒思路,全自主隨機(jī)生成?

選擇UUID?

可以說,成熟的、全自主生成方案,可能只有 128-bit UUID 一種,具體的說,是UUID Version 4。另外,微軟對它實(shí)現(xiàn),稱之為 GUID 。

一般的,使用的最多的是UUID Version 4,很大程度上是因?yàn)槠湟蕾嚨钠渌⻊?wù)最少。

這里,通過python (2.5+) 對UUID的實(shí)現(xiàn),體驗(yàn)一下UUID的生成效果:

另外,我們看一下網(wǎng)卡的MAC地址:

(因?yàn)閁UID Version 1會(huì)泄露網(wǎng)卡的MAC地址,所以我對MAC地址做了下小手術(shù))

可以看到UUID Version 1 最后一組數(shù)值 985aeb899615 與網(wǎng)卡的 MAC地址是一樣一樣的 98:5a:eb:89:96:15。

個(gè)人一直認(rèn)為,采用UUID Version 4是一種偷懶的,沒有針對具體應(yīng)用場景,缺乏必要設(shè)計(jì)的做法。

一方面,它是依據(jù)概率確保無碰撞的,計(jì)算的過程與概率上的「生日問題」是一樣的,不再展開。

另一方面,從使用的角度,UUID還有以下缺點(diǎn):

  • 太長,即便是轉(zhuǎn)換成36個(gè)字符,不利于輸入

  • 過于隨機(jī),沒有規(guī)律,在開發(fā)調(diào)試、線上故障定位,都容易看花眼。

  • 如果作為數(shù)據(jù)庫主鍵,對索引不利。

基于Hash算法?

眾多的Hash算法,例如「MD5 / SHA-1 / SHA-2 / SHA-3」,都看可以對內(nèi)容進(jìn)行摘要計(jì)算,形成一個(gè)定長的Hash值。

這些Hash算法,都會(huì)存在一個(gè)Hash沖突的問題,以及碰撞攻擊的問題。

以UUID類似,其文本化之后的隨機(jī)特征,不太適合應(yīng)用在ID生成方面。

標(biāo)識(shí)生成總結(jié)

  • 人工生成的標(biāo)識(shí),在相同的命名空間里,需要后續(xù)唯一性驗(yàn)證才能保證唯一

  • 由計(jì)算機(jī)生成,在低并發(fā)的場景下,適合通過一個(gè)服務(wù)集中生成,并保障此服務(wù)的高可用性

  • 由計(jì)算機(jī)生成,在高并發(fā)的場景下,適合通過一個(gè)保障命名空間獨(dú)立的命名規(guī)范下,由多個(gè)服務(wù)并行生成。

  • 采用步長和增長相結(jié)合的生成算法,本質(zhì)上都是對某個(gè)狀態(tài)進(jìn)行累積的結(jié)果。

  • 對于取模進(jìn)行分庫分表的場景,初始化值隨機(jī)有利于均勻分布。

  • (MongoDB 的 ObjectId 更是Flake系列算法的鼻祖,并在初始值上進(jìn)行了隨機(jī)化處理)

設(shè)計(jì)一個(gè)「合適」的標(biāo)識(shí)

1. 區(qū)分實(shí)體和關(guān)系

實(shí)體是點(diǎn),而關(guān)系是線。

一般而言,面向?qū)嶓w的標(biāo)識(shí)生成速度,要小于面向關(guān)系的生成速度。

具體的例子,以電商為例:買家、賣家、商品這些實(shí)體的錄入速度,要遠(yuǎn)比訂單生成小的多。也因此,主數(shù)據(jù)要比交易數(shù)據(jù)穩(wěn)定的多。

并且,關(guān)系還可能包含層次關(guān)系,進(jìn)而體現(xiàn)為一個(gè)依賴樹。

面向?qū)嶓w的標(biāo)識(shí)

面向?qū)嶓w的標(biāo)識(shí),更多的與概念相關(guān)(名稱)、與形態(tài)相關(guān)(型號(hào)),有很多的人為因素參與,隨機(jī)因素有限,命名的主體也來自于人。

對于實(shí)體制造,為任意一個(gè)產(chǎn)品進(jìn)行標(biāo)識(shí),大致會(huì)分為六個(gè)方面:品牌、品類、品名,型號(hào)、批號(hào)、產(chǎn)品序列號(hào)。

對于前四者,更多的是人為的進(jìn)行命名。例如,給定中文,找到對應(yīng)英文,再進(jìn)行縮寫。

對于批號(hào),則會(huì)增加一些時(shí)間因素,以關(guān)聯(lián)到產(chǎn)品的生產(chǎn)時(shí)間。例如,采用20160925表示具體某一天,或者采用201640表示具體某一周。(一般來說,同一個(gè)批號(hào)的產(chǎn)品,所使用的原材料是也是同一批。)

對于產(chǎn)品序列號(hào),最簡單的是采用自然數(shù)法進(jìn)行編號(hào)。

這一類的標(biāo)識(shí),在分布式系統(tǒng)下,在系統(tǒng)并發(fā)量小,集群規(guī)模小的情況下,可以采用基于數(shù)據(jù)庫或者協(xié)調(diào)器的生成方案。

面向關(guān)系的標(biāo)識(shí)

自然的,關(guān)系源于兩個(gè)或兩個(gè)以上的實(shí)體之間所進(jìn)行的某一個(gè)活動(dòng),并且具有一定的時(shí)效性。

常見的關(guān)系的表現(xiàn)形式有:交易流水號(hào),會(huì)話標(biāo)識(shí)等等。

這一類的標(biāo)識(shí),在分布式系統(tǒng)下,在系統(tǒng)并發(fā)量大,應(yīng)當(dāng)采用基于服務(wù)的內(nèi)置生成方案。唯一依賴的是在實(shí)例部署時(shí)、啟動(dòng)前,為期分配唯一的Machine Identifier。這個(gè)Machine Identifier可以交由以強(qiáng)一致性保證的協(xié)調(diào)器完成。

當(dāng)然,在系統(tǒng)并發(fā)量小的情況下,任然可以采用基于數(shù)據(jù)庫的生成方案,因?yàn)闆]有協(xié)調(diào)器集群的參與,系統(tǒng)整體的復(fù)雜度更低,更利于維護(hù)。

2. 標(biāo)識(shí)的容量

任何采用文字所表達(dá)的標(biāo)識(shí),最終在計(jì)算機(jī)里,都會(huì)根據(jù)一定的格式,被轉(zhuǎn)換為字節(jié)byte進(jìn)行處理,這個(gè)過程稱之為「序列化」。 這種序列化方式,本質(zhì)上是一種編碼方式。

變長編碼

一般來說,采用變長的編碼方式,主要的目的是為了應(yīng)對不可預(yù)期大小的信息量。

常見的有 TLV(Type-Length-Value) 方式。 Google的 Protocol Buffers 非常有意思地采用了 Base 128 Varints 的編碼方式。

本質(zhì)上,一個(gè) URI 也是一個(gè)變長標(biāo)識(shí),它可以標(biāo)識(shí)一個(gè)功能,也可以標(biāo)識(shí)一個(gè)虛擬實(shí)體。

RESTful是對此類命名方式的一種實(shí)踐方式,也是對 URI和HTTP協(xié)議組合之后,「表征力」的一個(gè)深入挖掘。

定長編碼

在回顧一下前文所提到的IPv4地址,它似乎、可能、或許會(huì)在2019年 完全枯竭, 因?yàn)樗挥?2-bit。相比之下,MAC地址有48-bit,IPv6有128-bit。即便是它們都沒那么容易枯竭,但也不代表由于人為因素,導(dǎo)致無法有效使用。

再回想下,每個(gè)人的身份證、手機(jī)號(hào)碼,都是采用定長的形式進(jìn)行編碼。

選擇定長有利于預(yù)先分配計(jì)算機(jī)資源,不管是內(nèi)存、文件系統(tǒng),還是數(shù)據(jù)庫。同時(shí),對于人的心理來說,可預(yù)期性大大增強(qiáng)了。

標(biāo)識(shí)的命名空間

命名空間有三個(gè)層面:

  • 異構(gòu)切分:對于不同的場景和視角,以樹形進(jìn)行層次劃分。

  • 同構(gòu)切分:對于異構(gòu)切分的結(jié)果,切分出不同的分片。

  • 時(shí)間切分:對于同一個(gè)分片,在不同時(shí)間點(diǎn)上的狀態(tài)。

一般地:

  • 首先,采用并行無狀態(tài)的生成算法,一般都采用時(shí)間作為首要的命名空間,并且此命名空間的實(shí)效性小于生成者的重啟時(shí)間

  • 其次,采用生成器實(shí)例自身的標(biāo)識(shí)作為次要命名空間,以保證各個(gè)生成器的時(shí)間即便是不同步也不會(huì)產(chǎn)生重復(fù)標(biāo)識(shí)

同時(shí),需要注意的是,這可能導(dǎo)致唯一標(biāo)識(shí)產(chǎn)生,大段跳躍,原因有:

  • 單位時(shí)間的并發(fā)量遠(yuǎn)小于子命名空間的容量

  • 生成器重啟

  • 標(biāo)識(shí)的冗余

不管標(biāo)識(shí)是在運(yùn)行時(shí)的內(nèi)存出現(xiàn),還是記錄到數(shù)據(jù)庫中或者文件里,它都需要占用硬件資源。

還是拿身份證舉例,一方面,一個(gè)18個(gè)字符長度的身份證,那么需要18個(gè)字節(jié)進(jìn)行存儲(chǔ)。18個(gè)字節(jié)意味著144-bit,比IPv6的128bit還長。

如果簡單的標(biāo)識(shí)全世界每個(gè)人,以目前全地球超過70億人口的總量,那么33個(gè)bit就足夠了。

采用這種冗余設(shè)計(jì)的原因,一方面是「半集中,半自主」和現(xiàn)實(shí)的行政、地域結(jié)構(gòu)對齊,另一方面是實(shí)現(xiàn)關(guān)聯(lián)信息的集成。

小結(jié)

  • 標(biāo)識(shí)編碼后的長度,則決定了一個(gè)標(biāo)識(shí)方案的整體容量。

  • 在一個(gè)統(tǒng)一的命名空間內(nèi),有多個(gè)標(biāo)識(shí)生成者并行生成時(shí),需要?jiǎng)澐知?dú)立的子命名空間,以保證生成的標(biāo)識(shí)在整個(gè)命名空間內(nèi)唯一。

  • 單個(gè)命名空間的標(biāo)識(shí),承載的信息量有限,在標(biāo)識(shí)的使用過程中,需要擴(kuò)展與包含一些其他視角的信息以進(jìn)行冗余。

3. 標(biāo)識(shí)的文本兼容

和人工取名字不一樣,自動(dòng)生成ID的主體,是計(jì)算機(jī)本身,但使用這個(gè)ID的主體,有兩個(gè):人和計(jì)算機(jī)。

對于計(jì)算機(jī),最擅長處理的是結(jié)構(gòu)化數(shù)組、條形碼或者二維碼;而對人,最擅長使用的是文本、圖形或者視頻。

一般而言,在大量的RESTful設(shè)計(jì)的應(yīng)用,其URI中會(huì)包含大量的ID,用來標(biāo)識(shí)用戶、商品、訂單等等,它們經(jīng)常會(huì)出現(xiàn)在URI中。

以ASCII編碼為基礎(chǔ)的各種文本化編碼算法,從Base16開始,正常的有Base32,Base64,Base58,Base85等等。

其中,Base16是最為「字節(jié)友好」的,因?yàn)椴恍枰M(jìn)行任何Padding操作,就可以以把 4-bit/half-byte 轉(zhuǎn)換為 [0-9a-f] 這十六個(gè)字符,因此Base16還有別名:Hex。另外對于鍵盤輸入,這16個(gè)英文字母,又是相對純數(shù)字之外,最方便的。

而Base32, Base64等等,都需要Padding。因?yàn)锽ase32是每 5-bit 進(jìn)行分組編碼,Base64則是 6-bit ,都無法直接對齊一個(gè) byte(8-bit)。

另外,Base16還對 URI 友好,不需要進(jìn)行任何的 URLEncode/Decode操作。

以64-bit長的ID為例,它既可以轉(zhuǎn)化為 long,也可以Base16成為16個(gè)字符的``HexString``,同時(shí)它大小寫不敏感。

相比之下,如果采用Base64的文本化方案,其長度雖然少了5個(gè)字符,為11個(gè),但其大小寫敏感,不利于人機(jī)交互的輸入,還會(huì)包含URI不友好,還會(huì)被轉(zhuǎn)義為「 %3D」的符號(hào)「=」。

一個(gè)精巧的標(biāo)識(shí)文本化算法,并不應(yīng)該簡單的把一個(gè)二進(jìn)制值轉(zhuǎn)為HexString。在日志里,應(yīng)該有相應(yīng)的解碼算法,解析出符合人類閱讀的字符,比如:精確到秒、且?guī)Ц袷綍r(shí)間,生成改標(biāo)識(shí)的主體,等等。

4. 標(biāo)識(shí)的安全性

標(biāo)識(shí)的信息泄露

采用連續(xù),或者固定步長的標(biāo)識(shí),容易從一個(gè)標(biāo)識(shí)猜測其他標(biāo)識(shí)的存在性。

常見的例子有:

  • 通過局域網(wǎng)掃描工具,掃描某個(gè)子網(wǎng)的活動(dòng)的IP地址

  • 通過端口掃描工具,掃描一個(gè)目標(biāo)主機(jī)開放的端口,以初步確定主機(jī)操作系統(tǒng)類型

另外,在物聯(lián)網(wǎng)領(lǐng)域,如果采用的EPC編碼,那么很容易通過連續(xù)編碼,估計(jì)某個(gè)產(chǎn)品的具體產(chǎn)量。

標(biāo)識(shí)的自校驗(yàn)?zāi)芰?

還是使用身份證號(hào)這個(gè)例子,根據(jù)國家標(biāo)準(zhǔn)(GB11643-1999),身份證號(hào)的前17位為本體碼,最后1位為校驗(yàn)碼。也就是說,它是通過前17位進(jìn)行數(shù)學(xué)公式計(jì)算之后獲得,主要目的是用于檢驗(yàn)錄入過程是否產(chǎn)生差錯(cuò)。

這樣設(shè)計(jì)的好處是,每當(dāng)輸入完18位身份證號(hào)后,可以直接判斷一個(gè)身份證號(hào),是否在邏輯上是「合規(guī)的」,對于系統(tǒng)而言不用查詢數(shù)據(jù)庫,可以減少IO操作。不過,這不代表這個(gè)身份證號(hào)是有效的,也有可能是一個(gè)無效,但符合校驗(yàn)規(guī)則的身份證號(hào)。

由于標(biāo)識(shí)的長度有限,能夠加入的冗余信息較少,一般的基于公鑰密碼體制的簽名機(jī)制,都難以在一個(gè)短標(biāo)識(shí)中嵌入。

 

來自:http://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=2659598286&idx=1&sn=3172172ccea316b0ed83429ae718b54d&

標(biāo)簽: dns Google Mysql 安全 代碼 電商 數(shù)據(jù)庫 搜索 搜索引擎 網(wǎng)絡(luò) 虛擬主機(jī) 域名

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:App啟動(dòng)優(yōu)化-Android性能優(yōu)化

下一篇:加速iOS開發(fā)的28個(gè)第三方庫