【伯樂線上導讀】:“如何通俗解釋「為什麼資料庫難以拓展」”,這個問題來自 Quora,題主還補充說自己有一些資料庫的基本知識,但依然不理解為什麼擴充套件資料庫如此困難。伯樂線上編譯摘編了這個問答貼的兩個熱門回覆。
Paul King , Facebook 資料科學家(3.6K 贊)
要擴充套件資料庫有四大挑戰:搜尋、併發性、一致性和速度。
假設你有一張清單,上面有10個人名。如果你想要查詢某個人,只需要看一眼清單就行。
但如果清單上有100萬個人名呢?這時,你就需要一些策略了。電話簿把人名按照字母順序排列,這樣你就可以略過不需要的部分了。這就是針對搜尋問題的一種解決方案。
如果有100萬人在同時使用這本電話簿呢?這就是併發性的問題。要麼大家在市政廳排長隊等待使用電話簿,要麼把電話簿影印100萬份——“主從複製”策略。如果你把這100萬份影印件放到每個人的家裡——“分散式”策略——你同樣可以得到快速響應。
如果有人電話號碼更換了呢?主從複製策略造成了一個問題:現在必須對100萬本電話簿作出更改。而且它們還在被使用呢,何時才能進行更改呢?如果一本一本的更改,就可能造成資料一致性問題。如果全部回收並印發新的,就可能造成可用性問題。
如果每小時都有成百上千的人更換他們的電話號碼呢?這時你就面臨由於“資源爭用”引起的嚴重的資訊堵塞,這種堵塞還會導致“競態條件”(不可預知的輸出)和“死鎖”(資料庫的僵局)。
以上所有問題都有解決方案,但這些解決方案可能會非常複雜。比如,可以透過發放電話簿的附錄(稱為“修改日誌”)而不是重新列印它們,不過你得時時刻刻檢查你的附錄。你可以按照修改日期釋出電話簿的新版本,這樣人們可以同一時間交換它們以獲得更高的一致性,不過這樣的話,電話簿就總會稍微有一點過時。
現在,把規模擴充套件到有上百萬的使用者使用,數十億條資料分散式的儲存在世界各地的資料中心中。
資料庫基本標的是維護一種假象,即它只有一份複製,同一時間只有一個人在修改它,所有人看到的都是最新的資料,並且能立即響應。當資料庫擴充套件到全球有上百萬的人使用和修改上以萬億計的資料時,這個標的就無法達到了。
因此資料庫設計的任務是使用環環相扣的演演算法技巧以盡可能的接近這一假象。
黃易山,Reddit 前 CEO,(2k 贊)
這裡有一個專門針對門外漢,例如完全不懂資料庫的非技術人員的解釋。
(對於懂資料庫的人,請自行忽略這句話以及接下來這個類比中的一些小技術錯誤。)
“擴充套件”在很多方面都是很難的,但是首先我想要從根本上講為什麼擴充套件很難——原因是“擴充套件”並不是一個單一方向的活動。總的來說,它的本質是把一個複雜的系統變得“更好”——通常是更大或更多,而且通常很快就不得不這麼做。關鍵在於一個複雜的系統不能透過一個簡單的方法就能變得更大或更多產或更高效——通常系統的各個方面相互影響,所以如果你想要拓展某一部分,那麼其它部分通常會失效,從而你無法得到想要的擴充套件——你幾乎總要做一些重構
打個比方:
把資料庫想象成一個圖書館。你在那裡存放書籍或者叢書(比如全套的哈利波特系列叢書)。特別的,你的web應用也是一個圖書館,它存放圖書,方便的提供人們閱讀。想象一下,這個圖書館出現在了TechCrunch上,變得非常受歡迎,如此一來你就突然面臨了一系列的擴張問題。讓我們列舉幾個問題,用簡單的術語進行解釋:
例一:很多、很多書
你的圖書館越來越受歡迎。因此,你比當初開始建立圖書館的時候多了很多書,很長一段時間裡,你只是把它們放在房間的新書架上。但是目前的房子裡無法放下全部的書了。它們已經超出了你的小圖書館可以承載的規模。你必須購買或者租賃相鄰的建築物,把書放在裡面。這可能會帶來一些問題,因為你附近的建築物是有限的,或者房地產價格非常高以至於無法持續的租賃隔壁那個很貴的房子。因此你必須認真思考租賃哪個房子,如何找到那些距離很近又很合算的用於存放書籍的房子。
這是真實的模擬,資料庫通常儲存在硬碟上,硬碟存放在有限的空間裡,你只能在一臺計算機(一個資料中心,一個機架)中存放許多的硬碟。為了抗衡這個普遍的問題資料中心設計的很大,但是如果你是一個非常大的圖書館,你可能還是會遇到這種限制,資料中心的機架無法承受如此之多的硬碟,甚至你需要廢棄掉這個資料中心並建立一個新的(這種情況很少見)。儘管如此,問題的核心是不管你最開始有多少空間,你總是需要擴充套件它,並且你沒法一直線性的在空間中增加“單元”(好比在圖書室裡增加書架),你終會需要做出跨越性的改變,例如租賃隔壁的房子或者租賃又一個機架或者建立又一個資料中心。
例二:在書的海洋裡找書
當你的圖書館只佔用一個房間的時候,你只需要把所有的書按照字母順序排列放好就行。如果有人想要某本書,他只需要在房間裡順序查詢到他想要的那本就好。這大約需要花費30分鐘。
現在你的圖書館很大,你租賃了很多房子。如果有人想要看某本書的話,他可能需要走遍所有的房子。人們根本不能接受找一本書需要花費這麼多的時間(和人們承受網頁的載入時間類似)。人們只想要直接走到正確的房子裡,走到正確的樓層,走到正確的那個書架,直接拿到那本想要的書。他們根本不願意花費超過半小時的時間。
為了實現這一標的,你得建立一個新的關聯絡統,叫做索引。現實中的圖書館確實遇到了這個問題,他們使用的解決方案是卡片目錄。如下圖所示:
年輕一代可能不知道這是什麼,因為這是計算機時代之前的產物。卡片目錄簡直就是個使用小抽屜和小紙片(卡片)的資料庫。因為它們太過笨重,所以我們把它們數字化並放進了計算機中。如果你小於25歲的話,你可能根本沒見過它們。
卡片目錄(即索引)為每本書建造了一個卡片,把卡片放進抽屜,按照標題、作者、主題等排序。如果你想要查詢某本書,就直接使用卡片目錄——放在單獨的一個房間裡——查詢你要的書的卡片,卡片中會有這本書的具體所在位置。所以你只需花費10分鐘來檢索卡片,10分鐘走到正確的房子,5分鐘走到確切的樓層和書架前,再花5分鐘找到確切的書。
如果一個圖書館變得太大了,它就需要引進卡片目錄,使得查詢一本書需要的時間保持在合理的範圍內(例如半小時),否則就需要花好幾天來搜尋遍所有房子以找到一本書,這樣人們就不會使用這個圖書館了。這和僅僅只是租賃更多的房子並全部搜尋有本質上的不同——這個例子說明當你在擴充套件中遇到門檻時,必須要想出一個新的解決方案以剋服問題——不僅僅是增加書架,你還必須整理書目,打印出所有的卡片(這很困難,因為你必須遍歷所有的書,把他們按照作者、標題和主題等排序,這很痛苦,因為你的書堆滿了好幾個房子),然後你得在圖書館靠門口的位置空出一個特殊的房間用於存放你的卡片目錄,告訴每個人先檢查卡片。
例三:很多人同時查詢同一本書
讓我們舉一個超級簡單的例子來說明這個問題:你的圖書館現在很受歡迎,每天有成千上萬的人同時光臨。人山人海,摩肩接踵。這可不是聽起來那麼荒謬——這是當一個web應用突然火起來時遇到的最普遍的問題。
現在有好多人想要看同一本書以至於他們卡住了大門。這聽起來很荒謬,因為現實中這很少發生。但是想想這個——現實中的大門可以允許一秒鐘透過一個人。因此如果每秒鐘有20個人想要進入你的圖書館, 那麼很快門口會排起長隊。越來越多的人到來,隊伍越來越長。最終,門口排隊的人數會超過在圖書館中的人數,大量等待的人群口口相傳他們只能一直在門口等待而永遠也無法讀到一本書。看不到書而恨你的人比看到書而得到滿足的人多的多,壞口碑就產生了。
一個顯而易見的解決方案是在牆上開更多的門。你現在又開了一道門,兩倍的人湧入了!你開了更多的門,最終有上百個門,每面牆都擠滿了門。嘿,你只需移除所有的牆!這樣,更多的人可以使用圖書館了!數量級的激增!
但很快你就會遇到另一個問題,每本書所在的書架前只有有限的空間,只能給有限的人站立,也許他們速度可以很快——他們瀏覽書架找到想要的書然後就離開。但是他們依然需要在書架前站立幾秒鐘,但最終因為你的圖書館太受歡迎,成百上千的人都在查詢同一本書(或者被查詢的兩本書放在同一個垂直空間),他們沒法都擠在書架前的一小塊空地裡。
再一次,書架前排起了長隊——也許是所有的書架,也許只是某一個放著暢銷書的書架。以下是一些可能的解決方案:
如果人群只是聚集在暢銷書架附近,那你只需要把暢銷書分散放在圖書館即可。但這樣,書本就不再是按序擺放的了,它們變得隨機分佈,所以你就需要重構你的卡片目錄以使得人們可以快速找到它們。這不是那麼痛苦——因為你僅僅只需要更新所有的暢銷書的卡片而已。
如果到處都人擠人,例如,所有的書都很受歡迎,或者僅僅是人太多,你可以嘗試增加副本。也就是說,複製你的整個圖書館然後在城市的另一邊(或者下一個街區)租賃一些新的房子,把一般的人遷移到新圖書館去。你可以這樣重覆做幾次,增加一些副本。這樣做的話需要確保備份都是最新的,你必須確保所有的新書在多個圖書館都有最新的備份。有一個解決方案是把其中一個圖書館稱為“主”圖書館,所有的新書都只進入這一個圖書館,每次有新書進入時,你得派人影印這些書併排一個快遞員把這些備份送到其它圖書館中。這些快遞員也需要佔用交通資源,這又限制了可以使用你的圖書館的人數,因此你需要限制每個圖書館的接待人數,當人數過多的時候,你就要再新建一個圖書館了。
總結如下,最開始的時候你想要擴充套件你的圖書館以應對大量的人群,你僅僅只是增加新的門,透過人數瞬間翻倍。你可以再開一扇門再次增加透過人數。在一段時間裡,你都可以透過增加新的門來擴充套件,直到你在所有的牆上都開滿了門——即你移除了所有的牆。在此之後你還想繼續擴充套件(記住,來你圖書館的人永不停息的在增長),你就得想一個全新的解決方案了,比如建立幾個備份圖書館。這樣做造成很多影響——你得影印你所有的書,租賃新的房子,然後還得想出一個合理分流的方案使得每個圖書館的人數都很合理。所有的這些都是新的基礎設施,你沒法等到你意識到需要開闢足夠多的門的時候再做這些,因為建設它們的時候訪問人數依然在不斷增加,等待的人群會很不滿意。所以你得根據訪問量的增長速率來預測當你開闢新門策略可能無效的時候就早早開始增加圖書館的數量。
例四:增加很多、很多新書
所有的圖書館都得與時俱進,也就意味著得不停的增加新書。讓我們假設你有一個很活躍的圖書館,每時每刻都有成百上千的新書增加進來。
如此一來,你得安排人購買新書,在主圖書館影印它們,把這些書分散放到書架上。你有一個超級通暢的交通和足夠數量的圖書館們,即使快遞員們在各個圖書館之間遊走送達新書,也不會影響你的圖書館的訪問速度。太棒了,一切看起來都很贊,你決定今天終於可以休個假了。
好的,你圖書館中所有的書都是排好序的,也就是說他們不是隨機的放在書架上,而是按照作者或者標題或者別的什麼排序擺放(在現實中,是按照杜威十進分類法,當你在小學第一次接觸到它的時候肯定覺得很荒謬,但一旦你明白了這些資料庫問題之後,很奇怪的,你就能明白它其實是很有意義的)無論如何,書本按序排放,當有人透過卡片目錄找到某本書在某個書架上的時候,他不需要瀏覽整個書架來找到那本書——書架上的每本書都是按序排放的,所以可以查閱書架中間的書,選取他的左側或者右側繼續查閱,以此遞迴找到特定的書。無論何時,所有的書都得排好序讓使用者可以照此方法找書。
書架上的書按需排列,書架也走擺的滿滿的。也就意味著當快遞員想要把新書放進書架的時候,需要把排在末尾的書移到下一個書架上,下一個書架上的末尾的書移到又一個書架上,以此往複。最終,你得重新設計書架,使其有一些空隙可以放書,而不再需要把書移到另一個書架,這個過程是很惱人的,也很花費時間,更重要的是,當你重新設計書架排放的時候,你不希望有其他的使用者或者快遞員從這些書架上拿書或者放書。所以你得“鎖住”這些書架以及周圍的所有書架,以防止你需要把書挪到別的書架上去,別的書架上的書又得挪到又一個別的書架上去等等。
這種鎖定造成了巨大的交通問題。問題從找書的時候需要等待其他站立在書架前的人離開變成了大量的人群需要等待在書架區的外圍,等待快遞員插入新書以及移動書籍的位置。如果快遞員很多,那這個問題就會經常發生。大量的人群需要等待某一個快遞員完成操作,更糟的是,一個快遞員可能需要等待另一個快遞員。在現實中,新書並不常常增加,但如果你執行一個網站有很多人同時上傳很多東西,這就等同於每時每刻都有有很多快遞員給圖書館快遞新書,你就會遇到上述的問題。
同時,如果快遞員動作不夠快,例如沒法把所有的備份同時送到所有的圖書館,那麼有些人不能找到某本書但是其他人可以,他們就會得到相互矛盾的資訊。
該問題的解決方案就給讀者留作練習吧。
要記住,解決該問題就得幫快遞員們想出一個全新的解決方案(也許可以將臨近的書放在同一批次一起更新,這樣一次就可以在一個書架上更新很多書了),或者改變圖書館的佈局方式(也許你可以為所有的書周圍都留下空位;但如果這些空位又被填滿了呢?)——總而言之,我們可以得到如下的教訓:如果你的快遞員數量不多,你每天新增的書本數量也不多,那這就不是什麼大問題,但如果你超過一個閥值(比如多如潮水的快遞員和新書)你就得改變你現在的整個解決方案和物理佈局,而這往往需要想象力和創造力。
這就是為什麼資料庫難以擴充套件的原因。
事實上,這也是為什麼擴充套件任何一個稍許複雜的系統(比如web應用,它包含了資料庫和其他伺服器及其互動)很難的原因。參考一所完整的研究性大學吧,它包含了實驗室、教室和宿舍等等,圖書館及其用途只是整個大學的組成之一。這些組成部分的任何一個的使用量的快速增長都會引發擴充套件問題。為了剋服這種問題,你通常都得重構整個動態底層協議和重排操作協議(即你程式碼裡的演演算法)或者你的資源佈局。實現這些總是需要創造性的努力並且不同系統的底層細節各不相同,因此,只有一些通用的解決方案——上文提到了其中一些——你常常得調整這些通用解決方案以適應你的情況:也許你很難租到房子用來當做複製圖書館;也許你的書都是大百科全書,快遞員沒法一次快遞很多本書;也許你那兒環境太冷,你沒法開很多扇門,否則顧客就凍死了。適用於這個環境的解決方案沒法完全適用於那個環境,所以你每次都不得不調整解決方案以適應眼前的環境,敏銳的觀察力是幫助你發現問題並找到最適宜該問題的解決方案的必備品。
最後要記住,當你重新設計解決方案的時候,會有越來越多的顧客敲你的門,沖你叫嚷,因為隊伍太長他們沒法看到想看的書了!
哦,對了。你的圖書館可能會讓你的錢包邊的空空,讓你的心流血,因為你要購買足夠多的書架,租賃足夠多的房子,那你怎麼樣才能開始賺錢呢?所有的風險投資者都不想資助你,因為你居然想讓顧客免費借書?你居然不願意插頁內廣告?
謝謝欣賞!^_^
本文由 伯樂線上 – 顧星竹 翻譯,sunbiaobiao 校稿。
英文出處:Quora
譯文連結:http://blog.jobbole.com/83838/