從需求出發來看關係模型與非關係模型–時代的變革1

上次咱們談到,由於互聯網應用的實際需求與傳統數據庫之間出現了不匹配的狀況。

因而,破壞與重構就成爲了新時代的主音。mysql

對互聯網應用而言,最急需的需求,就是處理大量用戶輸入的海量數據,進行一些邏輯處理後再將結果返回給用戶。所以,對於在線數據處理來講,可水平擴展的容量指標,可無限增加的寫入tps和讀取qps,是互聯網企業的最大,最急需的需求。算法

相比較而言,爲了追求性能和容量的儘量最大化,其餘的指標則被迫的推到了後面。這也很是容易理解,性能不夠,容量不夠,直接面臨的是不能提供服務,做爲互聯網應用,若是不能爲用戶帶來服務,其核心價值就受到了最大的挑戰。所以,互聯網應用的關鍵需求就是,高可用,高可擴展,高性能,其餘則是額外的追求。所以,綜合來看,互聯網在線處理的需求排序列表基本上能夠認爲是:數據的擴展性>請求的響應時間儘量短>down機時間儘量短>成本儘量低>可自動快速恢復>數據的讀取一致性>程序開發者的方便與快速響應需求。sql

但歷史的演進也是漸進式的發展的,必須考慮到前人們的經驗。由於關係模型的流行,關係數據庫也天然而然的是當時人們可以找到的最安全合理的擴展目標,也正由於如此,傳統數據庫的水平切分,是第一個嘗試解決這個問題的方案。mongodb

在這類方案中,用戶通常會被要求使用某一個簡單的切分條件將數據均勻的分散到幾臺甚至幾百臺數據庫中,從而能夠作到不管多少數據,均可以經過水平加機器的方式來作到能力的提高,從而使用數據庫就能夠知足「數據的擴展性」,「請求的響應時間」,「down機時間短」,這幾個指標了,但,有好就有壞,使用這種切分的方案後,原來能夠運行的SQL或事務卻不得不作出必要的限制了,雖然不爽,但與開發成本相比,知足核心需求是第一位的,因此,這個方案是基本符合要求的。數據庫

從上世紀80年代到本世紀,大部分應用使用水平切分的方式知足了業務的實際須要。天然而然的,人們開始要求更多,但願可以更簡單的解決問題。天然的,會有人提出來:關係數據庫咱們用着很好,關係模型表達也很是清楚和明確,你們都熟悉,大家爲何不作箇中間層,從而實現對上層徹底透明,而且與關係數據庫徹底兼容的數據訪問層出來呢?這樣咱們就能夠既不用修改咱們的業務邏輯,又能夠享受到近乎無限的水平擴展能力了不是麼?安全

想法很好,因而就有很是多的人開始往這個方向努力,他們在開始設計之初拿到的需求列表裏也是這麼寫的:能夠實現對應用徹底透明的數據庫訪問,用戶不須要關心下層是什麼數據,只須要按照關係模型寫業務邏輯,其餘東西都應該可以自動作好。網絡

然而開始着手去知足這個需求的時候,就發現了幾個必需要解決的問題。
1.多機事務怎麼作?2.多機join怎麼作才能很是高效?3.分佈式索引怎麼作?架構

嗯,其實這些問題一直困擾人們到如今都沒有獲得解決,爲何呢?由於硬件碰到了天花板。運維

下面咱們來作個簡單分析:
計算機是個分型的系統,從cpu設計開始,直到分佈式存儲,全部的操做處理其實都在作相似的事情。在cpu架構設計裏面,最核心的問題就是,一個數據要被多個處理器訪問,究竟是共享這個數據呢呢?仍是每次訪問都複製一份呢?
也所以纔會有CPU的三種標準處理方式,A方案:全局共享(smp)。B方案:全局不共享。以及C方案:部分共享部分不共享(numa)的折中方案。
在分佈式存儲領域也是同樣的,想要水平的擴展,勢必須要儘量的減小競爭的數據。而若是碰到全部機器都須要讀寫的數據時,只有共享才能作到最好的性能。數據庫sharding明顯的屬於mpp架構,所以碰到須要多機器都須要讀寫的數據時,只能依靠機器與機器之間的通訊來完成數據讀寫的協調性工做。nosql

這種協調,在單機的時候會使用cpu之間的消息隊列,或者數據總線。而在分佈式領域,協調就必須依託網絡來進行了。而網絡就是個硬件天花板。

既然要談到天花板,咱們就須要對網絡來進行一個簡要的分析,這樣才能更容易的理解這天花板在哪裏:做爲一種通訊的媒介,咱們把它抽象爲如下幾個關鍵的指標:延遲,吞吐量,安全性。
爲了比較方便,咱們以cpu到內存的數據傳輸通道做爲對比:
延遲網絡:30ms內存:21ns
吞吐量網絡:100mb/s內存:800ms/s
安全性網絡:有不可達問題內存:無不可達問題

明顯可以看到,延遲增長很是多,吞吐量則有明顯的下降。又由於網絡不夠安全,因此須要更屢次的網絡交互才能作到更高的安全性。在這幾個屬性的中,最麻煩的是延遲,由於延遲與距離相關,當距離變遠的時候,延遲就會沒法控制。咱們在後面還會更深刻的來討論網絡在分佈式領域中形成的影響。

所以,就算是算法十分完善,咱們也沒法下降在分佈式領域內針對同一個數據的延遲。而這直接致使原來可能可以進行的關係代數或事務過程,延遲直接變大一百倍。以致於業務沒法接受!
關係代數模型也有相似的問題,由於查詢共享的數據須要與多臺機器交互,延遲比使用內存增長不少,所以延遲被迫的增長了不少。

因而,咱們就悲劇的發現,想作到與單機數據庫同樣的事務或一致性體驗,在分佈式存儲領域則再也不可以體驗的到了。

由於這件事沒辦法獲得很好的解決,因此這裏的解決方案就發生了分化:

咱們在這裏不會去評價一種思路的好壞,不過一切思路和想法的最終判斷標準是他可以解決多少實際的問題。

一部分人從本身的實際場景出發,發現本身在一部分場景中(好比存儲業務日誌)只是在使用簡單的接口,而基於分佈式環境實現關係代數模型的難度又是這麼的使人沮喪。那麼,天然而然的會產生一種推論,拋棄關係代數模型不就行了?!
因而一個概念產生了:nosql。不要sql,擴展的廣一點就是不要關係代數模型和一致性模型。這一派的核心思路比較激進:既然關係代數模型性能那麼低,乾脆丟棄它而選擇更簡單的層次模型不就解決問題了?由於實現一個層次模型的keyval數據庫實現相對的容易,因而根據nosql這一理念,在很短期內就出現了一大批nosql的產品。這類產品的基本特徵就是,只實現了簡單的keyvalue接口,主要關注於數據的自動運維,以及利用新的存儲引擎實現來達到寫的優化,從而可以下降成本。比較有特點的nosql系統是cassandra,hbase,mongodb等。
我自己以爲這個想法挺不錯的,惋惜有一批nosql的開發者爲了本身的利益,把nosql宣傳成了無所不能的開發神器,徹底無視其致使的開發成本上升的負面做用,這就比較無語了。大部分狀況下,開發效率比自動的數據運維重要的多,在這種狀況下盲目的使用原始的層次模型接口來完成功能,可能會極大的下降生產效率,還望各位讀者當心。

另外的一些人認爲關係代數模型與擴展性無關,但願可以用新的方式來支持分佈式關係代數模型,這種嘗試目前有個統一的稱呼:newsql。他們的主要思路就是隻作適當的權衡,並努力將關係代數模型在分佈式環境下進行重構。

在這個領域內的一些比較有特點的想法是基於內存的數據庫實現,他們假定將來的數據庫應主要依託更大的內存和網絡來進行構建,這樣,數據庫就成功的規避了慢速磁盤設備對系統形成的影響,讓延遲降低到能夠接受的程度。比較具備表明性的是voltdb,mysqlcluster等

在另外的一些嘗試中,人們假定事務衝突的機率很小,而事務的數量則很大,依託這個假定,人們使用傳統意義上的讀寫鎖來實現數據的讀寫一致性,從而可以支持數據庫的查詢。這類實現中最出名的就是google的megastore和spanner

而傳統的數據庫陣營也在逐漸的被互聯網的需求所引導,逐漸的將本身歷史的包袱逐漸丟下,以更輕盈的體態來面對互聯網應用的需求了。

而針對不一樣讀取場景進行優化的實現就更如皓月繁星那樣多了。。

在咱們快速的瀏覽了這麼多針對如今問題的嘗試思路以後,讓咱們針對目前的人們針對在線海量數據庫的需求作一個簡單的總結吧:

從目前來看,原教旨的nosql運動已經遇到了瓶頸,雖然在實際的應用場景中,人們能夠在開始將本身的用戶模型使用通過精心設計的keyval引擎進行實現。不過隨着新業務需求被不斷的提出,用戶會逐漸的發現本身的大部分的開發內容是:將原有的數據,按照另一個key進行組織,而後提供給用戶進行查詢。這個過程則正是關係數據庫主要可以解決的問題。


在知足了基本需求之後,用戶對於方便性的需求會逐漸的變爲矛盾的主要方面,所以,借鑑傳統的關係數據庫的優秀經驗,結合互聯網應用的實際需求進行適當的改進和裁剪,是目前全部存儲領域從業人員共同努力的方向。
但在當前,由於用戶的主要需求沒能獲得所有的知足,針對不一樣的用戶場景,產生了不一樣的選擇,因而在目前來看,一種存儲模式解決全部問題的時代已通過去了,在存儲領域進入了戰國時代。
面對這麼多的存儲產品,一個問題天然而然的就產生了:面對這麼多不一樣的數據庫產品,個人場景適合什麼樣的存儲呢?在後續的文章中,我也將嘗試從關係數據庫出發,結合分佈式場景中的實際需求,給你們闡述在分佈式存儲領域中面臨的新挑戰和應對這些新挑戰的新的嘗試。以期讓你們可以快速的掌握分佈式存儲的核心脈絡,作到知其然而知其因此然,從而可以快速的選擇或實現適合本身的分佈式存儲產品。
相關文章
相關標籤/搜索