這個問題其實很複雜,說起來也枯燥無味,下面通一個簡單的例子描述一下,可能有不對的地方,請選擇性地閱讀。
如果伺服器上有一顆 1000G 的硬碟可以全部為使用者提供資料儲存,如果每個使用者分配 1G 的最大儲存空間,那麼能非配給多少個使用者使用呢?
你一定說是 1000/1=1000 個使用者。但事實上你這麼分配了,你會發現每個使用者平時根本不會上傳 1G 的東西將容量佔的漫漫的,有多又少,但平均使用者平時只上傳 50M 的檔案,也就是說,你 1000G 的硬碟分給 1000個 人使用,但只有效利用了其中的 50M*1000=50G 的空間,剩 950G 的空間基本都完全浪費了。
那麼怎麼解決呢?
咱可以變通一下,將這 1000G 的空間分配給 20000個 使用者使用,每個人的上傳上限容量還是 1G,但每人平時還是平均上 50M 的資料,那麼 20000*50M=1000G,這下子就把寶貴的伺服器上的儲存空間充分利用了。但你又怕這樣分配給 20000個 人後,萬一某一刻人們突然多上傳點資料,那麼使用者不是就覺察出來你分給人家的 1G 空間是假的了嗎?所以可以不分配那麼多人,只分配給 19000 人,剩下一些空間做應急之用。突然發現一下子將可分配的使用者數量翻了19倍啊,了不起。
那還有沒有辦法更加有效的利用一下呢?
如果我有 1000個 以上的伺服器,一個伺服器上有 1000G 空間,那麼我們個伺服器上都要留下 50G 的空白空間以備使用者突然上傳大資料時導致資料塞滿的情況,那麼我這 1000個伺服器上就空出了 1000臺*50G=50000G 的空間被浪費了,非常可惜。
基於以上原因,人們發明了計儲存叢集,使得一個使用者的資料可以被分配在多個伺服器上儲存,但在使用者那看起來只是一個 1G 的連續空間,那麼就沒必要在每個伺服器上預留出應急的空間了,甚至可以充分的將前一個伺服器塞滿後,在將資料往下一個伺服器中塞。這樣保證了伺服器空間的最大利用,如果某一刻管理員發現使用者都在瘋狂上傳資料(在一個大規模使用者群下,這樣的機率少之又少)導致我現有提供的空間不夠了,沒關係,只需要隨手加幾塊硬碟或者伺服器就解決了。
好吧,這下子我們的伺服器空間利用高多了,可以將一定量的空間分配給最多的使用者使用了。
但有沒有更好的改進方案呢?
管理員有一天發現,即使每個使用者平局下來只儲存 50M 的東西,但這 50M 也不是一蹴而就的,是隨著1-2年的使用慢慢的達到這個數量的,也就是說,一個新的使用者剛剛註冊我的網路空間時,不會上傳東西,或者只上傳一點非常小的東西。那麼我為每一個使用者都初始分配了 50M 的空間,即使將來2年後他們會填滿這 50M ,但這期間的這空間就有很多時浪費的啊。所以聰明的工程師說:既然我們可以分散式、叢集式儲存,一個使用者的資料可以分佈在多個伺服器上,那麼我們就假設一開始就給一個新註冊的使用者提供 0M 的空間,將來他用多少,我就給他提供多少儲存空間,這樣就徹底的保證硬碟的利用了。但使用者的前端還是要顯示 1G 的。
工程師的這個點子,使得我在建立網盤初期能用 1臺 1000G 的伺服器提供了大約 1000000 人來註冊和使用,隨著註冊的人多了,也有錢了,也可以不斷增加伺服器以提供他們後期的存貯了。同時因為一部分伺服器完了一年多購買,我的購買成本也下來了。
之後…。
聰明的工程師發現:網盤裡大家的內容的附件絕大多數都是自創的和不同的。但網盤上大家上傳的東西很多都是重複的。
比如:張三 今天下載了一部《西遊記》上傳上傳到了自己的網盤上,李四在三天後也下載了一模一樣的《西遊記》上傳到了網路硬碟上,隨著使用者的增多,你會發現總計有 1000個人 上傳了 1000份 一模一樣的檔案到你寶貴的伺服器空間上,所以工程師想出一個辦法,既然是一樣的檔案,我就只存一份不久好啦,然後在使用者的前端顯示是沒人都有一份不就行啦。當某些使用者要刪除這個檔案的時候,我並不真的刪除,只需要在前端顯示似乎刪除了,但後端一直保留著以供其他擁有此檔案的使用者下載。直到所有使用此檔案的使用者都刪除了這個檔案我再真的將其刪除吧。
這樣子隨著儲存的資料越來越多,註冊的使用者越來越多,其上傳的重複資料越來越多。你發現這樣的檢測重複檔案儲存的效率越來越大。這樣算下來似乎每個人上傳的不重複的檔案只能平均 1M/使用者。這下子你可以提供超過 50倍 的使用者使用您這有限的空間了。
但伴隨這使用,你又發現一個規律:張三上傳的《西遊記》和李四上傳的《東遊記》是同一個檔案,只不過檔名不一樣,難道我就不能識別出他們是一個檔案,然後只將其分別給不同的使用者儲存成不同的檔名不久行啦?確實可行,但這要利用一些識別檔案相同性的演算法,例如 MD5 值等。只要兩個檔案的 MD5 值一樣,檔案大小一樣,我就認為它們是相同的檔案,只需要儲存一份檔案並給不同的使用者記作不同的檔名就好了。
有一天你發現,因為每一個檔案都需要計算 MD5 值,導致 CPU 負荷很大,而且本來一樣的檔案非要浪費頻寬上傳回來才可以檢測一致性,能改進一下嗎?
聰明的工程師寫了個小軟體/.小外掛,美其名曰“上傳控制元件”,將計算 MD5 的工作利用這個軟體交給了上傳使用者的點老來完成,一旦計算出使用者要上傳的資料和伺服器上已經儲存的某個資料是一樣的,就乾脆不用上傳了,直接在使用者那裡標記上這個檔案已經按照 XX 檔名上傳成功了。這個過程幾乎是瞬間搞定了,並給其起了個高富帥的名字“秒傳”!
網盤提供商還做一些冗餘備份,一般有幾種方式。第一級,提供地域的冗餘,一些重要的服務,在華北,華東,華南,三個地域分別部署儲存服務。然後,即使在同樣一個地域,我們同樣也是會部署多個機房,有一些比較大一些機房提供這些資料跨區域的冗餘。
針對同樣一個區域,依然會提供很多的一些服務,就是機房裡面提供跨節點,透過一些機制保障資料可靠性。這個裡面需要做儲存系統的時候,還有很多控制節點,這個也是需要做到一些高可用,比如說,有一個數據,這個資料就是三個副本,放三個不同的交換機,還有不同的機器,不同的磁盤裡面去,一個機器一個磁碟壞的時候不影響整個資料的可靠性。對於控制節點的冗餘,實際上就是透過構建一個這種複製狀態機,提供多個副本,解決資料一致性。
資料的儲存是費錢的活,但工程師總是想盡辦法節省每兆位元組的儲存成本。
這個問題其實很複雜,說起來也枯燥無味,下面通一個簡單的例子描述一下,可能有不對的地方,請選擇性地閱讀。
如果伺服器上有一顆 1000G 的硬碟可以全部為使用者提供資料儲存,如果每個使用者分配 1G 的最大儲存空間,那麼能非配給多少個使用者使用呢?
你一定說是 1000/1=1000 個使用者。但事實上你這麼分配了,你會發現每個使用者平時根本不會上傳 1G 的東西將容量佔的漫漫的,有多又少,但平均使用者平時只上傳 50M 的檔案,也就是說,你 1000G 的硬碟分給 1000個 人使用,但只有效利用了其中的 50M*1000=50G 的空間,剩 950G 的空間基本都完全浪費了。
那麼怎麼解決呢?
咱可以變通一下,將這 1000G 的空間分配給 20000個 使用者使用,每個人的上傳上限容量還是 1G,但每人平時還是平均上 50M 的資料,那麼 20000*50M=1000G,這下子就把寶貴的伺服器上的儲存空間充分利用了。但你又怕這樣分配給 20000個 人後,萬一某一刻人們突然多上傳點資料,那麼使用者不是就覺察出來你分給人家的 1G 空間是假的了嗎?所以可以不分配那麼多人,只分配給 19000 人,剩下一些空間做應急之用。突然發現一下子將可分配的使用者數量翻了19倍啊,了不起。
那還有沒有辦法更加有效的利用一下呢?
如果我有 1000個 以上的伺服器,一個伺服器上有 1000G 空間,那麼我們個伺服器上都要留下 50G 的空白空間以備使用者突然上傳大資料時導致資料塞滿的情況,那麼我這 1000個伺服器上就空出了 1000臺*50G=50000G 的空間被浪費了,非常可惜。
基於以上原因,人們發明了計儲存叢集,使得一個使用者的資料可以被分配在多個伺服器上儲存,但在使用者那看起來只是一個 1G 的連續空間,那麼就沒必要在每個伺服器上預留出應急的空間了,甚至可以充分的將前一個伺服器塞滿後,在將資料往下一個伺服器中塞。這樣保證了伺服器空間的最大利用,如果某一刻管理員發現使用者都在瘋狂上傳資料(在一個大規模使用者群下,這樣的機率少之又少)導致我現有提供的空間不夠了,沒關係,只需要隨手加幾塊硬碟或者伺服器就解決了。
好吧,這下子我們的伺服器空間利用高多了,可以將一定量的空間分配給最多的使用者使用了。
但有沒有更好的改進方案呢?
管理員有一天發現,即使每個使用者平局下來只儲存 50M 的東西,但這 50M 也不是一蹴而就的,是隨著1-2年的使用慢慢的達到這個數量的,也就是說,一個新的使用者剛剛註冊我的網路空間時,不會上傳東西,或者只上傳一點非常小的東西。那麼我為每一個使用者都初始分配了 50M 的空間,即使將來2年後他們會填滿這 50M ,但這期間的這空間就有很多時浪費的啊。所以聰明的工程師說:既然我們可以分散式、叢集式儲存,一個使用者的資料可以分佈在多個伺服器上,那麼我們就假設一開始就給一個新註冊的使用者提供 0M 的空間,將來他用多少,我就給他提供多少儲存空間,這樣就徹底的保證硬碟的利用了。但使用者的前端還是要顯示 1G 的。
工程師的這個點子,使得我在建立網盤初期能用 1臺 1000G 的伺服器提供了大約 1000000 人來註冊和使用,隨著註冊的人多了,也有錢了,也可以不斷增加伺服器以提供他們後期的存貯了。同時因為一部分伺服器完了一年多購買,我的購買成本也下來了。
之後…。
聰明的工程師發現:網盤裡大家的內容的附件絕大多數都是自創的和不同的。但網盤上大家上傳的東西很多都是重複的。
比如:張三 今天下載了一部《西遊記》上傳上傳到了自己的網盤上,李四在三天後也下載了一模一樣的《西遊記》上傳到了網路硬碟上,隨著使用者的增多,你會發現總計有 1000個人 上傳了 1000份 一模一樣的檔案到你寶貴的伺服器空間上,所以工程師想出一個辦法,既然是一樣的檔案,我就只存一份不久好啦,然後在使用者的前端顯示是沒人都有一份不就行啦。當某些使用者要刪除這個檔案的時候,我並不真的刪除,只需要在前端顯示似乎刪除了,但後端一直保留著以供其他擁有此檔案的使用者下載。直到所有使用此檔案的使用者都刪除了這個檔案我再真的將其刪除吧。
這樣子隨著儲存的資料越來越多,註冊的使用者越來越多,其上傳的重複資料越來越多。你發現這樣的檢測重複檔案儲存的效率越來越大。這樣算下來似乎每個人上傳的不重複的檔案只能平均 1M/使用者。這下子你可以提供超過 50倍 的使用者使用您這有限的空間了。
但伴隨這使用,你又發現一個規律:張三上傳的《西遊記》和李四上傳的《東遊記》是同一個檔案,只不過檔名不一樣,難道我就不能識別出他們是一個檔案,然後只將其分別給不同的使用者儲存成不同的檔名不久行啦?確實可行,但這要利用一些識別檔案相同性的演算法,例如 MD5 值等。只要兩個檔案的 MD5 值一樣,檔案大小一樣,我就認為它們是相同的檔案,只需要儲存一份檔案並給不同的使用者記作不同的檔名就好了。
有一天你發現,因為每一個檔案都需要計算 MD5 值,導致 CPU 負荷很大,而且本來一樣的檔案非要浪費頻寬上傳回來才可以檢測一致性,能改進一下嗎?
聰明的工程師寫了個小軟體/.小外掛,美其名曰“上傳控制元件”,將計算 MD5 的工作利用這個軟體交給了上傳使用者的點老來完成,一旦計算出使用者要上傳的資料和伺服器上已經儲存的某個資料是一樣的,就乾脆不用上傳了,直接在使用者那裡標記上這個檔案已經按照 XX 檔名上傳成功了。這個過程幾乎是瞬間搞定了,並給其起了個高富帥的名字“秒傳”!
網盤提供商還做一些冗餘備份,一般有幾種方式。第一級,提供地域的冗餘,一些重要的服務,在華北,華東,華南,三個地域分別部署儲存服務。然後,即使在同樣一個地域,我們同樣也是會部署多個機房,有一些比較大一些機房提供這些資料跨區域的冗餘。
針對同樣一個區域,依然會提供很多的一些服務,就是機房裡面提供跨節點,透過一些機制保障資料可靠性。這個裡面需要做儲存系統的時候,還有很多控制節點,這個也是需要做到一些高可用,比如說,有一個數據,這個資料就是三個副本,放三個不同的交換機,還有不同的機器,不同的磁盤裡面去,一個機器一個磁碟壞的時候不影響整個資料的可靠性。對於控制節點的冗餘,實際上就是透過構建一個這種複製狀態機,提供多個副本,解決資料一致性。
資料的儲存是費錢的活,但工程師總是想盡辦法節省每兆位元組的儲存成本。