gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

MySQL 如何利用分片來解決 500 億數據的存儲問題

MySQL  如何利用分片來解決 500 億數據的存儲問題

這是一個關于我們在多個 MySQL 服務器上分割數據的技術研究。我們在 2012 年年初完成了這個分片方法,它仍是我們今天用來存儲核心數據的系統。

在我們討論如何分割數據之前,讓我們先了解一下我們的數據。心情照明,巧克力草莓,星際迷航語錄……

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

成長的痛

在 2011 年我們取得了成功。 在 一些 評估報告里,我們的發展比其他的初創公司要快得多。在 2011 年 9 月,我們每一項基礎設備都超出了負載。我們應用了一些 NoSQL 技術,所有這些技術都導致了災難性的后果。 同時,大量用于讀的 MySQL 從服務器產生了大量令人惱火的 bugs,特別是緩存。我們重構了整個數據存儲模式。為了使之有效,我們仔細制定了我們的要求。

業務要求

我們的全部系統需要非常穩定,易于操作和易于擴展。 我們希望支持數據庫能從開始的小存儲量,能隨著業務發展而擴展。

所有 Pin 友 生成的內容在網站上必須隨時可以訪問。

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

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

解決思路及要點備注

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

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

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

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

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

我們的切片方案

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

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

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

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

MySQL  如何利用分片來解決 500 億數據的存儲問題

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

每個 MySQL 實例可以有多個數據庫:

MySQL  如何利用分片來解決 500 億數據的存儲問題

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

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

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

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

每個切片數據庫保持相同的數據庫表及表結構,諸如,有 pins ,boards ,users_has_pins ,users_likes_pins ,pin_liked_by_user 等數據庫表。 在布署時同步構建。

分布數據到切片服務器設計方案

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

ID = (shard ID << 46) | (type ID << 36) | (local ID<<0) 以 Pin: https://www.pinterest.com/pin/241294492511... 為例,讓我們解構這個 Pin 對象的 全局 ID 標識 241294492511762325 : Shard ID = (241294492511762325 >> 46) & 0xFFFF = 3429 Type ID  = (241294492511762325 >> 36) & 0x3FF = 1 Local ID = (241294492511762325 >>  0) & 0xFFFFFFFFF = 7075733

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

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

有兩種類型的數據:對象或關系。對象包含對象本身細節。 如 Pin 。

存儲對象的數據庫表

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

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”, “link”: “http://webpage.com/asdf”, “user_id”: 241294629943640797, “board_id”: 241294561224164665, …}

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

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

> 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 數據庫表中的數據記錄。但是,請仔細想一下,是否在對象的 JSON 數據上加個叫做「 active」的域,把剔除工作交由前端中間業務邏輯去處理或許會更好呢。

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

關系映射數據庫表

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

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

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

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

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

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

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

增大服務能力

在我們的系統中,提升服務處理能力主要三個途徑。最容易的是升級機器(更大的空間,更快的硬盤速度,

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
日韩专区第三页| 天天干天天干天天干天天干天天干| 色婷婷综合久久久久中文字幕| 青青青在线观看视频| 精品少妇人妻av一区二区| 免费网站在线观看黄| 日韩精品视频一二三| 超碰在线公开97| 天天操,天天操| 中日韩av在线播放| 亚洲最新免费视频| 浴室偷拍美女洗澡456在线| 天天干天天操天天干天天操| 神马午夜伦理影院| 无码粉嫩虎白一线天在线观看 | 久久久精品在线视频| 女性隐私黄www网站视频| 日本激情视频在线| 午夜大片在线观看| 狠狠精品干练久久久无码中文字幕| 国产情侣第一页| 一本大道熟女人妻中文字幕在线 | 日本77777| 国产精品久久久久久久久电影网| a级黄色小视频| 免费大片在线观看| 国产麻豆电影在线观看| 无码人妻少妇伦在线电影| 日韩欧美xxxx| 国产高清免费在线| 亚洲国产精品毛片av不卡在线| 香蕉视频xxx| jizzjizz国产精品喷水| 天堂av2020| 国产乱子伦农村叉叉叉| 欧美精品 - 色网| 成人午夜视频免费在线观看| 日韩精品视频网址| 国产av人人夜夜澡人人爽| 永久免费网站视频在线观看| 亚洲色图久久久| 给我免费播放片在线观看| 久久久精品高清| a在线视频观看| 日本精品福利视频| jizz欧美性11| 成人黄色片视频| 少妇人妻大乳在线视频| 午夜av中文字幕| 日韩大片一区二区| 91av资源网| 97超碰在线人人| 69精品丰满人妻无码视频a片| 制服丝袜综合网| 无码人妻精品一区二区三区66| 131美女爱做视频| 黄色一级视频在线播放| 日日噜噜夜夜狠狠久久丁香五月| 中文字幕第88页| 日本在线观看免费视频| caoporn超碰97| 欧美在线观看视频网站| 免费日韩视频在线观看| 成人观看免费完整观看| 国产成人亚洲精品无码h在线 | 日本成年人网址| 精品久久久久久久久久中文字幕| 精品一区二区三区毛片| 超薄肉色丝袜足j调教99| 欧美xxxxxbbbbb| 日韩中文在线字幕| 国产91沈先生在线播放| 2018国产在线| 欧美色图另类小说| 91视频免费版污| 亚洲综合av在线播放| www.se五月| 国产xxxxhd| www.成年人视频| 六月丁香激情网| 免费激情视频在线观看| 欧美丝袜在线观看| 天天操天天干天天玩| 日本福利视频网站| 欧美s码亚洲码精品m码| 老头吃奶性行交视频| 91aaa精品| 国产青青在线视频| 亚洲国产精品三区| 神马午夜伦理影院| 国产精品99久久免费黑人人妻| 日本三级黄色网址| 国产精品av免费观看| 久久久久久久久久福利| 激情成人在线观看| av免费观看网| 亚洲精品乱码久久久久久动漫| 99er在线视频| 香港日本韩国三级网站| 久久人人爽人人爽人人av| 少妇性l交大片| 日韩成人三级视频| 日韩av一卡二卡三卡| 男人添女人下部高潮视频在观看| 欧美成人福利在线观看| 婷婷无套内射影院| 亚洲第一综合网站| 欧美成人福利在线观看| 日本欧美黄色片| 日韩成人午夜影院| 向日葵污视频在线观看| 337p粉嫩大胆噜噜噜鲁| 日本中文字幕一级片| 亚洲精品手机在线观看| 午夜肉伦伦影院| 人妻激情另类乱人伦人妻| 亚洲a级黄色片| 污网站免费在线| 粗暴91大变态调教| 国内自拍在线观看| 日本中文字幕一级片| 天天综合中文字幕| 三级黄色片免费观看| 黄色小视频免费网站| 欧美婷婷精品激情| 18岁视频在线观看| 亚洲熟女乱色一区二区三区| www精品久久| 99久久国产综合精品五月天喷水| 美国av在线播放| 18视频在线观看娇喘| 国产精品无码乱伦| 日韩不卡视频一区二区| dy888午夜| 欧美a级免费视频| 丁香六月激情婷婷| 日韩精品在线视频免费观看| 国产视频在线观看网站| 免费人成在线观看视频播放| 日韩亚洲欧美一区二区| 国产日韩亚洲欧美在线| 国产一级爱c视频| 国产成人黄色片| 男操女免费网站| 日韩不卡的av| 99热这里只有精品免费| 久久久999免费视频| 黄色一级免费大片| www.桃色.com| 欧美精品卡一卡二| 女性隐私黄www网站视频| 色天使在线观看| 水蜜桃在线免费观看| 免费无遮挡无码永久视频| 中文字幕国内自拍| 日韩 欧美 自拍| 国产免费观看高清视频| 91福利国产成人精品播放| 在线观看成人免费| 国产 福利 在线| 性欧美在线视频| 精品丰满人妻无套内射| www.色就是色| 日韩人妻无码精品久久久不卡| 久久综合久久色| 黄色三级中文字幕| 天天视频天天爽| 国产精品久久久久9999爆乳| 国产 porn| 北条麻妃69av| 人妻互换免费中文字幕| 少妇一级淫免费放| 国产二级片在线观看| 在线播放av中文字幕| 欧美三级一级片| 日本黄大片在线观看| 亚洲综合婷婷久久| 无罩大乳的熟妇正在播放| 色呦呦网站入口| 欧美wwwwwww| 无码少妇一区二区三区芒果| 激情五月婷婷六月| 欧美日韩一级在线| 亚洲欧美久久久久| 久久综合久久色| 成年人视频网站免费观看| 欧美日韩午夜爽爽| 国产又大又长又粗又黄| 午夜视频在线网站| 免费毛片小视频| 亚洲天堂av线| 亚洲第一页在线视频| 欧美色图色综合| 在线观看污视频| 成人小视频在线看| 日本免费a视频| 91网站在线观看免费| 日韩 欧美 自拍| 欧美少妇一区二区三区| 日本丰满大乳奶|