亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

關(guān)于大型網(wǎng)站技術(shù)演進的思考(五)--存儲的瓶頸

系統(tǒng) 2328 0

   上文里我遺留了兩個問題,一個問題是數(shù)據(jù)庫做了水平拆分以后,如果我們對主鍵的設(shè)計采取一種均勻分布的策略,那么它對于被水平拆分出的表后續(xù)的查詢操作 將有何種影響,第二個問題就是水平拆分的擴容問題。這兩個問題在深入下去,本系列就越來越技術(shù)化了,可能最終很多朋友讀完后還是沒有找到解決實際問題的啟 迪,而且我覺得這些問題都是像BAT這樣巨型互聯(lián)網(wǎng)公司才會認真思考的,因此本篇我打算換個角度來闡述本文的后續(xù)內(nèi)容。

?

  這里我們 首先要明確一個問題,到底是什么因素促使我們?nèi)プ鰯?shù)據(jù)庫的垂直拆分和水平拆分的呢?答案很簡單就是業(yè)務(wù)發(fā)展的需求,前文里的水平拆分技術(shù)方案基本都是拋棄 千變?nèi)f化的業(yè)務(wù)規(guī)則的限制,盡量將水平拆分的問題歸為一個簡單的技術(shù)實現(xiàn)方案,而純技術(shù)手段時常是看起來很美,但是到了面對現(xiàn)實問題時候,常常會變得那么 蒼白和無力。

?

  水平拆分 的難題里我還有個難題沒有講述,就是水平拆分后對查詢操作的影響,特別是對單表查詢的影響,這點估計也是大伙最為關(guān)心的問題,今天我不在延著水平拆分的技 術(shù)手段演進是闡述上文的遺留問題,而是我要把前面提到的技術(shù)手段和一些典型場景結(jié)合起來探討如何解決網(wǎng)站存儲的瓶頸問題。

?

  前文中我總結(jié)過一個解決存儲瓶頸的脈絡(luò),具體如下:

  單庫數(shù)據(jù)庫--> 數(shù)據(jù)庫讀寫分離--> 緩存技術(shù)--> 搜索技術(shù)--> 數(shù)據(jù)的垂直拆分--> 數(shù)據(jù)的水平拆分

?

  這個脈絡(luò)給一些朋友產(chǎn)生了誤解,就是認為這個過程應(yīng)該是個串行的過程,其實在實際的場景下這個過程往往是并行的,但是里面有一個元素應(yīng)該是串行的或者說思考時候有個先后問題,那就是對數(shù)據(jù)庫層的操作,具體如下:

  單庫數(shù)據(jù)庫--> 數(shù)據(jù)庫讀寫分離--> 數(shù)據(jù)的垂直拆分--> 數(shù)據(jù)的水平拆分

?

  而緩存技 術(shù)和搜索技術(shù)在數(shù)據(jù)庫的任意階段里都可以根據(jù)實際的業(yè)務(wù)需求隨時切入其中幫助數(shù)據(jù)庫減輕不必要的壓力。例如,當網(wǎng)站的后臺數(shù)據(jù)庫還是單庫的時候,數(shù)據(jù)庫漸 漸出現(xiàn)了瓶頸問題,而這個瓶頸又沒有達到需要采取大張旗鼓做讀寫分離方案的程度,那么我這個時候可以考慮引入緩存機制。不過要合理的使用緩存我們首先要明 確緩存本身的特點,這些特點如下所示:

?

  特點一:緩存主要是適用于讀操作,并且緩存的讀操作的效率要遠遠高于從數(shù)據(jù)庫以及硬盤讀取數(shù)據(jù)的效率。

   特點二:緩存的數(shù)據(jù)是存儲在內(nèi)存當中,因此當系統(tǒng)重啟,宕機等等異常場景下,緩存數(shù)據(jù)就會不可逆的丟失,且無法恢復,因此緩存不能作為可靠存儲設(shè)備,這 就導致一個問題,緩存里的數(shù)據(jù)必須首先從數(shù)據(jù)庫里同步到內(nèi)存中,而使用緩存的目的就是為了解決數(shù)據(jù)庫的讀操作效率低下的問題,數(shù)據(jù)庫的數(shù)據(jù)同步到緩存的操 作會因為數(shù)據(jù)庫的效率低下而在性能上大打折扣,所以緩存適合的場景是那些固定不變的數(shù)據(jù)以及業(yè)務(wù)對實時性變化要求不高的數(shù)據(jù)。

?

  根據(jù)緩存的上述兩個特點,我們可以把數(shù)據(jù)庫里和上述描述類似操作的相關(guān)數(shù)據(jù)遷移到緩存里,那樣我們就從數(shù)據(jù)庫上剝離了那些對數(shù)據(jù)庫價值不高的操作,讓數(shù)據(jù)庫專心做有價值的操作,這樣也是減輕數(shù)據(jù)庫壓力的一種手段。

?

  不過這個 手段局限性很強,局限性主要是一臺計算機了用于存儲緩存的內(nèi)存的大小都是遠遠要低于硬盤,并且內(nèi)存的價格要遠貴于硬盤,如果我們將大規(guī)模的數(shù)據(jù)從硬盤往內(nèi) 存遷移,從資源成本和利用率角度考慮性價比還是很低的,因此緩存往往都是用于轉(zhuǎn)存那些不會經(jīng)常變化的數(shù)據(jù)字典,以及經(jīng)常會被讀,而修改較少的數(shù)據(jù),但是這 些數(shù)據(jù)的規(guī)模也是有一定限度的,因此當單庫數(shù)據(jù)庫出現(xiàn)了瓶頸時候馬上就著手進行讀寫分離方案的設(shè)計性價比還是很高的。

?

  前文我講 到我們之所以選擇數(shù)據(jù)庫讀寫分離是主要原因是因為數(shù)據(jù)庫的讀寫比例嚴重失衡所致,但是做了讀寫分離必然有個問題不可避免,寫庫向讀庫同步數(shù)據(jù)一定會存在一 定的時間差,如果我們想減小讀庫和寫庫數(shù)據(jù)的時間差,那么任然會導致讀庫因為寫的粒度過細而發(fā)生部分性能的損失,但是時間差過大,或許又會無法滿足實際的 業(yè)務(wù)需求,因此這個時間差的設(shè)計一定要基于實際的業(yè)務(wù)需求合理的設(shè)計。

?

  同步的時 間差的問題還是個小問題,也比較好解決,但是如何根據(jù)實際的業(yè)務(wù)需求做讀寫分離這其實還是非常有挑戰(zhàn)性的,這里我舉個很常見的例子來說明讀寫分離的難度問 題,我們這里以淘寶為例,淘寶是個C2C的電商網(wǎng)站,它是互聯(lián)網(wǎng)公司提供一個平臺,商家自助接入這個平臺,在這個平臺上賣東西,這個和線下很多大賣場的模 式類似。淘寶是個大平臺,它的交易表里一定是要記下所有商戶的交易數(shù)據(jù),但是針對單個商家他們只會關(guān)心自己的網(wǎng)店的銷售數(shù)據(jù),這就有一個問題了,如果某一 個商家要查詢自己的交易信息,淘寶就要從成千上萬的交易信息里檢索出該商家的交易信息,那么如果我們把所有交易信息放在一個交易表里,肯定有商家會有這樣 的疑問,我的網(wǎng)店每天交易額不大,為什么我查詢交易數(shù)據(jù)的速度和那些大商家一樣慢了?那么我們到底該如何是解決這樣的場景了?

?

  碰到這樣 的情況,當網(wǎng)站的交易規(guī)模變大后就算我們把交易表做了讀寫分離估計也是沒法解決實際的問題,就算我們做的徹底點把交易表垂直拆分出來估計還是解決不了問 題,因為一個業(yè)務(wù)數(shù)據(jù)庫擁有很多張表,但是真正壓力大的表畢竟是少數(shù),這個符合28原則,而數(shù)據(jù)庫大部分的關(guān)鍵問題又都是在那些數(shù)據(jù)壓力大的表里,就算我 們把這些表單獨做讀寫分離甚至做垂直拆分,其實只是把數(shù)據(jù)庫最大的問題遷移出原來數(shù)據(jù)庫,而不是在解決該表的實際問題。

?

  如果我們 要解決交易表的問題我們首先要對交易表做業(yè)務(wù)級的拆分,那么我們要為交易表增加一個業(yè)務(wù)維度:實時交易和歷史交易,一般而言實時交易以當天及當天24小時 為界,歷史交易則是除去當天交易外的所有歷史交易數(shù)據(jù)。實時交易數(shù)據(jù)和歷史交易數(shù)據(jù)有著很大不同,實時交易數(shù)據(jù)讀與寫是比較均衡的,很多時候估計寫的頻率 會遠高于讀的頻率,但是歷史交易表這點上和實時交易就完全不同了,歷史交易表的讀操作頻率會遠大于寫操作頻率,如果我們將交易表做了實時交易和歷史交易的 拆分后,那么讀寫分離方案適合的場景是歷史交易查詢而非實時交易查詢,不過歷史交易表的數(shù)據(jù)是從實時交易表里同步過來的,根據(jù)這兩張表的業(yè)務(wù)特性,我們可 以按如下方案設(shè)計,具體如下:

?

  我們可以 把實時交易表設(shè)計成兩張表,把它們分別叫做a表和b表,a表和b表按天交替進行使用,例如今天我們用a表記錄實時交易,明天我們就用b表記錄實時交易,當 然我們事先可以用個配置表記錄今天到底使用那張表進行實時交易記錄,為什么要如此麻煩的設(shè)計實時交易表了?這么做的目的是為了實時交易數(shù)據(jù)同步到歷史數(shù)據(jù) 時候提供便利,一般我們會在凌晨0點切換實時交易表,過期的實時交易表數(shù)據(jù)會同步到歷史交易表里,這個時候需要數(shù)據(jù)遷移的實時交易表是全表數(shù)據(jù)遷移,效率 是非常低下,假如實時交易表的數(shù)據(jù)量很大的時候,這種導入同步操作會變得十分耗時,所以我們設(shè)計兩張實時交易表進行切換來把數(shù)據(jù)同步的風險降到最低。由此 可見,歷史交易表每天基本都只做一次寫操作,除非同步出了問題,才會重復進行寫操作,但是寫的次數(shù)肯定是很低的,所以歷史交易表的讀寫比例失衡是非常嚴重 的。不過實時交易表的切換也是有技術(shù)和業(yè)務(wù)風險的,為了保證實時交易表的高效性,我們一般在數(shù)據(jù)同步操作成功后會清空實時交易表的數(shù)據(jù),但是我們很難保證 這個同步會不會有問題,因此同步時候我們最好做下備份,此外,兩個表切換的時候肯定會碰到這樣的場景,就是有人在凌晨0點前做了交易,但是這個交易是在零 點后做完,假如實時交易表會記錄交易狀態(tài)的演變過程,那么在切換時候就有可能兩個實時表的數(shù)據(jù)沒有做好接力,因此我們同步到歷史交易表的數(shù)據(jù)一定要保持一 個原則就是已經(jīng)完成交易的數(shù)據(jù),沒有完成的交易數(shù)據(jù)兩張實時交易還要完成一個業(yè)務(wù)上的接力,這就是業(yè)界常說的數(shù)據(jù)庫日切的問題。

?

  歷史交易 表本身就是為讀使用的,所以我們從業(yè)務(wù)角度將交易表拆分成實時交易表和歷史交易表本身就是在為交易表做讀寫分離,居然了設(shè)計了歷史交易表我們就做的干脆 點,把歷史交易表做垂直拆分,將它從原數(shù)據(jù)庫里拆分出來獨立建表,隨著歷史交易的增大,上文里所說的某個商戶想快速檢索出自己的數(shù)據(jù)的難題并沒有得到根本 的改善,為了解決這個難題我們就要分析下難題的根源在那里。這個根源很簡單就是我們把所有商戶的數(shù)據(jù)不加區(qū)別的放進了一張表里,不管是交易量大的商戶還是 交易量小的商戶,想要查詢出自己的數(shù)據(jù)都要進行全表檢索,而關(guān)系數(shù)據(jù)庫單表記錄達到一定數(shù)據(jù)量后全表檢索就會變的異常低效,例如DB2當數(shù)據(jù)量超過了1億 多,mysql單表超過了100萬條后那么全表查詢這些表的記錄都會存在很大的效率問題,那么我們就得對歷史交易表進一步拆分,因為問題根源是單表數(shù)據(jù)量 太大了,那我們就可以對單表的數(shù)據(jù)進行拆分,把單表分成多表,這個場景就和前面說的水平拆分里把原表變成邏輯表,原表的數(shù)據(jù)分散到各個獨立的邏輯表里的方 式一致,不過這里我們沒有一開始做水平拆分,那是會把問題變麻煩,我們只要在一個數(shù)據(jù)庫下對單表進行拆分即可,這樣也能滿足我們的要求,并且避免了水平拆 分下的跨庫寫作的難題。接下來我們又有一個問題了那就是我們按什么維度拆分這張單表呢?

?

  我們按照 前文講到的水平拆分里主鍵設(shè)計方案執(zhí)行嗎?當然不行哦,因為那些方案明顯提升不了商戶檢索數(shù)據(jù)的效率問題,所以我們要首先分析下商戶檢索數(shù)據(jù)的方式,商戶 一般會按這幾個維度檢索數(shù)據(jù),這些維度分別是:商戶號、交易時間、交易類型,當然還有其他的維度,我這里就以這三個維度為例闡述下面的內(nèi)容,商戶查詢數(shù)據(jù) 效率低下的根本原因是全表檢索,其實商戶查詢至少有一個維度那就是商戶號來進行查詢,如果我們把該商戶的數(shù)據(jù)存入到一張單獨的表里,自然查詢的效率會有很 大的提升,但是在實際系統(tǒng)開發(fā)里我們很少通過商戶號進行拆分表,這是為什么呢?因為一個電商平臺的商戶是個動態(tài)的指標,會經(jīng)常發(fā)生變化,其次,商戶號的粒 度很細,如果使用商戶號拆分表的必然會有這樣的后果那就是我們可能要頻繁的建表,隨著商戶的增加表的數(shù)量也會增加,造成數(shù)據(jù)的碎片化,同時不同的商戶交易 量是不一樣的,按商戶建表會造成數(shù)據(jù)存儲的嚴重不平衡。如果使用交易類型來拆分表,雖然維度的粒度比商戶號小,但是會造成數(shù)據(jù)的分散化,也就是說我們查詢 一個商戶的全部交易數(shù)據(jù)會存在很大問題。由此可見拆表時候如何有效的控制維度的粒度以及數(shù)據(jù)的聚集度是拆分的關(guān)鍵所在,因為使用交易時間這個維度就會讓拆 分更加合理,不過時間的維度的設(shè)計也是很有學問的,下面我們看看騰訊分析的維度,如下所示:

? 關(guān)于大型網(wǎng)站技術(shù)演進的思考(五)--存儲的瓶頸(5)

  騰訊分析 的維度是今天這個其實相當于實時交易查詢,除此之外都是對歷史數(shù)據(jù)查詢,它們分為昨天、最近7天和最近30天,我們?nèi)绻獙v史交易表進行拆分也是可以參 照騰訊分析的維度進行,不過不管我們選擇什么維度拆分數(shù)據(jù),那么都是犧牲該維度成全了其他維度,例如我們按騰訊分析的維度拆分數(shù)據(jù),那么我們想靈活使用時 間查詢數(shù)據(jù)將會受到限制。

?

  我們把歷 史交易數(shù)據(jù)通過交易時間維度進行了拆分,雖然得到了效率提升,但是歷史交易數(shù)據(jù)表是個累積表,隨著時間推移,首先是月表,接下來是周表都會因為數(shù)據(jù)累積產(chǎn) 生查詢效率低下的問題,這個時候我們又該如何解決了?這個時候我們需要再引進一個維度,那么這個時候我們可以選擇商戶號這個維度,但是商戶號作為拆分維度 是有一定問題的,因為會造成數(shù)據(jù)分布不均衡,那么我們就得將維度的粒度由小變粗,其實一個電商平臺上往往少數(shù)商戶是完成了大部分電商平臺的交易,因此我們 可以根據(jù)一定指標把重要商戶拆分出來,單獨建表,這樣就可以平衡了數(shù)據(jù)的分布問題。

?

  我們總結(jié)下上面的案例,我們會得到很多的啟迪,我將這些啟迪總結(jié)如下:

  啟迪一:數(shù)據(jù)庫的讀寫分離不是簡單的把主庫數(shù)據(jù)導入到讀庫里就能解決問題,讀數(shù)據(jù)庫和寫數(shù)據(jù)的分離的目的是為了讓讀和寫操作不能相互影響效率。

  啟迪二:解決讀的瓶頸問題的本質(zhì)是減少數(shù)據(jù)的檢索范圍,數(shù)據(jù)檢索的范圍越小,讀的效率也就越高;

   啟迪三:數(shù)據(jù)庫的垂直拆分和水平拆分首先不應(yīng)該從技術(shù)角度進行,而是通過業(yè)務(wù)角度進行,如果數(shù)據(jù)庫進行業(yè)務(wù)角度的水平拆分,那么拆分的維度往往是要根據(jù) 該表的某個字段進行的,這個字段選擇要有一定原則,這個原則主要是該字段的維度的粒度不能過細,該字段的維度范圍不能經(jīng)常的動態(tài)發(fā)生變化,最后就是該維度 不能讓數(shù)據(jù)分布嚴重失衡。

?

  回到現(xiàn)實的開發(fā)里,對于一個數(shù)據(jù)庫做拆表,分表的工作其實是一件很讓人惱火的工作,這主要是有以下原因所造成的,具體如下所述:

?

  原因一:一個數(shù)據(jù)庫其實容納多少張表是有一定限制的,就算沒有超過這個限制,如果原庫本來有30 張表,我們拆分后變成了60 張,接著是120 張,那么數(shù)據(jù)庫本身管理這么多表也會消耗很多性能,因此公司的DBA 往往會控制那些過多分表的行為。

?

  原因二:每次拆表后,都會牽涉到歷史數(shù)據(jù)的遷移問題,這個遷移風險很大,遷移方案如果設(shè)計的不完善可能會導致數(shù)據(jù)丟失或者損壞,如果關(guān)鍵數(shù)據(jù)發(fā)生了丟失和損壞,結(jié)果可能非常致命。因此在設(shè)計數(shù)據(jù)庫分表分庫方案時候我們要盡量讓受影響的數(shù)據(jù)范圍變得最小。

?

  原因三:每次拆表和分表都會讓系統(tǒng)的相關(guān)方繃緊神經(jīng),方案執(zhí)行后,會有很長時間的監(jiān)控和觀察期,所以拆數(shù)據(jù)庫時常是一件令人討厭的事情。

?

  原因四:為了保證新方案執(zhí)行后確保系統(tǒng)沒有問題,我們常常會讓新舊系統(tǒng)并行運行一段時間,這樣可以保證如果新方案出現(xiàn)問題,問題的影響面最低,但是這種做法也有一個惡果就是會導致數(shù)據(jù)遷移方案要進行動態(tài)調(diào)整,從而增加遷移數(shù)據(jù)的風險

?

  因此當公司不得不做這件事情時候,公司都會很自然去考慮第三種解決方案, 第三種解決方案是指盡量不改變原數(shù)據(jù)庫的功能,而是另起爐灶,使用新技術(shù)來解決我們的問題 ,例如前文所說的搜索技術(shù)解決數(shù)據(jù)庫like的低效問題就是其中方案之一,該方案只要我們將數(shù)據(jù)庫的表按一定時間導入到文件系統(tǒng),然后對文件建立倒排索引,讓like查詢效率更好,這樣就不用改變原數(shù)據(jù)庫的功能,又能減輕數(shù)據(jù)庫的壓力。

?

  現(xiàn)在常用 的第三種解決方案就是使用NoSql數(shù)據(jù)庫,NoSql數(shù)據(jù)庫大多都是針對文件進行的,因此我們可以和使用搜索引擎那樣把數(shù)據(jù)導入到文件里就行 了,NoSql基本都采用Key/Value這種簡單的數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)和關(guān)系數(shù)據(jù)庫比起來更加的靈活,對原始數(shù)據(jù)的約束最少,所以在NoSql數(shù) 據(jù)庫里建表我們可以很靈活的把列和行的特性交叉起來用,這句話可能很多人不太理解,下面我舉個例子解釋下,例如hadoop技術(shù)體系里的 hbase,hbase是一個基于列族的數(shù)據(jù)庫,使用hbase時候我們就可以通過列來靈活的拆分數(shù)據(jù),比如我們可以把中國的省份作為一個列,將該省份的 數(shù)據(jù)都放入到這個列下面,在省這個維度下我們可以接著在定義一個列的維度,例如軟件行業(yè),屬于軟件行業(yè)的數(shù)據(jù)放在這個列下面,最終提供用戶查詢時候我們就 可以減少數(shù)據(jù)檢索的范圍,最終達到提升查詢效率的目的。由此可見當我們用慣了關(guān)系數(shù)據(jù)庫后,學習像hbase這樣的Nosql數(shù)據(jù)庫我們會非常的不適應(yīng), 因為關(guān)系數(shù)據(jù)庫的表有固定模式,也就是我們常說的結(jié)構(gòu)化數(shù)據(jù),當表的定義好了后,就算里面沒有數(shù)據(jù),那么這個結(jié)構(gòu)也就固定了,我們使用表的時候都是按這個 模型下面,我們幾乎感覺不到它,但是到了hbase的使用就不同了,hbase使用時候我們都在不停的為數(shù)據(jù)增加結(jié)構(gòu)化模型,而且這個維度是以列為維度 的,而關(guān)系數(shù)據(jù)庫里列確定后我們使用時候是無法改變的,這就是學習hbase的最大困難之一。Hbase之所以這么麻煩的設(shè)計這樣的計算模型,終極目的就 是為了讓海量數(shù)據(jù)按不同維度存儲起來,使用時候盡全力檢索數(shù)據(jù)檢索的數(shù)量,從而達到海量數(shù)據(jù)快速讀取的目的。

?

  好了,今天就寫到這里,祝大家生活愉快。

?

原文: http://www.cnblogs.com/sharpxiajun/p/4265853.html

?

關(guān)于大型網(wǎng)站技術(shù)演進的思考(五)--存儲的瓶頸(5)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一级毛片免费视频观看 | 免费夜色污私人影院网站 | 欧美日韩色黄大片在线视频 | a在线观看免费视频 | 欧美成人片在线 | 日本免费毛片在线高清看 | 国产黄大片在线观 | 国产精品免费看久久久麻豆 | 中文字幕色婷婷在线视频 | 99热com| 欧美成 人激情视频 | 国产美女视频免费 | 国产真实伦视频在线视频 | 色久悠悠在线观看 | 久久久久美女 | 日韩欧美综合 | 免费a视频在线观看 | 日本裤袜xxxx视频 | 国产理论最新国产精品视频 | 五月天婷婷免费视频 | 日本午夜大片a在线观看 | 国产99r视频精品免费观看 | 中文字幕国产 | 俺去也理论网站 | 日日综合 | 草草操| 欧美高清不卡午夜精品免费视频 | 日本一级aaaa特黄毛片 | 国内精品久久久久久不卡影院 | 欧美成人看片 | 国产女人精品性视频 | 久青草免费视频手机在线观看 | 干一干操一操 | s8国产成人精品视频 | 99视频精品全国免费 | 一本一道 | 久久香蕉国产线看观看网站 | 天天做天天爱天天怼 | 天天上天天干 | 久久er99热这里只是精品 | 久久精品国产欧美成人 |