Thinking in BigDate(七)大資料技術核心之NoSql(一)

來源:互聯網
上載者:User

       曾在Thinking in BigDate(三)大資料運作機理與趨勢,一文中談到結構化資料面臨的挑戰,隨著持續增長的海量資料,NoSql應運而生。本文,我們將續續揭開NoSql的神秘面紗,開啟非結構化資料的大門(不再過多的探討關係型資料庫的特點)。

原文章總結於《NoSql Distilled》作者:Pramod J.Sadalage ,Martin Fowler著,愛飛翔  譯《NoSql 精粹》

學而不思等於白學,重點在于思!

大資料技術核心之NoSql(一):提綱:

資料擷取:ETL

資料存放區:關係型資料庫、NoSql(Not Only SQL)、SQL等

資料管理:(基礎架構支援)雲端儲存、Distributed File System

資料分析與挖掘:(計算結果展現)資料的可視化

起源:

      也許在企業界中早已習慣傳統的關係型資料庫,但隨著待處理的資料逐漸增多,叢集資料的不斷增多。傳統資料庫已經不能滿足更加迥異的資料格式了。於是大家開始不斷探索,期待著一種在叢集環境中易於編程且執行效率高的大資料處理技術,在此情況下,NoSql應運而生。

       為什麼,傳統關係型資料庫開始遇到瓶頸,哪些瓶頸?為什麼資料增多,會伴隨著非結構性資料的的增多?什麼是非結構性資料?NoSql是什嗎?支援NoSql資料的資料庫有哪些?NoSql資料庫與關係型資料庫的區別?NoSql挑戰是什嗎?為何它會引起關注?什麼樣的人更應該關注NoSql?等等。

       可能這就是一個新事物的誕生必將引起,好事者的一致追捧,提出各種你能想象的問題,想盡一切辦法推促它前進。也可能在這個圈子中,總會有一批不知疲倦的人們在不斷的探索,不斷的尋求改變世界的方案,這也是這批人的引起為豪的樂趣。

       NoSql發展如此迅速的原因:由於需要處理的資料越來越多,所以大型系統的擴充方式,由原來在單一電腦上的縱向擴充(scale up),轉變為在電腦叢集上的橫向擴充(scale out)。這也應徵了許多NoSql資料庫的資料模型所具備的一個重要特徵,那就是:可以把內容密切相關的資料群組織成一種豐富的結構,並將其顯示儲存起來,以便作為一個單元(unit)來訪問。這種結構,我們暫且稱之為彙總(aggregate)。

關係與非關係型資料庫對比:關係型資料庫

特徵:

1、  持久化資料:能夠持久化儲存大量資料。這就存在“主儲存空間=記憶體”,“備份存放區器=硬碟”。而硬碟就可以做持久化資料使用。

2、  並發:並非操作擷取資料庫中的資料極為困難。而通過“事務”(加“事務錯誤”)處理機制可以保證資料不受破壞,解決並發問題。

3、  整合:共用Data Integration,將多個應用程式的資料儲存在同一個資料庫中。有利於團隊合作開發。同時可以應對多個應用程式的並發機制。

4、  標準模型:這體現在資料庫的標準化,有益於開發人員和資料庫專家可以學習基本的關聯式模式,就可以運用到不同的項目中。雖不同的資料庫之間存在差異,但核心機制是相同的,SQL、“事務”操作方式也幾乎一樣。

弊端:

1、  阻抗失諧:令開發人員失望的是關係型資料庫中的關聯式模式記憶體中的資料結構之間存在差異,這種差異通常稱為“阻抗失諧”。關聯式模式把資料群組織成“表”(table)和“行”(row),(你可以理解成“表”、“行”太規範了),更準確的說,更應該是“關係”(relation)和“元組”(tuole)。而在關聯式模式中,元組是由“鍵值對”(key-value pair)構成的集合,而關係則是元組的集合。(如果大家稍微瞭解NoSql(暫且把NoSql定義為非關係型資料庫)是基於key-value,上面的話就不難理解了)

2、  叢集:不能在叢集中運行隨著互連網公司規模急劇增加。如何解決儲存問題?這就引入縱向和橫向擴充的問題。縱向:需要更強大的電腦。橫向:就是採用多個小型電腦群組成的叢集。毋庸置疑的選擇,減低成本又能提高效能。這就遇到問題了:關係型資料庫並不是設計叢集用的,它們需要一種可以支援叢集的檔案系統,該檔案系統將資料寫入隨時可用的磁碟子系統中

       關係型資料庫也可以把資料劃分為幾個集合,並將其分配放在各自獨立的伺服器上運行,於是就能有效地對資料庫分區。這麼做雖然能將負載分到多個伺服器之中,但是應用程式必須控制所有分區,它要知道資料庫中的每份資料放在哪個伺服器上才行。而且必須要考慮資料完整性等性質。如此一說,只能說這是“非常之法”,迫不得已之法了。

非關係型資料庫(NoSql):

特徵:

1、  NoSql資料庫不使用或不怎麼使用SQL。不能說是優點還是缺點,問題在於,絕大多數人都是習慣了使用SQL,突然不使用,這不是逼著人去改嗎?你知道,它們很懶的。這就衍生出一些支援類SQL外掛程式的誕生,不要小看,這裡面足夠讓你大吃一驚(稍後介紹)。

2、  開源(很關鍵)

3、 拋棄了關聯式模式

4、 能在叢集中運行

5、  “無模式”資料,即不用事先修改結構定義,也可以自由添加欄位。

6、  Not Only SQL。“不只是SQL”,這中思維方式不僅僅把NoSql當做一項技術,而視為一場變革

弊端

1、  鑒於NoSql技術尚未成熟(最近誕生的如:Cassandra、MongoDB、Neo4J和Riak等),所以大部分企業級應用程式開發人員目前還應以現有關係型資料庫為主,但在前瞻性很強的項目中,可以選用先試先行。

2、  沒有規範的定義,每種NoSql解決方案的模型(如:“鍵值”、“文檔”、“列族”、“圖”)都不同,導致不同版本的NoSql動作陳述式之間相容性的差異

兩個概念:

1、  資料模型:是認知和操作資料時所用的模型。資料模型描述了我們如何同資料庫中的資料打交道。我們更關注資料模型。

2、  儲存模型:描述資料庫內部儲存及操作資料的機制。一般不涉及。

彙總資料模型:彙總

       關聯式模式把待儲存的資訊分割成元組(行,熟知資料庫操作的人都知道:關係型資料庫是對行操作的。意思是:讀寫都是按行操作元組是種受限資料結構:它只能包含一系列的值,因此不能在元組中嵌套另一元組,也不能包含由值或元組所組成的列表。致使所有操作都必須以元組為目標,而且返回值也必須是元組

       面向彙總使用的方式與之不同,我們通常操作資料時所用的單元,其結構都比元組資料複雜的多。如果能以這種複雜的結構存放列表或嵌套其他記錄結構,就解決了上面的問題,後面,“鍵值資料庫”、“文檔資料庫”、“列族資料庫”都使用的是這種更複雜的記錄。基於這種複雜的記錄簡稱“彙總”。

       為了更明白的闡述什麼是“彙總”,我們給出一個樣本:

       假設一個電子商務網站的使用者記錄,必須儲存使用者資訊、商品目錄、訂單、收貨地址、賬單地址和付款條件等資訊。這個應用情境,既可以用關係型資料模型建模,也可以用NoSql資料模型建模,我們來比較兩者的優劣。

       採用關係型模型建模:(簡單樣本)

1、  保證各張表格間不會出現重複資料。

2、  維護表格間的“完整性”


       圖面向關係型資料庫的資料模型

        圖  範例資料

採用彙總模型建模:

        圖 彙總資料模型      黑色菱形代表各資料在彙總結構中的關係

      範例資料,採用JSON格式來表示,因為它是NoSql領域中常用的資料格式

// in customers{"id":1,"name':"Martin","billingAddress":[{"city":"Chicago"}]} // in orders{"id":99,"customerId":1,"orderItems":[    {    "productId":27,    "price":32.45,    "productName":"NoSql Distilled"    }    ],    "shippingAddress":[{"city":"Chicago"}]    "orderPayment":[    "ccinfo":"1000-1000-1000"    "txnId":"abelif879rft",    "billingAdress":{"city":"Chicago"}    ],}

       這個模型有兩個主要彙總:客戶(Customer)和訂單(Order)。客戶資料包含一個賬單地址(billing address)列表,訂單資料包含訂單項(order item)列表,收貨地址(shipping address)和付款資訊(payment),而付款資訊有又含它所對應的賬單地址。

       同一邏輯地址(賬單地址和收貨地址所共用的“Chicago”)在樣本資料中出現了三次,但是此處我們不用ID來指代,而是直接複製這個地址字串。如果收貨地址和賬單地址都不會改變,這麼做就很合適。在關係型資料庫中,這種情況意味著Address表中的ID=77的那行資料保持不變。若要改變某個地址,需要在該表中建立新行。使用彙總模型後,我們就可以把整個地址結構複製到所有的彙總模型中。(?)

     考慮到上述模型與關係型資料庫要做權衡一樣,這裡我麼也可以採用非常規的模式,將產品名稱直接寫入訂單項。這種做法在彙總模型中很常見,我們希望在資料互動時盡量減少所需訪問的彙總個數。實際上,我麼也可以採用另一種方式,把客戶下的全部訂單放到客戶彙總中。

// in customers{"id":1,"name":"Martin","billingAddress":[{"city":"Chicago"}],“orders”:[{"id":99,"customerId":1,"orderItems":[    {    "productId":27,    "price":32.45,   "productName":"NoSql Distilled"    }    ],   "shippingAddress":[{"city":"Chicago"}]   "orderPayment":[   "ccinfo":"1000-1000-1000"   "txnId":"abelif879rft",   "billingAdress":{"city":"Chicago"}    ],}]}}

       這裡就必須談到如何劃分彙總邊界的問題(就是上面紅字部分涉及的地方),其實在建模過程中,邊界的劃分並沒有標準答案。如果想一次性訪問客戶的全部訂單,那就應該把它們放在一個大的彙總裡面,反之,若是每次只想專門處理一筆訂單,則應將“客戶”和“訂單”分離開來。這個都視情況而定,而有的時候這個邊界很難區分出來,在有的時候這種彙總反而會帶來更多的問題,這時彙總就不適宜了。

面向彙總的影響:

       雖然關係映射也能很好的處理各種資料元素之間的關係。上述樣本說明:訂單由訂單項、收貨地址及付款資訊組成。在關聯式模式中,可以用“外鍵”來表示表與表之間的關係,但是這樣做無法區分某個關係是否你能表示彙總。因此,資料庫無法使用彙總結構來協助其儲存於分布資料。

       選用面向彙總模型的決定因素,在於它非常適合在叢集中運行。這正是NoSql的關鍵之處。在叢集上運行時,需要把採集資料所需要的節點數降到最低如果資料庫中明確包含彙總結構,加上知道哪些資料要彙總一起操作,這些資料就可以放在一個節點中。(這在前期設計資料庫分散在不同節點上非常重要。例如:叢集中部署MongoDB收集不同機器上的的日誌資訊,因為不同機器上收集的記錄檔不同,這時候就需要考慮上述說的問題,哪些資料可以放在一個節點上收集更有利於彙總,在實際運用很關鍵

       關係型資料庫支援交易處理,即“ACID事務”,是關係型資料庫中的關鍵中的重點。那麼在NoSql中交易處理適合嗎?通常情況下,面向彙總的資料庫不支援跨越多個彙總的ACID事務。取而代之的是,每次只能在一個彙總結構上執行原子操作,也就是說。如果我們想以原子方式操作多個彙總,那就必須自己寫應用代碼(這不是廢話嗎?)。

鍵值與文檔資料模型

       鍵值與文檔資料庫都是面向彙總的。這些資料庫主要通過彙總來構建,且這兩類資料庫都包含大量的彙總,每個彙總中都包含擷取資料所用的鍵或ID。

兩種資料模型的區別:

       鍵值資料庫:彙總不透明(資料結構不知道其內部實現細節即可以為外部程式使用)。基本上都是通過鍵來搜尋彙總內容,查詢得到全部資料,不能僅僅查詢或擷取其中的一部分。優勢在於:彙總中可以儲存任意資料,資料庫可能會限制彙總的總大小。

       文檔資料庫:可以看到其結構。提交查詢的關鍵詞往往是基於文檔的內容,可以查詢並擷取其中一部分資料,它也許是通過鍵也許不是通過鍵擷取資料。優勢:資料庫中雖然限制了其中存放的內容,定義了自己的結構與資料類型,這樣的好處,可以更靈活的訪問資料。

列族儲存模型

       早期NoSql資料庫是Google的BigTable。BigTable模型的出現影響後來的HBase和Cassandra等NoSql 資料庫。在起先,大部分資料庫都以行為單中繼存放區資料,尤其在需要提高寫入性(寫入操作多)的情況下。然而,有些情況下寫入操作執行的很少,卻常常需要一次性讀取行中的很多列。在這種情況下,將所有行的某一組列作為基本資料存放區單元,效果會更好。於是“列儲存資料庫”的命名就來了。

       BigTable和它的繼承者都遵循“以一組列(就是列族)來儲存”的概念。後來大部分的NoSql資料庫都可以稱為“列族資料庫”或“列式資料庫”==“圖資料庫”

       理解列族模型最好的方式可以將其視為兩級彙總結構(two-level aggregate structure)。與“鍵值儲存”相同,第一個鍵通常代表行標識符,用來擷取想要的彙總。其於“鍵值儲存”的區別在於,其“行彙總”本身又是一個映射,其中包含更為詳細的值。

       列族資料庫將列組織為列族。每一列都必須是某個列族的一部分,而且訪問資料的單元也得是列。這樣設計的前提是,某個列族中的資料經常需要一起訪問把彙總分為列族,讓資料庫將其視為行彙總內的一個資料單元


       圖  列族結構表示客戶資訊

1、  面向行(row-oriented):每一行都是一個彙總(例如:ID-123456的顧客就是一個彙總),該彙總內部包含一些有用資料區塊(客戶資訊、訂單記錄)的列族。

2、  面向列(column-oriented):每個列族都定義了一種記錄類型(例如:客戶資訊),其中每行都表示一條記錄。(這裡的“行”,指上述圖中的行,其實對應資料庫中的列族)

        面向列,反映了“列”在列族資料庫中的重要性。由於資料庫瞭解這些資料通常的分組方式,在儲存及訪問時利用此資訊()。由於列族中可以隨意添加列,所以在建模項目清單時,可以把其中每個項目都表示為單獨的列。

總結:

       上面,大致介紹了三種不同風格的面向彙總的資料模型。三者共同點:叢集上運行,彙總是中心環節,因為資料庫必須保證將彙總內的資料存放在同一個節點上。彙總是“更新”操作的最小資料單位,對事務控制來說,以彙總為操作單元,大小正好。

       ·彙總作為互動單元的資料集合。資料庫中的ACID操作以彙總為界。

       ·鍵值資料看、文檔資料庫、列族資料庫都是面向彙總資料庫。

       ·彙總使資料庫在叢集上管理資料存放區更為方面。

       ·如果資料互動大都在同一彙總內執行,可選用面向彙總的資料庫;若互動操作需要使用多種不同格式的資料,最好選用,非彙總資料庫。


       後續繼續探討NoSql機理與實現。



CopyrightBUAA

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.