溫馨提示×

溫馨提示×

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

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

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

發(fā)布時間:2020-12-25 10:25:09 來源:億速云 閱讀:334 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細講解有關Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Pinteres 是你感興趣的所有東西的發(fā)現(xiàn)引擎。從數(shù)據(jù)的角度來說,Pinterest 是世界上最大的人類興趣圖集。有超過500億的 Pin 被 Pin 友們保存在10億塊圖板上。 用戶再次 Pin,喜歡其他人的 Pin(粗略地說是一個淺顯的復制品),關注其他 Pin 友,畫板和興趣,然后查看主頁上所訂閱Pin友的所有資訊。 太好了! 現(xiàn)在讓它擴大規(guī)模!

成長的痛

在2011年我們?nèi)〉昧顺晒Α?在 一些 評估報告里,我們的發(fā)展比其他的初創(chuàng)公司要快得多。在2011年9月,我們每一項基礎設備都超出了負載。我們應用了一些 NoSQL 技術,所有這些技術都導致了災難性的后果。 同時,大量用于讀的 MySQL 從服務器產(chǎn)生了大量令人惱火的 bugs,特別是緩存。我們重構(gòu)了整個數(shù)據(jù)存儲模式。為了使之有效,我們仔細制定了我們的要求。

業(yè)務要求

  • 我們的全部系統(tǒng)需要非常穩(wěn)定,易于操作和易于擴展。 我們希望支持數(shù)據(jù)庫能從開始的小存儲量,能隨著業(yè)務發(fā)展而擴展。

  • 所有 Pin友 生成的內(nèi)容在網(wǎng)站上必須隨時可以訪問。

  • 支持以確定的順序請求訪問 N 個 Pin在畫板中展示(像按照創(chuàng)建的時間,或者按照用戶特定的順序)。對于喜歡的 Pin 友和 Pin友的 Pin 列表等也能按照特定的順序展示。

  • 為了簡單起見,更新一般要保證最好的效果。為了獲取最終一致性,你需要一些額外的東西,如分布式 事務日志。這是一件有趣并(不)簡單的事情。

解決思路及要點備注

解決方案由于需要將海量的數(shù)據(jù)切片分布到多個數(shù)據(jù)庫實例上,不能使用關系數(shù)據(jù)庫的連接、外鍵或索引等方法整合整個數(shù)據(jù)。想想就知道,關聯(lián)的子查詢不能跨越不同的數(shù)據(jù)庫實例。

我們的方案需要負載平衡數(shù)據(jù)訪問。我們憎恨數(shù)據(jù)遷移,尤其是逐個記錄進行遷移,因關系的復雜性,這樣非常容易發(fā)生錯誤且加重系統(tǒng)不必要的復雜性。如果必須要遷移數(shù)據(jù),最好是邏輯節(jié)點集的整體遷移。

為了達到方案實施的可靠迅速,我們需要在我們的分布式數(shù)據(jù)平臺上使用最易于實現(xiàn)、最健壯的技術方案。

每個實例上的所有的數(shù)據(jù)將被完全復制到一個從實例上,作為數(shù)據(jù)備份。我們使用的是高可用性的 MapReduce (分布式計算環(huán)境) 的 S3 。我們前端的業(yè)務邏輯訪問后臺數(shù)據(jù),只訪問數(shù)據(jù)庫的 主實例永遠不要讓您的前端業(yè)務去讀寫訪問從實例 。因為它與 主實例 數(shù)據(jù)同步存在延遲,會造成莫名其妙的錯誤,一旦將數(shù)據(jù)切片并分布,沒有一絲理由讓你前端業(yè)務從 從實例 上讀寫數(shù)據(jù)。

最后,我們需要精心設計一個優(yōu)秀的方案生成和解析我們所有數(shù)據(jù)對象的 全局唯一標識( UUID ) 。

我們的切片方案

不管怎樣,我們需要設計符合我們需求的,健壯的,性能優(yōu)良和可維護的數(shù)據(jù)分布解決方案。換句話說,它不能稚嫩(未經(jīng)廣泛驗證)。因此,我們的基礎設計建立在 MySQL 之上,參見  we chose a mature technology(選擇成熟技術) 。設計之初,我們自然會跳開不用那些號稱具有自動分布(auto-scaling)新技術能力的數(shù)據(jù)庫產(chǎn)品,諸如 MongoDB,Cassandra 和 Membase 之類的產(chǎn)品,因為它們似乎實施簡單卻適用性太差(常常發(fā)生莫名其妙的錯誤導致崩潰)。

旁白:強烈建議從底層基礎入手,避免時髦新鮮的東東 — 扎扎實實把  MySQL 學好用好。相信我,字字都是淚。

MySQL 是成熟、穩(wěn)定并且就是好使的關系型數(shù)據(jù)庫產(chǎn)品。不僅我們用它,包括許多知名大公司也使用它作為后臺數(shù)據(jù)支撐,存儲著海量的數(shù)據(jù)。(譯注:大概幾年前,由于MySQL隨著 SUN 被 Oracle 的收購,歸到 Oracle 名下。許多公司,如 google,facebook 等由于擔心 MySQL 的開源問題,紛紛轉(zhuǎn)到由 MySQL 原作者開發(fā)的另一個開源數(shù)據(jù)庫 MariaDB 下)MySQL 支持我們對數(shù)據(jù)庫要求按序數(shù)據(jù)請求,查詢指定范圍數(shù)據(jù)及行(記錄)級上的事務處理的技術要求。MySQL有一堆功能特性,但我們不需要那些。由于 MySQL 本身是個單體解決方案,可我們卻要把我們的數(shù)據(jù)切片。(譯注:此處的意思是,一個單實例管理海量的數(shù)據(jù),勢必造成性能問題?,F(xiàn)在把一個海量整體數(shù)據(jù)切片成一個個單體數(shù)據(jù)集,需要一個強有力的技術解決方案,把一個個的單體整合成一個整體,提高性能還不出錯)下面是我們的設計方案:

我們起始使用8臺 EC2 服務器,每臺服務器都運行一個 MySQL 實例:

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

每個 MySQL 服務器各自以 主-主備份( master-master replicated )到1臺冗余主機作為災難恢復。我們前臺業(yè)務只從主服務實例讀/寫數(shù)據(jù) 。我建議你也這么做,它簡化許多事情,避免延遲故障。(譯注:主-主備份( master-master replicated ) 是MySQL數(shù)據(jù)庫本身提供的功能,指兩臺機器互做備份的一種模式,相對其它模式,如 主-從備份,兩臺機器數(shù)據(jù)完全一致,后臺同步,每臺機器有自己單獨 IP 都可訪問,可并發(fā)讀/寫訪問。但原文作者一再強調(diào)的是雖然這兩臺互為冗余使用 主-主備份,都可訪問。但你邏輯上區(qū)分 主-從,永遠只從其中一個進行讀/寫。例如,圖中所示, MySQL001A 和 MySQL001B 間 主-主備份,但你只從 MySQL001A 進行讀/寫訪問。另:他們使用了16臺機器,另8臺做從機的可能不是 EC2 也未必)

每個 MySQL 實例可以有多個數(shù)據(jù)庫:

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

注意每個數(shù)據(jù)庫是如何唯一地命名為 db00000,db00001,直到 dbNNNN。每個數(shù)據(jù)庫都是我們數(shù)據(jù)庫的分片。我們做了一個設計,一旦一塊數(shù)據(jù)被分配到一個分片中,它就不會移出那個分片。但是,你可以通過將分片移動到其他機器來獲得更大的容量(我們將在后面討論這一點)。

我們維護著一個配置數(shù)據(jù)庫表,此表中記錄這切片數(shù)據(jù)庫在哪臺機器上:

[
{“range”: (0,511), “master”: “MySQL001A”, “slave”: “MySQL001B”},
{“range”: (512, 1023), “master”: “MySQL002A”, “slave”: “MySQL002B”},
 ...
{“range”: (3584, 4095), “master”: “MySQL008A”, “slave”: “MySQL008B”}
]

這個配置表僅當遷移切片數(shù)據(jù)庫或替換主機時修改。例如,一個主實例主機宕掉了,我們會提升它的從實例主機為主實例,然后盡快頂替一個新機器當從實例主機。配置腳本保留在 ZooKeeper  上,當出現(xiàn)上述修改時,通過腳本發(fā)送到維護切片服務的機器上進行配置改變。(譯注:可發(fā)現(xiàn)原作者一直強調(diào)的,前端業(yè)務僅從邏輯主實例讀寫數(shù)據(jù)的好處)。

每個切片數(shù)據(jù)庫保持相同的數(shù)據(jù)庫表及表結(jié)構(gòu),諸如,有 pins ,boards ,users_has_pins ,users_likes_pins ,pin_liked_by_user 等數(shù)據(jù)庫表。 在布署時同步構(gòu)建。

分布數(shù)據(jù)到切片服務器設計方案

我們組合 切片 ID(shard ID) 、數(shù)據(jù)類型標識和 局部 ID(local ID) 形成64位的 全局唯一標識(ID) 。切片 ID(shard ID) 占16個位(bit), 數(shù)據(jù)類型標識占10個位(bit), 局部 ID(local ID) 占36個位(bit)。 明眼人馬上會發(fā)現(xiàn),這才62位。我過去的分布及整合數(shù)據(jù)經(jīng)驗告訴我,保留幾位留做擴展是無價寶。因此,我保留了2位(設為0)。(譯注:這里解釋一下,根據(jù)后面的運算和說明,任何對象的唯一標識 ID 是64位,最高2位始終為0,之后是36位的局部標識,之后是10位類型標識,最后是16位的切片標識。局部標識可表示 2^36達600多億個 ID 。數(shù)據(jù)類型可表示2^10達1024個對象類型,切片標識可細分成2^16達65536個切片數(shù)據(jù)庫。前面說的方案切了4096個切片數(shù)據(jù)庫)

ID = (shard ID << 46) | (type ID << 36) | (local ID<<0)

以 Pin: https://www.pinterest.com/pin/241294492511... 為例,讓我們解構(gòu)這個 Pin 對象的 全局 ID 標識  241294492511762325 :

Shard ID = (241294492511762325 >> 46) & 0xFFFF = 3429
Type ID  = (241294492511762325 >> 36) & 0x3FF = 1
Local ID = (241294492511762325 >>  0) & 0xFFFFFFFFF = 7075733

可知這個 Pin 對象在3429切片數(shù)據(jù)庫里。 假設 Pin 對象 數(shù)據(jù)類型標識為 1,它的記錄在3429切片數(shù)據(jù)庫里的 pin 數(shù)據(jù)表中的 7075733 記錄行中。舉例,假設切片3429數(shù)據(jù)庫在 MySQL012A中,我們可利用下面語句得到其數(shù)據(jù)記錄:(譯注:這里原作者泛泛舉例,若按其前面方案例子來說,3429應在MySQL007A 上)

conn = MySQLdb.connect(host=”MySQL012A”)
conn.execute(“SELECT data FROM db03429.pins where local_id=7075733”)

有兩種類型的數(shù)據(jù):對象或關系。對象包含對象本身細節(jié)。 如 Pin 。

存儲對象的數(shù)據(jù)庫表

對象庫表中的每個記錄,表示我們前端業(yè)務中的一個對象,諸如:Pins(釘便簽), users(用戶),boards(白板)和  comments(注釋),每個這樣的記錄在數(shù)據(jù)庫表中設計一個標識 ID 字段(這個字段在表中作為記錄的 自增主鍵「auto-incrementing primary key」  ,也就是我們前面提到的 局部 ID「 local ID」 ),和一個 blob 數(shù)據(jù)字段 -- 使用 JSON 保存對象的具體數(shù)據(jù) --。

CREATE TABLE pins (
  local_id INT PRIMARY KEY AUTO_INCREMENT,
  data TEXT,
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

舉例,一個 Pin 對象形狀如下:

{“details”: “New Star Wars character”, “l(fā)ink”: “http://webpage.com/asdf”, “user_id”: 241294629943640797, “board_id”: 241294561224164665, …}

創(chuàng)建一個 Pin 對象,收集所有的數(shù)據(jù)構(gòu)成 JSON blob 數(shù)據(jù)。然后,確定它的 切片 ID「 shard ID」 (我們更樂意把 Pin 對象的切片數(shù)據(jù)放到跟其所在 白板「  board」 對象相同的切片數(shù)據(jù)庫里,這不是強制設計規(guī)則)。Pin 對象的數(shù)據(jù)類型標識為 1。連接到 切片 ID 指示的切片數(shù)據(jù)庫,插入(insert)Pin 對象的 JOSON 數(shù)據(jù)到 Pin 對象數(shù)據(jù)庫表中,MySQL 操作成功后將會返回 自增主鍵「auto-incrementing primary key」 給你,這個作為此 Pin 對象的 局部 ID「 local ID」?,F(xiàn)在,我們有了 shard 、類型值、local ID 這些必要信息,就可以構(gòu)建出此 Pin 對象的64位 ID 。(譯注:原作者提到的,他們的前端業(yè)務所用到的每種對象都保存在一個對象數(shù)據(jù)庫表里,每個對象記錄都通過一個全局唯一 ID去找到它,但這個全局唯一 ID并不是數(shù)據(jù)庫表中的 局部ID,由于切片的緣故。原作者一直在講這個設計及其原理。這樣設計的目的為了海量數(shù)據(jù)切片提高性能,還要易用,可維護,可擴展。后面,作者會依次講解到)

編輯一個 Pin 對象,使用 MySQL 事務「transaction」 在 Pin 對象的數(shù)據(jù)記錄上 讀出--修改--寫回「read-modify-write」 Pin 對象的 JOSON 數(shù)據(jù)字段:

> BEGIN
> SELECT blob FROM db03429.pins WHERE local_id=7075733 FOR UPDATE
[修改 json blob]
> UPDATE db03429.pins SET blob=’<修改后的 blob>’ WHERE local_id=7075733
> COMMIT

編輯一個 Pin 對象,您當然可以直接刪除這個對象在 MySQL 數(shù)據(jù)庫表中的數(shù)據(jù)記錄。但是,請仔細想一下,是否在對象的 JSON 數(shù)據(jù)上加個叫做「 active」的域,把剔除工作交由前端中間業(yè)務邏輯去處理或許會更好呢。

(譯注:學過關系數(shù)據(jù)庫的應知道,自增主鍵在記錄表中是固實,在里面刪除記錄,會造成孔洞。當多了,勢必造成數(shù)據(jù)庫性能下降。數(shù)據(jù)庫只負責保存數(shù)據(jù)和高性能地查詢、讀寫數(shù)據(jù),其數(shù)據(jù)間的關系完全靠設計精良的對象全局ID通過中間件邏輯去維護 這樣的設計理念一直貫穿在作者的行文中。只有理解了這點您才能抓住這篇文章的核心)

關系映射數(shù)據(jù)庫表

關系映射表表示的是前端業(yè)務對象間的關系。諸如:一個白板(board)上有哪些釘便簽(Pin), 一個釘便簽(Pin)在哪些白板(board)上等等。表示這種關系的 MySQL 數(shù)據(jù)庫表包括3個字段:一個64位的「from」ID, 一個64位的「to」ID和一個順序號。每個字段上都做索引方便快速查詢。其記錄保存在根據(jù)「from」字段 ID 解構(gòu)出來的切片 ID 指示出的切片數(shù)據(jù)庫上。

CREATE TABLE board_has_pins (
  board_id INT,
  pin_id INT,
  sequence INT,
  INDEX(board_id, pin_id, sequence)
) ENGINE=InnoDB;

(譯注:這里的關系映射指前端業(yè)務對象間的關系用數(shù)據(jù)庫表來運維,并不指我上節(jié)注釋中說到的關系數(shù)據(jù)庫的關系映射。作者開篇就講到,由于切片,不能做關系數(shù)據(jù)庫表間的關系映射的,如一對一,一對多,多對多等關系關聯(lián))

關系映射表是單向的,如 board_has_pins(板含便簽)表方便根據(jù) board (白板)ID查詢其上有多少 Pin(釘便簽)。若您需要根據(jù) Pin(釘便簽)ID查詢其都在哪些 board(白板)上,您可另建個表 pin_owned_by_board(便簽屬于哪些白板)表,其中 sequence 字段表示 Pin 在 board 上的順序號。(由于數(shù)據(jù)分布在切片數(shù)據(jù)庫上,我們的 ID 本身無法表示其順序)我們通常將一個新的 Pin 對象加到 board 上時,將其 sequence 設為當時的系統(tǒng)時間。sequence 可被設為任意整數(shù),設為當時的系統(tǒng)時間,保證新建的對象的 sequence 總是大于舊對象的。這是個方便易行的方法。您可通過下面的語句從關系映射表中查詢對象數(shù)據(jù)集:

SELECT pin_id FROM board_has_pins 
WHERE board_id=241294561224164665 ORDER BY sequence 
LIMIT 50 OFFSET 150

語句會查出50個 pin_ids(便簽 ID ),隨后可用這些對象 ID 查詢其具體信息。

我們只在業(yè)務應用層進行這些關系的映射,如 board_id -> pin_ids -> pin objects (從 白板 ID -> 便簽 IDs -> 便簽對象)。 這種設計一個非常棒的特性是,您可以分開緩存這些關系映射對。例如,我們緩存 pin_id -> pin object (便簽 ID -> 便簽對象)關系映射在 memcache(內(nèi)存緩存)集群服務器上,board_id -> pin_ids (白板 ID -> 便簽 IDs)關系映射緩存在 redis 集群服務器上。這樣,可以非常適合我們優(yōu)化緩存技術策略。

增大服務能力

在我們的系統(tǒng)中,提升服務處理能力主要三個途徑。最容易的是升級機器(更大的空間,更快的硬盤速度,更多的內(nèi)存,無論什么解決系統(tǒng)瓶頸的升級都算)

另一個途徑,擴大切片范圍。最初,我們設計只切片了4096個數(shù)據(jù)庫,相比我們設計的16位的切片 ID,還有許多空間,因為16位可表示65536個數(shù)。某些時間節(jié)點,若我們再提供8臺機器運行8個 MySQL 數(shù)據(jù)庫實例,提供從 4096 到 8192 的切片數(shù)據(jù)庫,之后,新的數(shù)據(jù)將只往這個區(qū)間的切片數(shù)據(jù)庫上存放。并行計算的數(shù)據(jù)庫有16臺,服務能力必然提升。

最后的途徑,遷移切片數(shù)據(jù)庫主機到新切片主機(局部切片擴容)以提升能力。例如,我們想將前例中的 MySQL001A 切片主機(其上是 0 到 511 編號的切片數(shù)據(jù)庫)擴展分布到2臺切片主機上。同我們設計地,我們創(chuàng)建一個新的 master-master 互備份主機對作為新切片主機(命名為 MySQL009A 和 B)并從 MySQL001A 上整體復制數(shù)據(jù)。

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

當數(shù)據(jù)復制完成后,我們修改切片配置,MySQL001A 只負責 0 到 255 的切片數(shù)據(jù)庫,MySQL009A 只負責 256 到 511 的切片數(shù)據(jù)庫?,F(xiàn)在2臺中每臺主機只負責過去主機負責的一半的任務,服務能力提升。

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析

一些特性說明

對于舊系統(tǒng)已產(chǎn)生的業(yè)務對象數(shù)據(jù),要根據(jù)設計,對業(yè)務對象要生成它們在新系統(tǒng)中的 UUIDs,你應意識到它們放到哪兒(哪個切片數(shù)據(jù)庫)由你決定。(譯注:你可以規(guī)劃舊數(shù)據(jù)在切片數(shù)據(jù)庫上的分布)但是,在放入到切片數(shù)據(jù)庫時,只有在插入記錄時,數(shù)據(jù)庫才會返回插入對象的 local ID,有了這個,才能構(gòu)建對象的 UUID。
(譯注:在遷移時要考慮好業(yè)務對象間關系的建立,通過UUID)

對于那些在已有大量數(shù)據(jù)的數(shù)據(jù)庫表,曾使用過修改表結(jié)構(gòu)類命令 (ALTERs)--諸如添加個字段之類的 -- 的人來說,您知道那是一個 非常 漫長和痛苦的過程。我們的設計是絕不使用 MySQL 上 ALTERs 級別的命令(當已有數(shù)據(jù)時)。在我們的業(yè)務系統(tǒng) Pinterest 上,我們使用最后一個 ALTER 語句大概是在3年前了。 對于對象表中對象,如果您需要添加個對象屬性字段,您添加到對象數(shù)據(jù)的 JOSON blob 字段里。您可以給新對象屬性設定個默認值,當訪問到舊對象的數(shù)據(jù)時,若舊對象沒有新屬性,您可以給其添加上新屬性默認值。對于關系映射表來說,干脆,直接建立新的關系映射表以符合您的需要。這些您都清楚了!讓您的系統(tǒng)揚帆起行吧!

模轉(zhuǎn)(mod)數(shù)據(jù)庫的切片

模轉(zhuǎn)數(shù)據(jù)切片(mod shard)名稱僅僅是像 Mod Squad,實則完全不同。

一些業(yè)務對象需要通過非 ID (non-ID)的方式查詢訪問。(譯注: 此 ID 指之前設計說明中的64位 UUID)舉例來說,如果一名 Pin友(Pinner)是以他(她)的 facebook 注冊帳號注冊登錄我們的業(yè)務平臺上的。我們需將其 facebook ID 與我們的 Pin友(Pinner)的 ID 映射。 facebook ID 對于我們系統(tǒng)只是一串二進制位的數(shù)。(譯注:暗示我們不能像我們系統(tǒng)平臺的設計那樣解構(gòu)別的平臺的 ID,也談不上如何設計切片,只是把它們保存起來,并設計使之與我們的 ID 映射)因此,我們需要保存它們,也需要把它們分別保存在切片數(shù)據(jù)庫上。我們稱之為模轉(zhuǎn)數(shù)據(jù)切片(mod shard)其它的例子還包括 IP 地址、用戶名和用戶電子郵件等。

模轉(zhuǎn)數(shù)據(jù)切片(mod shard)類似前述我們業(yè)務系統(tǒng)的數(shù)據(jù)切片設計。但是,你需要按照其輸入的原樣進行查詢。如何確定其切片位置,需要用到哈希和模數(shù)運算。哈希函數(shù)將任意字串轉(zhuǎn)換成定長數(shù)值,而模數(shù)設為系統(tǒng)已有切片數(shù)據(jù)庫的切片數(shù)量,取模后,其必然落在某個切片數(shù)據(jù)庫上。結(jié)果是其數(shù)據(jù)將保存在已有切片數(shù)據(jù)庫上。舉例:

shard = md5(“1.2.3.4") % 4096

(譯注:mod shard 這個詞,我網(wǎng)上找遍了,試圖找到一個較準確權威的中文翻譯!無果,因為 mod 這個詞有幾種意思,最近的是module 模塊、模組,同時它也是模運算符(%)。我根據(jù)原文意思,翻譯為 模轉(zhuǎn) ?;蚩煞g為 模式,但個人感覺意思模糊。不當之處,請指正。另,原作者舉的例子是以 IP 地址舉例的,哈希使用的是 md5,相比其它,雖老但性能最好)

在這個例子中分片是1524。 我們維護一個類似于ID分片的配置文件:

[{“range”:    (0,  511), “master”: “msdb001a”, “slave”: “msdb001b”},
  {“range”:  (512, 1023), “master”: “msdb002a”, “slave”: “msdb002b”},
  {“range”: (1024, 1535), “master”: “msdb003a”, “slave”: “msdb003b”},
…]

因此,為了找到 IP 為1.2.3.4的數(shù)據(jù),我們將這樣做:

conn = MySQLdb.connect(host=”msdb003a”)
conn.execute(“SELECT data FROM msdb001a.ip_data WHERE ip='1.2.3.4'”)

你失去了一些分片好的屬性,例如空間位置。你必須從一開始就設置分片的密鑰(它不會為你制作密鑰)。最好使用不變的id來表示系統(tǒng)中的對象。這樣,當用戶更改其用戶名時,您就不必更新許多引用。

最后的提醒

這個系統(tǒng)作為  Pinterest 的數(shù)據(jù)支撐已良好運行了3.5年,現(xiàn)在看來還會繼續(xù)運行下去。設計實現(xiàn)這樣的系統(tǒng)是直觀、容易的。但是讓它運行起來,尤其遷移舊數(shù)據(jù)卻太不易了。若您的業(yè)務平臺面臨著急速增長的痛苦且您想切片自己的數(shù)據(jù)庫。建議您考慮建立一個后端集群服務器(優(yōu)先建議 pyres)腳本化您遷移舊數(shù)據(jù)到切片數(shù)據(jù)庫的邏輯,自動化處理。我保證無論您想得多周到,多努力,您一定會丟數(shù)據(jù)或丟失數(shù)據(jù)之間的關聯(lián)。我真的恨死隱藏在復雜數(shù)據(jù)關系中的那些搗蛋鬼。因此,您需要不斷地遷移,修正,再遷移... 你需要極大的耐心和努力。直到您確定您不再需要為了舊數(shù)據(jù)遷移而往您的切片數(shù)據(jù)庫中再操作數(shù)據(jù)為止。

這個系統(tǒng)的設計為了數(shù)據(jù)的分布切片,已盡最大的努力做到最好。它本身不能提供給你數(shù)據(jù)庫事務 ACID 四要素中的 Atomicity(原子性)、Consistency(一致性)、Isolation(隔離性)哇嘔!聽起來很壞呀,不用擔心。您可能不能利用數(shù)據(jù)庫本身提供的功能很好地保證這些。但是,我提醒您,一切盡在您的掌握中,您只是讓它運行起來,滿足您的需要就好。設計簡單直接就是王道,(譯注:也許需要您做許多底層工作,但一切都在您的控制之中)主要是它運行起來超快! 如果您擔心 A(原子性)、I(隔離性)和 C(一致性),寫信給我,我有成堆的經(jīng)驗讓您克服這些問題。

還有最后的問題,如何災難恢復,啊哈? 我們創(chuàng)建另外的服務去維護著切片數(shù)據(jù)庫,我們保存切片配置在 ZooKeeper 上。當單點主服務器宕掉時,我們有腳本自動地提升主服務器對應的從服務器立即頂上。之后,以最快的速度運行新機器頂上從服務器的缺。直至今日,我們從未使用過類似自動災難恢復的服務。

關于“Pinterest MySQL利用分片來解決百億數(shù)據(jù)存儲問題的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

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

AI