Ticket 服务: 一种经济的分布式唯一主键生成方案
生活随笔
收集整理的這篇文章主要介紹了
Ticket 服务: 一种经济的分布式唯一主键生成方案
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
MySQL分庫分表早已經(jīng)不是什么新鮮話題了。甚至已經(jīng)成了說到MySQL就會說到的話題。在一張表中,MySQL提供了原生的自增主鍵實(shí)現(xiàn)。但是在這樣的分布式系統(tǒng)中,怎么保證數(shù)據(jù)在多張表上的ID是唯一的呢? Flickr提出了一個方案,將文章簡單翻譯一下給大家,方便大家閱讀。嫌棄我翻譯水平太爛的,請移步原文: http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/ --------------------------------------------- 我就是分割線?分割線就是我 ?----------------------------------------- 這篇文章是“ 在Flickr里使用,廣泛使用,擴(kuò)展MySQL”系列文章的第一彈。 Ticket服務(wù)本身其實(shí)沒什么好說的,但他是Flickr系統(tǒng)里一個重要的組成部分。是我們接下來要談到的話題的核心,就像sharding和主主復(fù)制一樣。Ticket服務(wù)器給我們提供了一個生成全局(Flickr范圍內(nèi))唯一的整數(shù)的服務(wù),這個整數(shù)用來作為我們分布式系統(tǒng)中的主鍵使用。為什么(需要這樣一種機(jī)制)?
Sharding(或者叫 data partition)(譯者注:數(shù)據(jù)分片)是使我們的數(shù)據(jù)存儲能力能夠水平擴(kuò)展的方案。我們不是將我們所有的數(shù)據(jù)都存在一個物理的數(shù)據(jù)庫上,相反,我們有很多數(shù)據(jù)庫,每個數(shù)據(jù)庫存儲一部分?jǐn)?shù)據(jù),然后我們將壓力負(fù)載均衡到這些數(shù)據(jù)庫上去。但在某些情況下,我們需要在不同的數(shù)據(jù)庫之間進(jìn)行數(shù)據(jù)合并,所以我們需要主鍵是全局唯一的。另外,我們的數(shù)據(jù)庫sharding是基于主主復(fù)制的。這意味著我們需要保證,在一個分片內(nèi),主鍵也是唯一的,這樣才能避免主鍵沖突(重復(fù))。我們當(dāng)然希望能夠和其他人一樣,使用MySQL的自增字段來生成主鍵。但是,這種方案在跨多個物理或邏輯數(shù)據(jù)庫時,沒有辦法保證唯一性。(使用)GUIDs(行不行)?
看來,我們就是需要一個全局唯一的id,那為什么不用GUID(譯者注: GUID=Globally Unique Identifier 全局唯一標(biāo)示)呢?最大的原因就是GUID太大了,而且他在MySQL中索引效果太差了。為了保證我們的MySQL足夠快,我們將所有要查詢的條件都索引起來,然后只在索引鍵上做查詢。所以,索引的大小就成了一個關(guān)鍵性的指標(biāo)。如果你不能將你的索引全部都放到內(nèi)存里,那你的數(shù)據(jù)庫就不可能足夠快。而且,Ticket服務(wù)給我們的ID是有序的。這個特點(diǎn)給我們做業(yè)務(wù)報表和做調(diào)試的時候帶來了很大的方便性,而且我們還可以再上面做一些緩存的優(yōu)化方案。(使用)一致性哈希(行不行)?
像? Amazon’s Dynamo和其他一些系統(tǒng),在數(shù)據(jù)存儲上面提供了一致性哈希環(huán)來解決GUID和分片的問題。這種方案更適合于寫廉價的應(yīng)用場景(比如:? LSMTs),而MySQL是一種針對隨機(jī)讀取專門做過優(yōu)化的系統(tǒng)。集中式自增
我們不能讓MySQL的自增跨數(shù)據(jù)庫工作,那如果我們只用一個數(shù)據(jù)庫呢?假設(shè)在有人上傳圖片的時候,我們都往這個數(shù)據(jù)庫庫中插入一條數(shù)據(jù),然后用這個表的自增主鍵值作為我們所有數(shù)據(jù)庫的唯一主鍵。 在目前每秒60+張圖片上傳的情況下,這張表很快就會變得奇大無比。就算在中央數(shù)據(jù)庫中我們只存儲圖片的id,而不存儲其他任何信息,這張表也很快就會大到無法管理的地步。更何況圖片的評論,收藏,分組,標(biāo)簽等等等等也都需要唯一ID。REPLACE INTO
大約小十年前,MySQL在ANSI SQL標(biāo)準(zhǔn)上做了一個非標(biāo)準(zhǔn)的 “REPLACE INTO”擴(kuò)展。雖然后來有 “INSERT ON DUPLICATE KEY UPDATE”更好的解決了這類問題,但REPLACE INTO現(xiàn)在仍然能用。 REPLACE和INSERT很像。除了在新插入的行中主鍵或唯一所以中的值在表中已經(jīng)存在的情況下,會先刪除老的那行數(shù)據(jù),再插入新的這行數(shù)據(jù)。 這樣的話,我們就可以通過更新(replace)數(shù)據(jù)庫中的某一行來獲取一個新的自增主鍵ID了。來個總結(jié)
一個Flickr Ticket服務(wù)器是一個只包含一個數(shù)據(jù)庫獨(dú)立的數(shù)據(jù)庫服務(wù)器。然后這個數(shù)據(jù)庫里包含了一些類似Ticket32和Ticket64的表(分別用于提供32位整型主鍵和64位長整型主鍵)。 Tickets64 的Sckeme大概像這樣: CREATE TABLE `Tickets64` (`id` bigint(20) unsigned NOT NULL auto_increment,`stub` char(1) NOT NULL default '',PRIMARY KEY (`id`),UNIQUE KEY `stub` (`stub`) ) ENGINE=MyISAM SELECT * from Tickets64 返回的一行數(shù)據(jù)大概像這樣: +-------------------+------+ | id | stub | +-------------------+------+ | 72157623227190423 | a | +-------------------+------+ 當(dāng)我們需要一個新的64位的主鍵的時候,我們可以通過執(zhí)行下面的SQL得到: REPLACE INTO Tickets64 (stub) VALUES ('a'); SELECT LAST_INSERT_ID();單點(diǎn)問題
你絕對不愿意看到你的ID服務(wù)器因?yàn)閱吸c(diǎn)問題掛掉。我們實(shí)現(xiàn)“高可用”的方法是跑兩個Ticket服務(wù)。但在兩個機(jī)器之間進(jìn)行寫入/更新的復(fù)制是會有問題的,由于必要的鎖的存在,會嚴(yán)重降低整個網(wǎng)站的性能。我們的做法是將ID生成的職責(zé)均分到兩個服務(wù)上,一個生成奇數(shù),一個生成偶數(shù)。設(shè)置如下: TicketServer1: auto-increment-increment = 2 auto-increment-offset = 1TicketServer2: auto-increment-increment = 2 auto-increment-offset = 2 然后我們使用輪詢的方式去輪流訪問這兩個服務(wù)器,來達(dá)到負(fù)載均衡的目的和應(yīng)對停機(jī)的情況。如果有一邊不能保持同步了(停機(jī)了),那最多就是可能會有連續(xù)的幾十萬個奇數(shù)(或者偶數(shù))的ID。但這不會有任何副作用。更多的隊(duì)列
在Ticket服務(wù)器中,除了Ticket32和Ticket64這樣的兩張表,我們其實(shí)還有其他更多的表。我們的圖片,賬號, 離線任務(wù),組等等都有自己獨(dú)立的ID隊(duì)列。離線任務(wù)有它自己獨(dú)立的ID隊(duì)列是因?yàn)樗嗔?#xff0c;然后我們又不希望有不必要的因素導(dǎo)致隊(duì)列增長(譯者注:前面提到,ID的大小一定程度上反應(yīng)了業(yè)務(wù)的數(shù)據(jù)量)。分組和賬號有他們自己的ID隊(duì)列是因?yàn)槲覀兒苌倌盟麄儊碜霰容^。圖片有自己的ID隊(duì)列是因?yàn)槲覀円WC切換之后要和之前單表的自增ID保持同步,因?yàn)橹暗淖栽鰅d我們可以很方便的知道我們總共上傳了多少張圖片。就是這樣
雖然,這個方案看起來不是特別優(yōu)雅。但令人震驚的是從2006年1月13號我們上線到現(xiàn)在,在生產(chǎn)環(huán)境跑的都非常好。這個設(shè)計已經(jīng)成為我們Flickr工程師的一個設(shè)計理念——“ 在最壞的情況下也能工作”的一個典型代表了。轉(zhuǎn)載于:https://my.oschina.net/laichendong/blog/283796
總結(jié)
以上是生活随笔為你收集整理的Ticket 服务: 一种经济的分布式唯一主键生成方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员,请不要抢系统管理员的饭碗
- 下一篇: [c#基础]堆和栈