生活随笔
收集整理的這篇文章主要介紹了
分布式系统工程实践
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://www.nosqlnotes.net/wp-content/uploads/Distributed_System_Engineering_Practice.pdf
分布式系統(tǒng)工程實(shí)踐 楊傳輝 日照 淘寶 ? 分布式系統(tǒng)工程實(shí)踐 ................................ ................................ ................................ ....................... 1 1 引言 ................................ ................................ ................................ ................................ ........... 3 2 基礎(chǔ)知識(shí) ................................ ................................ ................................ ................................ ... 3 2.1 硬件基礎(chǔ) ................................ ................................ ................................ ....................... 4 2.2 性能估算 ................................ ................................ ................................ ....................... 4 2.3 CAP ................................ ................................ ................................ ................................ 6 2.4 一致性模型 ................................ ................................ ................................ ................... 7 2.5 NOSQL 與 SQL ................................ ................................ ................................ ............... 9 2.6 Two - Phase commit ................................ ................................ ................................ ...... 10 2.7 Paxos ................................ ................................ ................................ ........................... 11 3 關(guān)鍵技術(shù)實(shí)現(xiàn) ................................ ................................ ................................ ......................... 12 3.1 網(wǎng)絡(luò)編程框架 ................................ ................................ ................................ ............. 12 3.2 HA 與 Replication ................................ ................................ ................................ ........ 13 3.3 分裂 ................................ ................................ ................................ ............................. 14 3.4 遷移 ................................ ................................ ................................ ............................. 15 3.5 負(fù)載均衡 ................................ ................................ ................................ ..................... 16 3.6 Chubby ................................ ................................ ................................ ........................ 16 3.7 分布式事務(wù) ................................ ................................ ................................ ................. 17 3.8 Copy - on - write 與 Snap shot ................................ ................................ ........................ 17 3.9 操作日志與 checkpoint ................................ ................................ .............................. 19 3.10 列式存儲(chǔ)與壓縮 ................................ ................................ ................................ ..... 19 4 通用存儲(chǔ)系統(tǒng)分類 ................................ ................................ ................................ ................. 20 5 典型存儲(chǔ)系統(tǒng)工程實(shí)現(xiàn) ................................ ................................ ................................ ......... 21 5.1 單機(jī)存儲(chǔ)引擎 ................................ ................................ ................................ ............. 21 5.1.1 隨機(jī)訪問存儲(chǔ)引擎 ................................ ................................ ......................... 21 5.1.2 通用存儲(chǔ)引擎 ................................ ................................ ................................ . 22 5.1.3 單機(jī)存儲(chǔ)優(yōu)化 ................................ ................................ ................................ . 23 5.2 SQL 數(shù)據(jù)庫(kù) ................................ ................................ ................................ ................. 23 5.3 線上最終一致性系統(tǒng) ................................ ................................ ................................ . 24 5.4 線上弱一致性系統(tǒng) ................................ ................................ ................................ ..... 26 5.5 半線上及線下系統(tǒng) ................................ ................................ ................................ ..... 29 5.5.1 兩層結(jié)構(gòu) ................................ ................................ ................................ ......... 29 5.5.2 GFS ................................ ................................ ................................ ................... 30 5.5.3 Bigtable ................................ ................................ ................................ ............ 31 6 通用計(jì)算系統(tǒng)分類 ................................ ................................ ................................ ................. 32 7 典型計(jì)算系統(tǒng)工程實(shí)現(xiàn) ................................ ................................ ................................ ......... 33 7.1 MapReduce Offlin e ................................ ................................ ................................ ..... 33 7.2 Online 計(jì)算 ................................ ................................ ................................ ................. 34 7.2.1 流式計(jì)算 ................................ ................................ ................................ ......... 34 7.2.2 并行數(shù)據(jù)庫(kù)的 SQL 查詢 ................................ ................................ ................. 35 7.2.3 數(shù)據(jù)倉(cāng)庫(kù)復(fù)雜查詢 ................................ ................................ ......................... 36 8 應(yīng)用 ................................ ................................ ................................ ................................ ......... 38 8.1 電子商務(wù)類 ................................ ................................ ................................ ................. 38 8.2 搜索類 ................................ ................................ ................................ ......................... 38 8.3 社交類 ................................ ................................ ................................ ......................... 39 8.4 郵箱類 ................................ ................................ ................................ ......................... 40 8.5 圖片及視頻類 ................................ ................................ ................................ ............. 40 8.6 數(shù)據(jù)倉(cāng)庫(kù)類 ................................ ................................ ................................ ................. 40 8.7 云服務(wù)類 ................................ ................................ ................................ ..................... 41 9 工程實(shí)現(xiàn)注意事項(xiàng) ................................ ................................ ................................ ................. 41 9.1 工程現(xiàn)象 ................................ ................................ ................................ ..................... 41 9.2 規(guī)范制訂 ................................ ................................ ................................ ..................... 42 9.3 經(jīng)驗(yàn)法則 ................................ ................................ ................................ ..................... 42 9.4 質(zhì)量控制 ................................ ................................ ................................ ..................... 42 9.4.1 測(cè)試第一 ................................ ................................ ................................ ......... 42 9.4.2 代碼 Review ................................ ................................ ................................ .... 42 9.4.3 服務(wù)器程序的資源管理 ................................ ................................ ................. 43 10 致謝 ................................ ................................ ................................ ................................ . 43 11 參考文獻(xiàn) ................................ ................................ ................................ ......................... 43 11.1 書籍類 ................................ ................................ ................................ ..................... 43 11.2 論文類 ................................ ................................ ................................ ..................... 43 11.2.1 分布式理論 ................................ ................................ ................................ ..... 43 11.2.2 Google 系列 ................................ ................................ ................................ .... 44 11.2.3 Dynamo 及 P2P 系列 ................................ ................................ ...................... 44 11.2.4 存儲(chǔ)系統(tǒng) ................................ ................................ ................................ ......... 44 11.2.5 計(jì)算系統(tǒng) ................................ ................................ ................................ ......... 44 11.2.6 其它 ................................ ................................ ................................ ................. 44 11.3 網(wǎng)頁(yè)類 ................................ ................................ ................................ ..................... 45 11.3.1 個(gè)人博客類 ................................ ................................ ................................ ..... 45 11.3.2 專題類 ................................ ................................ ................................ ............. 45 11.3.3 其它 ................................ ................................ ................................ ................. 45 1 引言 NOSQL 的資料很 多, 不過不成體系,讓分布式系統(tǒng)開發(fā)工程師無所適從 。筆者 根據(jù)過去 跟 著陽(yáng)老師 開發(fā)類似 Google GFS/MapReduce/Bigtable 的系統(tǒng)以及對(duì) Dynamo, PNUTS 等典型系 統(tǒng)的理解 嘗試梳理流行的分布式存儲(chǔ)和計(jì)算系統(tǒng) 的分類,設(shè)計(jì)及實(shí)現(xiàn) 。 本文結(jié)構(gòu)安排如下: ? 基礎(chǔ)知識(shí): 一個(gè)大規(guī)模數(shù)據(jù)處理系統(tǒng)工程師必備的基礎(chǔ)知識(shí); ? 關(guān)鍵技術(shù)實(shí)現(xiàn):工程實(shí)踐中遇到的典型問題的解決思路; ? 通用存儲(chǔ)系統(tǒng)分類 :講述筆者 關(guān)于存儲(chǔ)系統(tǒng) 如何劃分的個(gè)人觀點(diǎn); ? 典型存儲(chǔ)系統(tǒng)工程實(shí)現(xiàn):選取 典型的 存儲(chǔ) 系統(tǒng)講述 大致實(shí)現(xiàn); ? 通用計(jì)算系統(tǒng)分類 :講述筆者對(duì)于計(jì)算系統(tǒng)如何劃分的個(gè)人觀點(diǎn); ? 典型計(jì)算系統(tǒng)工程實(shí)現(xiàn): 講述典型計(jì)算系統(tǒng)的大致實(shí)現(xiàn); ? 應(yīng)用:存儲(chǔ) & 計(jì)算 系統(tǒng)應(yīng)用的一些實(shí)例; ? 工程實(shí)現(xiàn)注意事項(xiàng): 總結(jié)設(shè)計(jì)和開發(fā)過程中 可能犯的一些錯(cuò)誤; ? 致謝及參考資料:列出一些值得看的論文和網(wǎng)頁(yè)資料; 每個(gè)章節(jié)涉及的話題都很大,由于筆者的水平實(shí)在是非常 非常 有限,只能說是盡力把自己知 道并能夠說明白的寫下來, 作為自己對(duì)過去工作的回憶 。 把其中任何一個(gè)話題講明白都 遠(yuǎn)遠(yuǎn) 超出了我的能力范疇 ,寫錯(cuò)的地方在所難免, 各位同學(xué)發(fā)現(xiàn)問題 盡管笑一笑, 當(dāng)然,歡迎任 何形式的討論, 我會(huì)盡量和更多的同學(xué)討論來不斷完善這個(gè)文檔。 本文只是一個(gè) 初始 綜述, 后續(xù) 將 細(xì)化每一個(gè)問題 并發(fā)表到博客中。 2 基礎(chǔ)知識(shí) 本章描述工程實(shí)現(xiàn)需要的一些基礎(chǔ)知識(shí),由于篇幅的關(guān)系,只抽取一些認(rèn)為對(duì)理解和設(shè)計(jì)大 規(guī)模系統(tǒng)必要的基礎(chǔ)知識(shí) 進(jìn)行 描述 。另外, 假設(shè)讀者 了解 NOSQL 基 本概念,做過 或者看過 一兩個(gè)類似的系統(tǒng),閱讀過 GFS/Bigtable/Paxos 相關(guān)的論文。 分布式理論有一個(gè)特點(diǎn)是:大 致的做法是很容易想到的,但是完全沒 有問題的做法非常難想,理解理論的用處就 在于區(qū)分 出想法的問題在哪兒以及實(shí)現(xiàn)的難度。 2.1 硬件基礎(chǔ) 分布式系統(tǒng)開發(fā)工程師需要了解硬件的大致價(jià)格,熟記硬件的性能。 硬件 大致 性能如下: 標(biāo)記為紅色性能參數(shù)比較常用,其中,磁盤的性能指標(biāo)專指分布式平臺(tái)專用的大容量 SATA 磁盤,尋道時(shí)間為 8~10ms ,順序讀取速率為 40~50MB 。 某些應(yīng)用 使用 SAS 磁盤或者 Flash 盤,性能較好,評(píng)估時(shí)需查看硬件的性能參數(shù)。磁盤和網(wǎng)絡(luò)都有一個(gè)特征,一次讀寫的數(shù)據(jù) 量越大性能越好,這是由硬件特征及底層軟件算法決定的,如 tcp 慢連接和磁盤尋道時(shí)間長(zhǎng)。 2.2 性能估算 給定一個(gè)問題,往往會(huì)有多種設(shè)計(jì)方案,而方案評(píng)估的一個(gè)重要指標(biāo)就是性能,如何在系統(tǒng) 設(shè)計(jì)時(shí)估算而不是程序執(zhí)行時(shí)測(cè)試得到性能數(shù)據(jù)是系統(tǒng)架構(gòu)設(shè)計(jì)的重要技能。性能估算有如 下用途: 1) 多種設(shè)計(jì)方案選擇; 2) 評(píng)價(jià)程序?qū)崿F(xiàn)是否足夠優(yōu)化; 3) 向框架 / 服務(wù)提供方提出性能要求的依據(jù); L1 c ache reference 0.5ns Branch mispredict 5ns L2 cache reference 7ns Mutex lock/unlock 100ns Main memory reference 100ns Send 1M bytes over 1Gbps network 10ms Read 1M sequentially from memory 0.25ms Round trip within data center 0.5ms Disk seek 8~10ms Read 1MB sequentially from disk 20~25ms 很多同學(xué)喜歡 通過查看程序運(yùn)行時(shí) CPU 及網(wǎng)絡(luò)的使用情況來評(píng)價(jià)程序是否足夠優(yōu)化, 這 也是一種很重要的方法。然而,這種方法掩蓋了不優(yōu)化的實(shí)現(xiàn),如 O(N) 的算法被錯(cuò)誤實(shí)現(xiàn) 成 O(N^2) ,網(wǎng)絡(luò)收發(fā)冗余數(shù)據(jù)等。 性能評(píng)估需要假設(shè)程序的執(zhí)行環(huán)境,如集群規(guī)模及機(jī)器配置,集群上其它服務(wù)占用資源的比 例。 對(duì)硬件性能指標(biāo)有了初步認(rèn)識(shí)以后,我們可以做出一些簡(jiǎn)單的判斷,如: 某 K - V 引擎 RD : 我們的 K - V 引擎 單 客戶端同步讀取每秒可以達(dá)到 18000/s 。 問:是否批量讀取? 答:是,每批讀取 10 個(gè)記錄。 由于 tcp Round trip 時(shí)間為 0.5ms ,讀取請(qǐng)求個(gè)數(shù)的理論極限為 2000/s ,而 上例中 K - V 引 擎的 RD 卻說單客戶同步讀取可以達(dá)到 18000/s ,可以斷定 該 RD 指的是批量讀取方式。且這 已經(jīng)是單機(jī)能夠做到的極限值了。 下面我們通過幾個(gè)實(shí)例說明如何進(jìn)行性能評(píng)估。 1. 1 GB 的 4 字節(jié)整數(shù) , 內(nèi)存 排序時(shí)間為多少? 拿到這個(gè)問題,我們往往會(huì)計(jì)算 CPU 運(yùn)算次數(shù),如快排的運(yùn)算次數(shù)為 1.4 * N * log(N) , 其中 1.4 為快排的系數(shù),再根據(jù) CPU 的運(yùn)算頻率計(jì)算出排序耗時(shí)。不過這種方法很土也不是 很準(zhǔn), Jeff Dean 告訴我們可以這樣估算:排序時(shí)間 = 比較時(shí)間(分支預(yù)測(cè)錯(cuò)誤) + 內(nèi)存訪 問時(shí)間。快排過程中會(huì)發(fā)生大量的分支預(yù)測(cè)錯(cuò)誤,所以比較次數(shù)為 2^28 * log (2^28) ≈ 2^33 , 其中約 1/2 的比較會(huì)發(fā)生分支預(yù)測(cè)錯(cuò)誤,所以比較時(shí)間為 1/2 * 2 ^ 32 * 5ns = 21s ,另外,快 排每次找到分割點(diǎn)都需要一遍內(nèi)存移動(dòng)操作,而內(nèi)存順序訪問性能為 4GB/s ,所以內(nèi)存訪問 時(shí)間為 28 * 1GB / 4GB = 7s 。因此,單線程排序 1GB 4 字節(jié)整數(shù)總時(shí)間約為 28s 。 2. Bigtable 設(shè)計(jì)的性能指標(biāo)分析 假設(shè) Bigtable 總體設(shè)計(jì)中給出的性能指標(biāo)為 : 系統(tǒng)配置: 50 臺(tái) 4 核 8GB 內(nèi)存 12 路 SATA 硬盤,同樣數(shù)量的客戶端; Table : row name : 16 - byte , column : 16 - byte , value : 1KB ; 64KB data block ; no compression ; R andom reads (in disk) : 1KB/item*300item/s*50=15MB/s Random reads (in memory) : 1KB/item*4000item/s*50=200MB/s Random writes : 1KB/item*2000item/s*50=100MB/s S equential reads(in disk) : 1KB/item*1000item/s*50=50MB/s Sequential writes : 1KB/item*2000item/s*50=100MB/s 先看磁盤中的隨機(jī)讀取性能,由于在 Bigtable 的設(shè)計(jì)中每個(gè)隨機(jī)讀取 都要讀取一個(gè) 64KB 的大塊,而磁盤中讀取 64KB 數(shù)據(jù)時(shí)間為:磁盤尋道時(shí)間 + 讀取時(shí)間 = 10 ms + 64KB / 50MB/s = 12 ms 。所以每秒讀取 300 個(gè)記錄 指多客戶端讀取或者單客戶端異步 / 批量讀取 。由于每臺(tái) 機(jī)器有 12 個(gè) SATA 大容量磁盤,隨機(jī)讀的理論值為 12 * 1s / 12ms = 10 00 個(gè) /s 。設(shè)計(jì)為每秒 讀取 300 個(gè)是考慮到有負(fù)載平衡等因素簡(jiǎn)單地打了一個(gè)折扣 。 再看內(nèi)存中的隨機(jī)讀取。一般來說,內(nèi)存操作都是每秒 1W~10W 。由于網(wǎng)絡(luò)發(fā)送小數(shù)據(jù) 有較多 overhead 且 Bigtable 內(nèi)存操作有較多的內(nèi)存開銷,所以保守設(shè)計(jì)為單機(jī)每秒讀取 4000 個(gè)記錄。 其它的可類似分析。性能分析可能會(huì)很復(fù)雜,因?yàn)椴煌那闆r下決定性能的瓶頸不一樣, 有的時(shí)候是網(wǎng)絡(luò),有的時(shí)候是磁 盤,有的時(shí)候甚至是機(jī)房的交換機(jī)。這種性能分析的經(jīng)驗(yàn)是 需要慢慢積累的。 最后,我們?cè)倏纯茨骋粋€(gè) MapReduce 應(yīng)用的例子 。 MapReduce 可以簡(jiǎn)單地分為幾個(gè)過 程: Map 處理時(shí)間 + shuffle 和排序時(shí)間 + reduce 處理時(shí)間,雖然 shuffle 、 map 處理和排序 可以部分并行,但性能估算的時(shí)候不必考慮。假設(shè) 50 臺(tái)機(jī)器,原始輸入為 50G , 例中 MapReduce 應(yīng)用的 map 函數(shù) 處理時(shí)間為 100s , reduce 函數(shù) 處理時(shí)間為 60s , shuffle 的中間 結(jié)果數(shù)據(jù)量為 300G , reduce 輸出的最終結(jié)果大小 為 600M 。 Map 處理時(shí)間 = 輸入讀取時(shí)間 + Map 函數(shù) 處理時(shí)間 + 輸出中間結(jié)果時(shí)間 其中,輸入讀取時(shí)間 = 50G / 2.5G = 25s (50 臺(tái)機(jī)器,假設(shè)每臺(tái)機(jī)器讀取帶寬為 50M/s) , M ap 函數(shù) 處理時(shí)間 = 60s , 輸出中間結(jié)果時(shí)間 = 300G / 15G = 20s (50 臺(tái)機(jī)器,每臺(tái)機(jī)器 12 個(gè)磁盤,假設(shè)用滿 6 個(gè) 磁盤,帶寬為 6 * 50M = 300M) 所以, Map 處理時(shí)間 = 25s + 60s + 20s = 105s Shuffle 和排序時(shí)間 = shuffle 時(shí)間 + 排序時(shí)間 其中, shuffle 時(shí)間 = 300G / 2G = 150s (50 臺(tái)機(jī)器,假設(shè)每臺(tái)機(jī)器的讀取和寫入帶寬均為 40M ,單機(jī)總帶寬為 80M) 排序時(shí)間 = 單機(jī)排序 6G 的時(shí)間,假設(shè)每條記錄為 1KB = 排序比較時(shí)間 + 訪問時(shí)間, 約為 25s 所以, shuffle 和排序的時(shí)間 = 150s + 25s = 175s Reduce 處理時(shí)間 = reduce 函數(shù) 處理時(shí)間 + 最終結(jié)果輸出時(shí)間 其中, reduce 函數(shù) 處理時(shí)間 = 100s , 最終結(jié)果輸出時(shí)間 = 600M / 500M (50 臺(tái)機(jī)器,單機(jī)寫 DFS 假設(shè)時(shí)間為 10M/s) = 1s ( 忽略 ) 所以, 例中的 MapReduce 應(yīng)用 運(yùn)行一遍大致需要的時(shí)間 = Map 處理時(shí)間 + shuffle 和排 序時(shí)間 + Reduce 處理時(shí)間 = 105s + 175s + 100s = 380s ,當(dāng)然, MapReduce 過程中還有框架 的開銷和其它應(yīng)用的影響,我們可以簡(jiǎn)單地認(rèn)為影響為 20% ,所以總時(shí)間 = 380s + 380s * 20% = 456s ,約為 7~8 min 。 當(dāng)然, MapReduce 應(yīng)用 實(shí)際的性能估算不會(huì)如此簡(jiǎn)單,實(shí)際估算時(shí)需要考慮每臺(tái)機(jī)器上 啟動(dòng)的 Map 和 Reduce 個(gè)數(shù)等因素,且需要根據(jù)實(shí)驗(yàn)的結(jié)果不斷地驗(yàn)證和重新調(diào)整估算。但 是,我們至少可以保證,估算的結(jié)果和實(shí)際不會(huì)相差一個(gè)數(shù)量級(jí),估算結(jié)果可以用來指導(dǎo)初 期的設(shè)計(jì)和 Map/Reduce Worker 的個(gè)數(shù)、 Map/Reduce 任務(wù)數(shù)選擇,評(píng)估應(yīng)用的可優(yōu)化空間 并作為向 MapReduce 框架提供小組提出需求的依據(jù)。 性能估算是大規(guī)模系統(tǒng)設(shè)計(jì)中較難掌握的技能,開始性能估算時(shí)可能估計(jì)得很不準(zhǔn),不過不 要?dú)怵H,通過在項(xiàng)目中不斷練習(xí),大規(guī)模系統(tǒng)的分析和設(shè)計(jì)能力 才能做到有理可依 。 2.3 CAP CAP 是一個(gè)很時(shí)髦的概念 , 然而, 對(duì)于設(shè)計(jì)和實(shí)現(xiàn)大規(guī)模分布式系統(tǒng)而言,只需要在腦海里 面有一個(gè)粗略的概念即可。 我們先看看 CAP 是怎么回事。 CAP 理論由 Berkerly 的 Brewer 教授提出 ,在最初的論文中 , 三者含義如下: ? 一致性 ( C onsistency) : 任何一 個(gè)讀操作總是能讀取到之前完成 的寫操作結(jié)果 ; ? 可用性 ( A vailability) : 每一個(gè)操作總是能夠在確定的時(shí)間內(nèi)返回; ? 分區(qū)可容忍性 (Tolerance of network P artition) :在出現(xiàn)網(wǎng)絡(luò)分區(qū)的情況下,仍然能夠滿足一 致性和可用性; CAP 理論認(rèn)為,三者不能同時(shí)滿足,并給出了證明,簡(jiǎn)單闡述如下: 假設(shè)系統(tǒng)出現(xiàn)網(wǎng)絡(luò)分區(qū) 為 G1 和 G2 兩個(gè)部分,在一個(gè)寫操作 W1 后面有一個(gè)讀操作 R2 , W1 寫 G1 , R2 讀取 G2 , 由于 G1 和 G2 不能通信,如果讀操作 R2 可以終結(jié)的話,必定不能讀取寫操作 W1 的操作結(jié) 果。 然而, 這種對(duì)一致性及可用性的定義方法在工程實(shí)踐上意義不大, CAP 理論只是粗略地告訴 我們 “天下沒有免費(fèi)的午餐”。 比如 Availability 的定義, 10 秒鐘停服務(wù)和 1 個(gè)小時(shí)停服務(wù)在 工程實(shí)踐中完全是兩個(gè)概念。因此 ,我們往往會(huì)修改 CAP 的 定義如下: ? 一致性 ( C onsistency) : 讀操作 總是能讀取到之前完成的寫操作結(jié)果,滿足這個(gè)條件的系統(tǒng) 稱為 強(qiáng)一致系統(tǒng),這里的“之前”一般對(duì)同一個(gè)客戶端而言,但可能是一個(gè)客戶端的多個(gè) Session ; ? 可用性 ( A vailability) : 讀寫操作在 單臺(tái) 機(jī)器發(fā)生故障的情況下仍然能夠 正常執(zhí)行,而不需要 等到機(jī)器重啟或者機(jī)器上的服務(wù)分配給其它機(jī)器才能執(zhí)行; ? 分區(qū)可容忍性 (Tolerance of network P artition) : 機(jī)房停電 或者機(jī)房間網(wǎng)絡(luò)故障 的時(shí)候仍然能 夠滿足一致性和可用性; 工程實(shí)踐對(duì)網(wǎng)絡(luò)分區(qū)考慮較少, 一般可以認(rèn)為:一致性和寫操作的可用性不能同時(shí)滿足, 即 如果要保證強(qiáng)一致性,那么出現(xiàn)機(jī)器故障的時(shí)候,寫操作需要等機(jī)器重啟或者機(jī)器上的服務(wù) 遷移到別的機(jī)器才可以繼續(xù)。 2.4 一致性模型 Amazon 的 CTO 專門在官網(wǎng)中闡述了一致性模型, 足見其重要性,可以認(rèn)為, 一 致性要求 直 接決定了存儲(chǔ)系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)的復(fù)雜度。 為了更好的描述客戶端一致性,我們通過以下的場(chǎng)景來進(jìn)行,這個(gè)場(chǎng)景中包括三個(gè)組成部分: ? 存儲(chǔ)系統(tǒng) 存儲(chǔ)系統(tǒng)可以理解為一個(gè)黑盒子,它為我們提供了可用性和持久性的保證。 ? Process A Process A 主要實(shí)現(xiàn)從存儲(chǔ)系統(tǒng) write 和 read 操作 ? Process B 和 Process C Process B 和 C 是獨(dú)立于 A ,并且 B 和 C 也相互獨(dú)立的,它們同時(shí)也實(shí)現(xiàn)對(duì)存儲(chǔ)系統(tǒng)的 write 和 read 操作。 下面以上面的場(chǎng)景來描述下不同程度的一致性: ? 強(qiáng)一致性 強(qiáng)一致性(即時(shí)一致性) 假如 A 先寫入了一個(gè)值到存儲(chǔ)系統(tǒng),存儲(chǔ)系統(tǒng)保證后續(xù) A,B,C 的讀取操作都將返回最新值 ? 弱一致性 假如 A 先寫入了一個(gè)值到存儲(chǔ)系統(tǒng),存儲(chǔ)系統(tǒng)不能保證后續(xù) A,B,C 的讀取操作能讀取到 最新值。此種情況下有一個(gè) “ 不一致性窗口 ” 的概念,它特指從 A 寫入值,到后續(xù)操作 A,B,C 讀取到最新值這一段時(shí)間。 ? 最終一致性 最終一致性是弱一致性的一種特例。假如 A 首先 write 了一個(gè)值到存儲(chǔ)系統(tǒng),存儲(chǔ)系統(tǒng) 保證如果在 A,B,C 后續(xù)讀取之前沒有其它寫操作更新同樣的值的話,最終所有的讀取操 作都會(huì)讀取到最 A 寫入的最新值。此種情況下,如果沒有失敗發(fā)生的話, “ 不一致性窗 口 ” 的大小依賴于以下的幾個(gè)因素:交互延遲,系統(tǒng)的負(fù)載,以及復(fù)制技術(shù)中 replica 的 個(gè)數(shù)(這個(gè)可以理解為 master/salve 模式中, salve 的個(gè)數(shù))。 一致性 模型 的變體如下: ? Causal consis tency (因果一致性) 如果 Process A 通知 Process B 它已經(jīng)更新了數(shù)據(jù),那么 Process B 的后續(xù)讀取操作則讀取 A 寫入的最新值,而與 A 沒有因果關(guān)系的 C 則可以最終一致性。 ? Read - your - writes consistency 如果 Process A 寫入了最新的值,那么 Process A 的后續(xù)操作都會(huì)讀取到最新值。但是其它用 戶可能要過一會(huì)才可以看到。 ? Session consistency 此種一致性要求客戶端和存儲(chǔ)系統(tǒng)交互的整個(gè)會(huì)話階段保證 Read - your - writes ,數(shù)據(jù)庫(kù)分庫(kù) 以后 一般會(huì)提供這種一致性保證,使得同一個(gè) Session 的讀寫操作發(fā)送到同一臺(tái)數(shù)據(jù)庫(kù)節(jié)點(diǎn) 。 ? Monotonic read consistency 此種一致性要求如果 Process A 已經(jīng)讀取了對(duì)象的某個(gè)值,那么后續(xù)操作將不會(huì)讀取到更早 的值。 ? Monotonic write consistency 此種一致性保證系統(tǒng)會(huì)序列化執(zhí)行一個(gè) Process 中的所有寫操作。 為了便于后續(xù)的說明, 我們修改 Amazon CTO 關(guān)于最終一致性的定義 。 Dynamo 通過 NWR 策略提供的最終一致性主要是針對(duì) Dynamo 的多個(gè)副本而言的,它們之間保持最終一致。不 過對(duì)于用戶,我們假設(shè) N=3, W=2, R=2 的一種情況,用戶 先調(diào)用 W1 寫 A 和 B 兩個(gè)副本后成 功返回,接著調(diào)用 W2 寫 B 和 A 兩個(gè)副本后成功返回,可能出現(xiàn)在副本 A 上 W1 先于 W2 執(zhí) 行,而在副本 B 上 W2 先于 W1 執(zhí)行,雖然副本 A 和 B 都 能夠 通過執(zhí)行滿足交換律的合并操 作,比如基于 ” last write wins ” 的策略進(jìn)行合并使得最終副本 A 和 B 上的數(shù)據(jù)完全一致, 但是 可能出現(xiàn)一些異常情況,比如副本 A 和 B 所在的機(jī)器時(shí)鐘不一致,合并的結(jié)果是 W1 把 W2 給覆蓋了 , W2 的操作結(jié)果消失了 。這顯然 與用戶的期望是不一致的。 為了方便后續(xù)對(duì)系統(tǒng)進(jìn)行劃分, 我們 把 Amazon Dynamo 這種需要依賴操作合并,可能 會(huì)丟失數(shù)據(jù)的模型從最終一致性模型中排除出去 。 最終一致性 模型要求同一份數(shù)據(jù)同一時(shí) 刻只能被一臺(tái)機(jī)器修改, 也就是說機(jī)器宕機(jī) 時(shí)需要停很短 時(shí)間寫服務(wù) 。 Amazon Dynamo 提 供的一致性模型我們歸類到一般的弱一致性模型中。 2.5 NOSQL 與 卑 NOSQL 可以認(rèn)為是選取了 SQL 特性的子集, 在擴(kuò)展性和用戶接口友好 兩個(gè) 方面做了一 個(gè)權(quán)衡。 “越多選擇,越多迷茫” ,實(shí)踐經(jīng)驗(yàn)告訴我們,如果將 SQL 的 功能完全暴露給用戶, 用戶一定會(huì)使用一些我們不希望的功能,比如多表 join ,外鍵,等 等 。 NOSQL 的意義在于 , 我們預(yù)先定義一些特性,這些特性滿足某一個(gè)應(yīng)用的需求,并且 只滿足這些特性使得我們的 系統(tǒng)很容易擴(kuò)展。 SQL 定義了一個(gè)功能全集, NOSQL 根據(jù)應(yīng)用特點(diǎn)選取幾種特定的應(yīng)用定義 不同的特性集合 ,以適應(yīng)互聯(lián)網(wǎng)數(shù)據(jù)量高速膨脹的需求。 一般來說, NOSQL 的應(yīng)用會(huì)比 SQL 的應(yīng)用更加注意可用性, 所以 NOSQL 應(yīng)用對(duì)外表現(xiàn) 為經(jīng)常可以選擇最終一致性模型 。不過,從通用系統(tǒng)的角度看,這里的最終一致性指:大多 數(shù)操作允許讀取老的數(shù)據(jù) ,少數(shù)操作仍然希望讀取最新的數(shù)據(jù),并且應(yīng)用不希望出現(xiàn)數(shù)據(jù)丟 失的情況。 所以,不能因?yàn)?NOSQL 就容忍數(shù)據(jù)丟失的情況,雖然這會(huì)極大地加大系統(tǒng)設(shè)計(jì) 和實(shí)現(xiàn)的難度。 另外, NOSQL 不等于必須用 MapReduce 做計(jì)算模型,雖然二者經(jīng)常結(jié)對(duì)出現(xiàn),不過本 質(zhì)上是不相關(guān)的。 NOSQL 比較常見的模型包括: ? KV 模型 :只支持最簡(jiǎn)單的針對(duì) <key, value> 對(duì)的操作 ? 支持簡(jiǎn)單 table schema 的模型,如 Bigtable 模型 由于 NOSQL 相對(duì) SQL 而言更加注重?cái)U(kuò)展性、成本等, NOSQL 有一些共同 的設(shè)計(jì)原則: ? 假設(shè)失效是必然發(fā)生的 : NOSQL 注意擴(kuò)展性和成本,機(jī)器數(shù)變多時(shí),原本屬于異 常現(xiàn)象的機(jī)器故障變成一種正常現(xiàn)象, NOSQL 也采用一些比較便宜的普通 PC 機(jī), 要求通過軟件的方法處理錯(cuò)誤。 ? 限定應(yīng)用模式。從最為簡(jiǎn)單的 KV 應(yīng)用模型,到復(fù)雜的支持用戶自定義 schema 的 Bigtable 模型, NOSQL 支持的接口永遠(yuǎn)不可能和 SQL 相比。一般來說, NOSQL 系統(tǒng) 都只支持隨機(jī)讀和順序讀 ,少量系統(tǒng)支持表索引,類似外鍵這種影響擴(kuò)展性且不實(shí) 用的功能基本是不需要支持的。 ? 擴(kuò)容: 數(shù)據(jù)庫(kù)擴(kuò)容一般是成倍增加機(jī)器的,而 NOSQL 系統(tǒng)一般是一臺(tái) 或者少量幾 臺(tái)構(gòu)成一個(gè)機(jī)器組加入系統(tǒng)。 一般有兩種 數(shù)據(jù)分布方法,一種是一致性 Hash ,這 個(gè)算法在 Dynamo 論文中有詳細(xì)的介紹,另外一種方法是將整個(gè)表格分成連續(xù)的小 段,每個(gè)小段是一個(gè)子表,由全局管理機(jī)器負(fù)責(zé)將每個(gè)小段分配到新加入的數(shù)據(jù)讀 寫服務(wù)機(jī)器。 用一個(gè)例子說明取舍 SQL 的部分特性帶來的好處。比如單機(jī) SQL 的 add 操作,這是 非 常容易的,然而,在多機(jī)上的實(shí)現(xiàn)變得非常困難。 因?yàn)槲覀冃枰僮鞫鄠€(gè)副本,可能出現(xiàn)某 些 操作成功,某些永遠(yuǎn)不成功的情況,我們只能通過一些鎖的方法來解決,比如分布式事務(wù) 的兩階段悲觀鎖或者另外一種 樂觀鎖。 Mysql 團(tuán)隊(duì)也有部分同學(xué)開始通過削減 SQL 模型不必要的特性來滿足互聯(lián)網(wǎng)數(shù)據(jù)高速增 長(zhǎng)的需求,它們發(fā)起了一個(gè)叫做 Drizzle 的項(xiàng)目。 Drizzle 誕生于 MySQL ( 6.0 )關(guān)系數(shù)據(jù)庫(kù)的 拆分。在過去幾個(gè)月里,它的開發(fā)者已經(jīng)移走了大量非核 心的功能(包括視圖、觸發(fā)器、 已編譯語句、存儲(chǔ)過程、查詢緩沖、 ACL 以及一些數(shù)據(jù)類型),其目標(biāo)是要建立一個(gè)更精簡(jiǎn)、 更快的數(shù)據(jù)庫(kù)系統(tǒng)。 個(gè) group 同一時(shí)刻總是有一個(gè) Master 節(jié)點(diǎn)作為代表, Slave 節(jié)點(diǎn)上的狀態(tài)與 Master 不一致時(shí) 以 Master 為準(zhǔn)。 工程實(shí)踐中,分裂仍然是很復(fù)雜的,因此國(guó) 內(nèi)幾 乎所有的分布式存儲(chǔ)系統(tǒng)都采用預(yù)先切 分 好 tablet 的方法。只要切分 得比較細(xì),系統(tǒng)支撐一兩年是沒有問題的,等到出現(xiàn)問題時(shí)可 以整個(gè)系統(tǒng)停服務(wù)對(duì)數(shù)據(jù)重新劃分。 3.4 遷移 我們?nèi)匀患僭O(shè)整個(gè)大表按照類似 Bigtable 中的方法被劃 分為很多的子表 tablet 。 子表遷 移在 集群主控機(jī)的指導(dǎo)下進(jìn)行,遷移的做法和分裂有很多共通 之處。 假設(shè)機(jī)器 A 需要將子表遷移到機(jī)器 B ,遷移的做法與單機(jī) 子表分裂 時(shí) 拷貝數(shù)據(jù)的方法類 似。分為兩個(gè)階段,第一個(gè)階段將機(jī)器 A 的待遷移子表的數(shù)據(jù)拷貝到 機(jī)器 B , 這個(gè)階段新來 的修改操作只記錄操作日志;第二個(gè)階段停止寫服務(wù),將第一個(gè)階段 拷貝數(shù)據(jù)過程中接收到 的修改操作拷貝到機(jī)器 B ;數(shù)據(jù)遷移完成時(shí)主控機(jī)修改被遷移子表的位置信息,整個(gè)遷移過 程結(jié)束。 同樣,如果單機(jī)存儲(chǔ)引擎支持快照功能,整個(gè)流程會(huì)更加容易和高效。 Bigtable 的遷移依賴于底層 GFS 提供可靠的文件存儲(chǔ) , Bigtable 寫操作的操作日志持久 化到 GFS 中,且每個(gè) tablet 由一臺(tái) Tablet Server 提供服務(wù)。當(dāng) Tablet Server 出現(xiàn)宕機(jī)或者負(fù) 載平衡 需要執(zhí)行子表遷移操作時(shí), 只需要停止源 Tablet Server 對(duì)待遷移 tablet 的服務(wù)并在目 的 Tablet Server 上重新加載 tablet 即可。 由于 Bigtable 有 GFS 提供可靠存儲(chǔ),我們可以認(rèn)為 Tablet Server 服務(wù)節(jié)點(diǎn)是無狀態(tài)的。 我們 在這里提出 一種設(shè)計(jì)方案:將機(jī)器分成一個(gè)一個(gè)的 group ,每一個(gè)子表都在某個(gè) group 的每臺(tái)機(jī)器 存放一個(gè)備份 ,同一個(gè)時(shí)刻 一個(gè) group 中只有一臺(tái)機(jī)器提供寫服務(wù),其它 機(jī)器都提供讀服務(wù)。 將子表從 group A 遷移到 group B 其實(shí)就是將子表從 group A 中的 Master 機(jī)器遷移到 group B 中的 Master 機(jī)器,整個(gè)過程由集群的主控機(jī)來協(xié)調(diào)。 下面我們考慮一下 遷移過程中發(fā)生的各種異常情況: 1, 遷移的第一個(gè)階段 group A 中 Master 宕機(jī): group A 中某臺(tái)與 Master 保持 強(qiáng)同步的 Slave 接替 Master 對(duì)外服務(wù), 整個(gè)遷移過程 失敗結(jié)束 ; 2, 遷移的第二個(gè)階段 group A 中 Master 宕機(jī): group A 中某臺(tái)與 Master 保持強(qiáng)同步的 Slave 接替 Master 對(duì)外服務(wù),整個(gè)遷移過程失敗結(jié)束 ; 3, 遷移過程中 group B 中 Master 宕機(jī):整個(gè)遷移過程失敗結(jié)束; 4, 拷貝數(shù)據(jù)完成后集群主控機(jī)修改子表位置信息失敗:此時(shí)被遷移 tablet 在 group A 和 group B 中的數(shù)據(jù)完全一樣,任意一個(gè) group 提供服務(wù)均可; 5, 遷移完成后 group A 中 Master 宕機(jī): group A 中某臺(tái)與 Master 保持強(qiáng)同步的 Slave 接 替 Master 對(duì)外服務(wù), 這個(gè) Slave 可能 不 知道子表已經(jīng)遷移的信息。 子表遷移后客戶端寫操作 需要重新建立連接,這個(gè)過程會(huì)請(qǐng)求集群的主控機(jī), 但是 group A 的機(jī)器可能使用老數(shù)據(jù)繼 續(xù)提供讀服務(wù),這就需要 Master 將子表遷移信息告知 group A 中的其它機(jī)器。 上述的機(jī)器同構(gòu)的做法有一個(gè)問題: 增加副本需要 全部 拷貝 一臺(tái)機(jī)器 存儲(chǔ)的 數(shù)據(jù), 如果 數(shù)據(jù)總量為 1TB ,拷貝限速 20MB/s ,拷貝時(shí)間為十幾個(gè)小時(shí),另外, 子表遷移 的 工程實(shí)現(xiàn) 也比較麻煩 。 因此 , 工程上多數(shù)系統(tǒng)靜態(tài)分配好每個(gè)子表所在的機(jī)器并且不遷移,如數(shù)據(jù)庫(kù) sharding 預(yù)先分配好每一份數(shù)據(jù)所在的機(jī)器。 另外一種做法是設(shè)計(jì)的時(shí)候 分離靜態(tài)數(shù)據(jù)和修 改數(shù)據(jù),定期合并,遷移的時(shí)候只遷移靜態(tài)數(shù)據(jù),這個(gè)思想在 淘寶最近研發(fā)的 Oceanbase 系統(tǒng)里面有所體現(xiàn)。 3.5 負(fù)載均衡 負(fù)載平衡是一個(gè)研究課題,難點(diǎn)在于負(fù)載平衡的策略和參數(shù) 調(diào)整,工程化的難度不大, 和數(shù)據(jù)挖掘相關(guān)的 項(xiàng)目有些類似,需要不斷地做假設(shè)并做實(shí)驗(yàn)驗(yàn)證。 負(fù)載平衡有兩種思路,一種是集群總控機(jī)根據(jù)負(fù)載情況全局調(diào)度,另一種思路是采用 DHT 方法。 第二種思路可以參考 Amazon Dynamo 的論文 , DHT 算法中每個(gè)節(jié)點(diǎn)分配的 token 決定 了數(shù)據(jù)及負(fù)載的分布。 假設(shè) DHT 環(huán)中有 S 個(gè)節(jié)點(diǎn),一種比較好的 token 分配方法是將整個(gè) Hash 空間分成 Q 等份, Q >> S , token 分配維持每個(gè)節(jié)點(diǎn)分配 Q/S 個(gè) token 的特性。當(dāng)節(jié)點(diǎn) 下線時(shí),需要將它所服務(wù)的 token 分配給其它節(jié)點(diǎn),從而保持每個(gè)節(jié)點(diǎn)包含 Q/S 個(gè) token 的 特性;同樣,當(dāng)新節(jié)點(diǎn)上線時(shí),也需要 從集群中已有的節(jié)點(diǎn)獲取 token 使得最終維持每個(gè)節(jié) 點(diǎn) Q/S 個(gè) token 的特性。 第一種 思路需要工作機(jī)通過 heartbeat 定時(shí)將讀、寫個(gè)數(shù),磁盤,內(nèi)存負(fù)載等信息 發(fā)送 給主控機(jī),主控機(jī)根據(jù)負(fù)載計(jì)算公式 計(jì)算出需要遷移的數(shù)據(jù)放入到遷移隊(duì)列中等待執(zhí)行 。 負(fù) 載平衡的時(shí)候需要注意控制節(jié)奏,比如一臺(tái)工作機(jī)剛上線的時(shí)候,由于負(fù)載最輕,如果主控 機(jī) 將大量的數(shù)據(jù)遷移到新上線的機(jī)器,由于遷移過程不能提供寫服務(wù),整個(gè)系統(tǒng)的對(duì)外表現(xiàn) 性能會(huì)因?yàn)樾略鰴C(jī)器而變差。 一般來說,從新機(jī)器加入到集群負(fù)載達(dá)到比較均衡的狀態(tài)需要 較長(zhǎng)一段時(shí)間,比如 30 分鐘到一個(gè)小時(shí)。 3.6 Chubby Chubby 是 Google 的 Paxos 實(shí)現(xiàn), Paxos 靠譜的實(shí)現(xiàn)不多, Chubby 毫無疑問是做的最優(yōu)秀的 。 Chubby 通過類似文件系統(tǒng)接口的方式給用戶暴露分布式鎖服務(wù)。 我們先看看應(yīng)用是如何使 用 Chubby 服務(wù)的。 在 GFS/Bigtable 論文中,我們至少能夠看到有如下幾處 使用了 Chubby 。 1, Master 選舉。 Master 宕機(jī)時(shí), 與 Master 保持強(qiáng)同步的 Slave 切換為 Master 繼續(xù)提供服務(wù)。 在這個(gè)過程中, Master 和 Slave 都定時(shí)向 Chubby 請(qǐng)求成為 Master 的鎖, Master 鎖有一個(gè) Lease 的期限,如果 Master 正常,一定會(huì)在 Master 鎖沒有過期的時(shí)候申請(qǐng)延長(zhǎng)鎖的時(shí)間,繼續(xù)提 供服務(wù)。當(dāng) Master 宕機(jī)且鎖的 Lease 過期時(shí), Slave 將搶到 Master 鎖 切換為 Master 。 2, tablet 服務(wù)。為了保證強(qiáng)一致性,一個(gè) tablet 同一時(shí)刻只允許被一個(gè) Tablet Server 加載 提 供服務(wù)。每個(gè) tablet server 啟動(dòng)時(shí)都向 Chubby 服務(wù)獲取一個(gè)鎖,每當(dāng) Master 發(fā)現(xiàn) tablet server 出現(xiàn)異常時(shí),它也嘗試獲取該 Tablet server 的鎖。 Master 和 Tablet Server 二者只有一個(gè)節(jié)點(diǎn) 能夠獲取到鎖,如果鎖被 Master 獲取,可以確定 Tablet Server 已經(jīng)宕機(jī),此時(shí)可以將它服 務(wù)的 tablet 分配給其它機(jī)器。 3, 存儲(chǔ) Bigtable 表格的 sche ma 信息。 由于 Chubby 可以認(rèn)為是一個(gè)一致的共享存儲(chǔ),并且 schema 的訪問壓力不大, Chubby 可以存儲(chǔ) schema 信息。 我們?cè)賮砜纯?Chubby 內(nèi)部大致是如何實(shí)現(xiàn)的。 Chubby 一般有五臺(tái)機(jī)器組成一個(gè)集群,可以 部署成兩地三機(jī)房,這樣任何一個(gè)機(jī)房停電都不影響 Chubby 服務(wù)。 Chubby 內(nèi)部的五臺(tái)機(jī)器 需要通過實(shí)現(xiàn) Paxos 協(xié)議選取一個(gè) Chubby Master 機(jī)器,其它機(jī)器是 Chubby Slave ,同一時(shí) 刻只有一個(gè) Chubby Master 。 Chubby 相關(guān)的數(shù)據(jù),比如鎖信息,客戶端的 Sessio n 信息都需 要同步到整個(gè)集群,采用半同步的做法,超過一半的機(jī)器成功就可以回復(fù)客戶端。每個(gè) Chubby Master 和 Chubby Slave 都希望成為 Chubby Master , Chubby Master 有一個(gè) Lease 期限, 如果 Chubby Master 正常,它將在 Lease 快到期的時(shí)候延長(zhǎng) Lease 期限,如果 Chubby Master 宕機(jī), Chubby 集群內(nèi)部將觸發(fā)一次 Paxos 選舉過程。 每個(gè) Chubby Slave 都希望自己成為 Chubby Master ,它們類似于 Paxos 協(xié)議中的 Proposer ,每 個(gè) Chubby 集群中的節(jié)點(diǎn)都是 Acceptor ,最后可以確保只有一個(gè)和原有的 Chubby Master 保持完全同步的 Chubby Slave 被 選取為新的 Chubby Master 。 當(dāng)然,無論是 Paxos 選舉還是 Session ,鎖信息同步, Chubby 集 群內(nèi)部機(jī)器故障檢測(cè)都遠(yuǎn)沒有這么簡(jiǎn)單,這里的實(shí)現(xiàn)也是筆者的揣測(cè),如果有同學(xué)感興趣, 可以參考 Berkerly DB 中半同步(包括選舉過程)的實(shí)現(xiàn),這部分代碼是由 Google 內(nèi)部開源 出來的。 3.7 分布式事務(wù) 對(duì)于分布式事務(wù),大多數(shù)情況下我們應(yīng)該想的是如何回避它,兩階段鎖的方法不僅效率 低,而且實(shí)現(xiàn)特別復(fù)雜。 有的時(shí)候,我們需要和業(yè)務(wù)方一起探討如何規(guī)避分布式事務(wù)。 這里 我們會(huì)用到 流行的概念 BASE , 即基本可用,柔性狀態(tài),柔性一致和最終一致等。對(duì)一個(gè) “ 基 本可用 ” 系統(tǒng)來說,我們需要把系統(tǒng)中的所有功能點(diǎn)進(jìn)行優(yōu)先級(jí)的劃分, 比如轉(zhuǎn)賬業(yè)務(wù)和淘 寶的收藏夾業(yè)務(wù)兩者對(duì)一致性的要求 肯定 是不同的。 柔性狀 態(tài)對(duì)用戶來說是一個(gè)完整的系統(tǒng), 它的一致性是不允許有任何損失的,就是說用戶支付了 10 塊錢,那么他的帳戶上必然是只 扣掉了 10 塊錢;但是對(duì)于系統(tǒng)內(nèi) 部的狀態(tài),我們可以采用一種柔性的策略,比如說系統(tǒng)內(nèi) 分布了 ABC 三個(gè)功能模塊,我們?cè)试S它們?cè)谀骋粫r(shí)刻三個(gè)模塊的狀態(tài)可以不一致。我們會(huì) 通過業(yè)務(wù)和技術(shù)的手段,比如說異步機(jī)制或者批處理方式來保證系統(tǒng)通過柔性狀態(tài)一致來獲 得可用性。 目前底層 NOSQL 存儲(chǔ)系統(tǒng)實(shí)現(xiàn)分布式事務(wù)的只有 Google 的系統(tǒng), 它在 Bigtable 之上用 Java 語言開發(fā)了一個(gè)系統(tǒng) Megastore ,實(shí)現(xiàn)了兩階段鎖,并通過 Chubby 來避免兩階段鎖協(xié) 調(diào)者宕機(jī)帶來的問題。 Megastore 實(shí)現(xiàn)目前只有簡(jiǎn)單介紹,還沒有相關(guān)論文。 在這個(gè)問題上, 我們只能說是 Google 的同學(xué)工程能力太強(qiáng)了,我們開發(fā) NOSQL 系統(tǒng)的時(shí)候還是走為上策。 3.8 Copy - on - write 與 湡獨(dú) Copy - on - write 技術(shù)在互聯(lián)網(wǎng)公司使用比較多,這時(shí)因?yàn)榇蠖鄶?shù)應(yīng)用的讀寫比例接近 10 : 1 , Copy - on - write 讀操作不用加鎖,極大地提高了讀的效率,特別是現(xiàn)在服務(wù)器一般都 有 8 個(gè)或者 16 個(gè)核。 Copy - on - write 技術(shù)還帶來了一個(gè)好處,那就是 Snapshot 的時(shí)候不需要 停服務(wù),而 Snapshot 功能對(duì)于分布式文件系統(tǒng)非常重要。 Copy - on - write 技術(shù) 在樹 形結(jié)構(gòu)中比較容易實(shí)現(xiàn),假如我們實(shí)現(xiàn)一個(gè)支持 Copy - on - write 的 B 樹,基本可以用來 作為 大多數(shù)管理結(jié)構(gòu)的內(nèi)部數(shù)據(jù)結(jié)構(gòu),比如 GFS 的 chunk 管理,文件 名管理, Bigtable 中的子表管理。 Copy - on - write 的示意圖如下: 的是建立一張全局的索引表,索引和數(shù)據(jù)相互獨(dú)立,這樣做的優(yōu)點(diǎn)是可以根據(jù)索引直接定位 到主鍵,缺點(diǎn)是 索引維護(hù)成本較高。 對(duì)于給定主鍵或者索引 列值 的查詢, 直接將請(qǐng)求發(fā)送到 相應(yīng)的數(shù)據(jù)節(jié)點(diǎn) ;否則,將請(qǐng)求發(fā)送 到所有的數(shù)據(jù)節(jié)點(diǎn)。與并行數(shù)據(jù)庫(kù)類似,由合并節(jié)點(diǎn)來生成 最終結(jié)果。 數(shù)據(jù)倉(cāng)庫(kù)存儲(chǔ)子系統(tǒng) 處理機(jī)器故障問題, 可以采用 5.4 中的線上最終一致性系統(tǒng)實(shí)現(xiàn)。 大致的架構(gòu)如下: M a s t e r S l a v e S l a v e D a t a S e r v e r G r o u p M a s t e r S l a v e S l a v e D a t a S e r v e r G r o u p M e r g e r M e r g e r M e r g e r M e r g e r 數(shù) 據(jù) 訪 問 中 間 層 R e a d c l i e n t R e a d c l i e n t R e a d c l i e n t C o n f i g M a s t e r U p d a t e r U p d a t e r C o n f i g S l a v e r e p l i c a t i o n H e a r t b e a t & C o n t r o l W r i t e c l i e n t W r i t e c l i e n t H e a r t b e a t & C o n t r o l W r i t e d a t a W r i t e d a t a G e t d a t a l o c a t i o n G e t d a t a l o c a t i o n H e a r t b e a t & C o n t r o l H e a r t b e a t & C o n t r o l 如上圖, 通過 Updater 節(jié)點(diǎn)將數(shù)據(jù)寫入數(shù)據(jù)節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn) 按照 Data Server Group 的形式組 織, 通過 Master/Slave 備份來保證可靠性 ,同一個(gè) Data Server Group 中 Master 出現(xiàn)故障后 由 Slave 接替其繼續(xù)提供服務(wù),保證可用性。 客戶端的查詢操作在 Merger 節(jié)點(diǎn)上執(zhí)行,它 合并相應(yīng) Data Server Group 中的數(shù)據(jù)分片并進(jìn)行 limit, order by, group by 等操作。 當(dāng)出現(xiàn)負(fù) 載不均衡時(shí), Config Master 將指導(dǎo)數(shù)據(jù)分片從負(fù)載高的 Data Server Group 遷移到負(fù)載低的 Data Server Group 。 8 應(yīng)用 本章講述筆者對(duì)于一些典型應(yīng)用的存儲(chǔ)問題的理解,這里必須聲明:任何一個(gè)應(yīng)用涉及的知 識(shí)都遠(yuǎn)超過筆者的能力范疇,后續(xù)的內(nèi)容只是闡述個(gè)人很膚淺的理解,漏洞很多,請(qǐng)諒解。 8.1 電子商務(wù)類 阿里巴巴引領(lǐng)著電子商務(wù)的方向。以淘寶為例, 淘寶面臨的存儲(chǔ)相關(guān)問題包括 賣家商品, 交易信息, 用戶信息,用戶評(píng)價(jià), 用戶收藏,購(gòu)物車 ,圖片 等等,并且 淘寶累積存儲(chǔ)了 不同 業(yè)務(wù)系統(tǒng)收集的 海量 業(yè)務(wù)數(shù)據(jù),比如 訪問點(diǎn)擊、交易過程、商品類目屬性以及呼叫中心客服 內(nèi)容等 。 淘寶大多數(shù)存儲(chǔ)系統(tǒng)的特點(diǎn)是:數(shù)據(jù)量大,記錄條數(shù)特別多, 單點(diǎn)記錄不大, 讀寫比例 高 ,且可能要求事務(wù)。 由于訪問量特別大,以前采用 Oracle + 小型機(jī)的解決方案,對(duì)于不 需要事務(wù)的需求,可以通過 Mysql sharding 的方式實(shí)現(xiàn) 。 我們正在做的 Oceanbase 系統(tǒng) 巧妙 地 利用讀寫比例大且單條記錄一般比較小的特點(diǎn), 將動(dòng)態(tài)更新的數(shù)據(jù)放在 單機(jī) 內(nèi)存中并通過 強(qiáng)同步保證可靠性及可用性,動(dòng)態(tài)數(shù)據(jù)定期與靜態(tài)數(shù)據(jù)合并。 淘寶的小文件 存儲(chǔ)系統(tǒng) TFS 已經(jīng)開源了,目前主要是用來存儲(chǔ)海量圖片文件。 淘寶 TFS 處理百億級(jí)別的圖片存儲(chǔ),數(shù)據(jù)量 PB 級(jí)別, 這個(gè)問題屬于 5.4 中提到的線上最終一致性系 統(tǒng)的范疇, 不過通用系統(tǒng)的解決方案過于復(fù)雜,性價(jià)比不高。于是,淘寶天才的工程師們利 用圖片應(yīng)用的特點(diǎn)設(shè)計(jì)了通用的 小文件存儲(chǔ)系統(tǒng) TFS ( TFS 開源 ) 。 圖片存儲(chǔ)系統(tǒng) 的特點(diǎn)主要有 兩個(gè) : 1, 用戶 一次性準(zhǔn)備好文件所有數(shù)據(jù) 并 提交到文件系統(tǒng),每個(gè)文件打開后一次性寫入所 有數(shù)據(jù)并關(guān)閉; 2, 用戶不關(guān)心文件的名字, 用戶不會(huì)指定某個(gè)文件進(jìn)行寫操作, 可以等到 文件寫成功 后生成文件名并由客戶端保存。 TFS 利用這兩個(gè)特點(diǎn)大大地簡(jiǎn)化了文件系統(tǒng)寫流程和元數(shù)據(jù)管理服務(wù)器的設(shè)計(jì),而這也 正是海量文件系統(tǒng)最為復(fù)雜之處。 淘寶是一個(gè)開放、共享的數(shù)據(jù)公司,還通過數(shù)據(jù)倉(cāng)庫(kù)提供各種數(shù)據(jù)給客戶。 目前使用了 Oracle RAC 集群提供服務(wù),當(dāng)然,也通過 Hadoop + HIVE 進(jìn)行一些線下的預(yù)處理。 淘寶的主搜索其實(shí)是一個(gè)實(shí)時(shí)搜索, 賣家 更新的商品信息需要秒級(jí)別反映到用戶的搜索 結(jié)果中。 淘寶的主搜索是很靈活的,可以根據(jù) 商 品類別,賣家名稱,商品屬性等進(jìn)行搜 索, 因此,主搜索的存儲(chǔ)系統(tǒng)需要建立不同維度的索引信息, 主搜索使用內(nèi)部的 iSearch 產(chǎn)品, 機(jī)器被分成 56 組,每組 14 臺(tái),組內(nèi)機(jī)器存儲(chǔ)相同的數(shù)據(jù)。 商品更新 發(fā)生在 Oracle 商品庫(kù) 中 , 并以異步的方式同步到主搜索 索引 系統(tǒng)。 8.2 搜索類 搜索類公司的核心競(jìng)爭(zhēng)力 ,或者說 互聯(lián)網(wǎng)公司的 核心競(jìng)爭(zhēng)力都 可以認(rèn)為 就是數(shù)據(jù)以及對(duì) 數(shù)據(jù)的處理 能力,比如商業(yè)價(jià)值挖掘,用戶意圖挖掘等。 搜索類最成功的當(dāng)然就是 Google , 它能取得現(xiàn)在的成功很大程度上得益于底層的 GFS/MapReduce/Bigtable 等 帶來的大規(guī)模數(shù) 據(jù)處理能力。 搜索 流程大致包括: 抓取、數(shù)據(jù)分析、建立索引 及 索引服務(wù) 。 通過 spider 將網(wǎng)頁(yè)抓取過 來后存儲(chǔ)到本地的分布式存儲(chǔ)系統(tǒng) ,即網(wǎng)頁(yè)庫(kù)中。 網(wǎng)頁(yè)庫(kù)的業(yè)務(wù)邏輯并不復(fù)雜,無非就是對(duì) 某一個(gè)網(wǎng)頁(yè)或者一批網(wǎng)頁(yè), 如某個(gè)域名下的所有網(wǎng)頁(yè)的查詢 ,刪除一批網(wǎng)頁(yè)或者更新網(wǎng)頁(yè)相 關(guān)的信息,比如權(quán)重等。 但是網(wǎng)頁(yè)庫(kù)的數(shù)據(jù)量太大,假設(shè)需要處理 500 億網(wǎng)頁(yè),每個(gè)網(wǎng)頁(yè)平 均存儲(chǔ)大小為 5 0KB , 那么,網(wǎng)頁(yè)庫(kù)的 大小為 50GB * 50KB = 2.5PB ,這已經(jīng) 遠(yuǎn)遠(yuǎn)超出了關(guān)系 型數(shù)據(jù)庫(kù)的處理能力。 網(wǎng)頁(yè)庫(kù)應(yīng)用為半線上應(yīng)用,采用 GFS 加 Bigtable 的方案最為合適。不 過為了規(guī)避 復(fù)雜性,可以簡(jiǎn)單地將 網(wǎng)頁(yè)庫(kù)通過 Hash 的方法分布到多臺(tái)機(jī)器組成的分布式集 群中, 并通過支持 MapReduce 來進(jìn)行 線下挖掘, Rank 調(diào)研等。 將網(wǎng)頁(yè)庫(kù)的內(nèi)容進(jìn)行 一系列的處理,比如計(jì)算 PageRank ,網(wǎng)頁(yè)去 重,最終將生成倒排 表用于 線上服務(wù)。 搜索命令的處理大致分成兩步:第一步從倒排表中找出匹配的網(wǎng)頁(yè)索引 信息,第二步根據(jù)索引信息從網(wǎng)頁(yè)庫(kù)中獲取網(wǎng)頁(yè)內(nèi)容。 倒排表有一個(gè)特點(diǎn)就 是讀取量 特別大, 要求延遲很小,且 倒排表一般是定時(shí)生成的,也就是說,倒排表中的數(shù)據(jù)基本是靜態(tài)的 。 倒 排表的 問題域和存儲(chǔ)系統(tǒng)有些差別,這是因?yàn)?每個(gè)關(guān)鍵詞對(duì)應(yīng)的網(wǎng)頁(yè)信息非常多, 需要分散 到多臺(tái)機(jī)器以便 后續(xù)的計(jì)算。因此 ,主流的搜索引擎一般將機(jī)器分成多個(gè) group ,每個(gè) group 可能包含幾十臺(tái)機(jī)器,存儲(chǔ)相同的數(shù)據(jù) ,每個(gè)查詢請(qǐng)求都發(fā)送到 所有的 group ,每個(gè) group 中選擇一臺(tái)機(jī)器 進(jìn)行計(jì)算,計(jì)算 完成后合并最終結(jié)果。 8.3 社交類 ? IM 類 IM 類應(yīng)用需要存儲(chǔ)的數(shù)據(jù)有兩類:用戶數(shù)據(jù)及消息數(shù)據(jù)。 用戶數(shù)據(jù) 的存儲(chǔ)比較簡(jiǎn)單 , 假設(shè)每個(gè)用戶的信息為 10K ,有 10 億用戶,用戶數(shù)據(jù)量為 10K * 1 GB = 1 0 TB ,可以使用 5.4 中的線上最終一致性系統(tǒng)方案或者 專用的根據(jù)用戶 id 進(jìn)行數(shù)據(jù)劃分的方案。 消息 分為兩種, 在線消息和離線消息 ,其中,離線消息存儲(chǔ)時(shí)一個(gè)必要的功能,而在線 消息是一個(gè) plus , 它和離線消息在數(shù)據(jù)量上有巨大差距, 可以選擇不在服務(wù)器端存儲(chǔ) 。 個(gè)人 消息和群消息也有一些區(qū)別。 個(gè)人消息處理比較簡(jiǎn)單, 而群的消息處理 和 SNS 中訂閱好友 動(dòng)態(tài) 有些類似。 SNS 中用戶更新動(dòng)態(tài)時(shí) ,系統(tǒng)會(huì)將這個(gè)動(dòng)態(tài)更新 推送給用戶的所有好友,而 在 IM 中,用戶往群里面發(fā)送一條消息,有兩種處理方法:第一種方法是推送給群里面的所 有用戶,第二種方法是直接保存到群中。 采用第一種方法 群 消息的數(shù)據(jù)量會(huì)增大很多倍, 采 用第二種方法減少了群消息的數(shù)據(jù)量,不過幾十上百個(gè)用戶同時(shí)讀取群消息,即使群消息是 順序 存儲(chǔ)的,最后 在磁盤上 也變成了 隨機(jī)跳讀。 另外一種折衷的方案是對(duì)在線用戶采用第一 種方法,離線用戶采用第二種方法,即只將群消息推送給在線用戶, 離線用戶上線后 主動(dòng)拉 取群 離線消息。 ? SN S & 微博客 前面已經(jīng)提到了 SNS & 微博客 的消息推送功能 ,這是 通過將消息推送給所有的好友實(shí)現(xiàn) 的,可以開發(fā)一個(gè) 類似 Active MQ 的 支持發(fā)布 / 訂閱機(jī)制的消息隊(duì)列。 另外,微博客支持實(shí) 時(shí)搜索, 例如新浪微博中搜索關(guān)注人說的話, 這 和郵件系統(tǒng)的搜索類似,只需要對(duì)用戶訂閱 的消息進(jìn)行字符串匹配。 微 薄中的一個(gè)難點(diǎn)問題是某些用戶被關(guān)注程度特別高, 如果采用推 送的方式 將 對(duì)系統(tǒng)產(chǎn)生很大的壓力, 個(gè)人認(rèn)為可以采用推拉結(jié)合的方式。
總結(jié)
以上是生活随笔為你收集整理的分布式系统工程实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。