NoSQL 之于大數(shù)據(jù)
關(guān)系型數(shù)據(jù)庫幾乎是許多開發(fā)者和DBA對于傳統(tǒng)三層架構(gòu)應(yīng)用的唯一選擇。使用這一場景有很多原因,數(shù)據(jù)建模方法,查詢語言與數(shù)據(jù)交互,保證數(shù)據(jù)的一致性部署,并能夠為復(fù)雜的應(yīng)用服務(wù)。
然而,這不是解決所有數(shù)據(jù)存儲問題的唯一方案,也是NoSQL 產(chǎn)生的原因。NoSQL 提供了新的方法而不是采用面向標(biāo)準(zhǔn)SQL的范式。
NoSQL 技術(shù)與高伸縮性無縫融合,很多技術(shù)同時具備了高分布性和高性能,是大數(shù)據(jù)分析的存儲基石。大多數(shù)時間里,它們使 現(xiàn)有RDBMS 技術(shù)所實現(xiàn)的架構(gòu)更加完整,例如 作為緩存服務(wù)器,搜索引擎,非結(jié)構(gòu)化存儲,易變信息存儲等。主要分為4類:
- Key/value
- 列存儲
- 面向文檔的存儲
- 圖存儲
現(xiàn)在深入到各種技術(shù),選擇最適用于使用場景的技術(shù)。
Key/Value
***個也是最早的 NoSQL 數(shù)據(jù)存儲就是key/value. 這些數(shù)據(jù)就像字典一樣根據(jù)key來匹配value,通常使用在需要高性能的基本信息存儲,例如需要快速讀寫的session信息,這些存儲在這樣的情景非常高效,也通常具有高伸縮性。
Key/value也經(jīng)常被用于上下文的隊列化來保證數(shù)據(jù)不丟失,例如日志架構(gòu)或搜索引擎的索引架構(gòu)。Redis 和Riak KV 是非常有名的key/value數(shù)據(jù)存儲; Redis 使用的更加廣泛,因為它有著一個內(nèi)存型 K/V 存儲,并且持久化是可選的。Redis 經(jīng)常用于web應(yīng)用中來存儲session相關(guān)的數(shù)據(jù),例如node或者-
PHP的 web應(yīng)用 ; 每秒鐘可以提取成千上萬的session信息而沒有性能損失。另一個典型場景是后面要講到的序列化:Redis位于 Logstash 和 ElasticSearch 之間來存儲t ElasticSearch 查詢中的索引。
Column
由于要存儲超大量的記錄信息 到達(dá)了key/value存儲限制的時候就需要用到列存儲。列存儲技術(shù)對于RDBMS世界的工程師可能不太容易理解,但事實上非常簡單。RDBMS 中數(shù)據(jù)是按行存儲的,而列存儲中是按列的。使用列數(shù)據(jù)庫的主要好處是能高速訪問海量數(shù)據(jù)。 RDBMS的一行在硬盤上是一個連續(xù)的存儲,多行可能存儲在硬盤不同的位置,使訪問稍顯復(fù)雜,在列數(shù)據(jù)庫中的一列數(shù)據(jù)是連續(xù)存儲的。
舉個例子,考慮在RDBMS中查詢索引博客的標(biāo)題,尤其是有數(shù)百萬數(shù)據(jù)的時候,需要大量的IO操作,而在列數(shù)據(jù)庫中,這樣的查詢只是一次訪問。這樣的數(shù)據(jù)庫在從特定簇提取海量數(shù)據(jù)中非常順手,但此消彼長的是缺乏靈活性。使用最多的列存儲數(shù)據(jù)庫是
Google Cloud Bigtable, 但開源的列存儲數(shù)據(jù)庫是Apache HBase 和Cassandra.
列存儲數(shù)據(jù)庫的另一個好處是容易伸縮,這些列在海量存儲時具有高伸縮性。這就是為什么它們主要用于保存非易變且長久保留信息的原因。
Document
列存儲數(shù)據(jù)庫對于含有比較深嵌套結(jié)構(gòu)的結(jié)構(gòu)化數(shù)據(jù)的存儲不是***的,這種場景需要使用面向文檔的數(shù)據(jù)存儲。數(shù)據(jù)實際上以key/value 存儲,但是所有壓縮的數(shù)據(jù)叫做文檔。 文檔依賴于一個結(jié)構(gòu)或者編碼例如XML, 但更多時候是 JSON (JavaScript Object Notation).
盡管文檔型數(shù)據(jù)庫對于數(shù)據(jù)的結(jié)構(gòu)化存儲和表達(dá)都非常有用,但也有其脆弱的一面,特別是與數(shù)據(jù)的交互性操作。它們基本上要遍歷整個文檔,例如當(dāng)讀取某個特定字段的時候,遍歷可能會影響性能。
當(dāng)需要存儲嵌套信息的時候,可以采用文檔型數(shù)據(jù)庫。例如,考慮怎樣表達(dá)應(yīng)用中的一個賬戶,大概有以下信息:
基礎(chǔ)信息:姓名,生日,照片 ,URL, 創(chuàng)建日期等等
復(fù)雜信息: 地址,認(rèn)證方法(password, Facebook, 等第三方認(rèn)證),興趣等等。
這也是NoSQL 文檔型數(shù)據(jù)庫經(jīng)常用到web應(yīng)用的原因: 表達(dá)嵌套對象非常容易,由于都使用JSON,還可以與前端的JavaScript技術(shù)無縫集成。
使用最多的文檔型數(shù)據(jù)庫是MongoDB, Couchbase, 和 Apache CouchDB,都非常容易安裝和啟動,有很好的文檔說明,而且都是可伸縮的,除此之外,它們也是開放現(xiàn)代web應(yīng)用的明確選擇。
Graph
Graph 數(shù)據(jù)庫與其它數(shù)據(jù)庫有著本質(zhì)的區(qū)別。它使用了不同的范式來表達(dá)數(shù)據(jù)——樹結(jié)構(gòu),節(jié)點和邊連接起來叫做關(guān)系。這些數(shù)據(jù)庫是隨著社交網(wǎng)絡(luò)而誕生的,例如表達(dá)用戶的好友網(wǎng)絡(luò),他們的好友關(guān)系等等。對于其它類型的數(shù)據(jù)存儲,可能把一個用戶的好友關(guān)系存儲在一個文檔中,但是,存儲好友關(guān)系還依然非常復(fù)雜;使用圖數(shù)據(jù)庫就非常簡單,為每個好友創(chuàng)建節(jié)點,通過關(guān)系連接他們,依賴查詢的需要和范圍瀏覽圖。
***的圖數(shù)據(jù)庫是Neo4j, 象前面所說的,主要使用場景是處理復(fù)雜的關(guān)系信息,例如實體間的連接,也可以用于分類的場景。
Figure 2-1 展示了在圖數(shù)據(jù)庫中3個實體是如何連接的。
圖中的兩天賬戶節(jié)點Jane 和 John, 它們之間的每一條邊定義了他們的關(guān)系,在某天相互認(rèn)識,另一組節(jié)點連接的兩個賬戶展示了Jane 和 Joh在某天后都成為了足球組的成員。
使用場景中的NoSQL
根據(jù)使用場景,首先需要一個文檔型的 NoSQL數(shù)據(jù)庫,將存儲在關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)結(jié)構(gòu)化的一個 JSON 文檔. 如前所述,傳統(tǒng)的RDBMSs 將數(shù)據(jù)存儲到多個有關(guān)系的表,當(dāng)?shù)玫揭粋€完整對象時變得比較復(fù)雜和低效。在Figure 2-2. 中可以看到一個賬戶被分割成多個表的例子。
如果要獲得所有的賬戶信息,基本上需要join兩到三個表?,F(xiàn)在考慮這樣的情形: 需要處理所有用戶在應(yīng)用中的每一次連接,這些連接有著不同的商業(yè)邏輯。 ***,想要賬戶自身的視圖。通過傳遞一個賬戶標(biāo)識通過API從全部用戶視圖中得到一個怎樣的文檔呢?
- { "id": "account_identifier", "email": "account@email.com", "firstname": "account_firstname", "lastname": "account_lastname", "birthdate": "account_birthdate", "authentication": [{ "token": "authentication_token_1", "source": "authenticaton_source_1", "created": "16-12-12" }, { "token": "authentication_token_2", "source": "authenticaton_source_2", "created": "16-12-12" }], "address": [{ "street": "address_street_1", "city": "address_city_1" "zip": "address_zip_1" "country": "address_country_1" "created": "16-12-12" }]}
好處顯而易見: 通過保持一個實體的 JSON 表達(dá),可以更快更好的訪問數(shù)據(jù)。進(jìn)一步,將這一方法通用化,從NoSQL數(shù)據(jù)庫讀取所有的讀操作,而讓所有的寫操作 (create, update,delete) 還在RDBMS上 .但必須實現(xiàn)一個邏輯來維持 RDBMS到NoSQL 的數(shù)據(jù)同步,如果沒在緩存中的話還要創(chuàng)建一個關(guān)系型數(shù)據(jù)庫的對象。
在NoSQL高效可伸縮地創(chuàng)建文檔時為什么還要保持 RDBMS呢?因為這不是應(yīng)用的真正目的。我不想產(chǎn)生一個Big Bang 的影響. 假設(shè)RDBMS已經(jīng)準(zhǔn)備好了,但因為RDBMS缺乏靈活性而集成了一個NoSQL存儲。希望充分利用兩個***的技術(shù) —— 特別是RDBMS的數(shù)據(jù)一致性和NoSQL的伸縮性 。
【本文來自51CTO專欄作者老曹的原創(chuàng)文章,作者微信公眾號:喔家ArchiSelf,id:wrieless-com】