文章首發於51CTO技術棧公衆號
做者 陳彩華
文章轉載交流請聯繫 caison@aliyun.com
複製代碼
隨着大數據時代的到來,愈來愈多的網站、應用系統須要支撐海量數據存儲,高併發請求、高可用、高可擴展性等特性要求,傳統的關係型數據庫在應付這些調整已經顯得力不從心,暴露了許多能以克服的問題。由此,各類各樣的NoSQL(Not Only SQL)數據庫做爲傳統關係型數據的一個有力補充獲得迅猛發展。html
本文將分析傳統數據庫的存在的相關問題,以及幾大類NoSQL如何解決這些問題,但願給你們提供在不一樣業務場景下,關於存儲方面技術選型提供參考。java
大數據場景下I/O較高 由於數據是按行存儲,即便只針對其中某一列進行運算,關係型數據庫也會將整行數據從存儲設備中讀入內存,致使I/O較高web
存儲的是行記錄,沒法存儲數據結構redis
表結構schema擴展不方便 如要須要修改表結構,須要執行執行DDL(data definition language),語句修改,修改期間會致使鎖表,部分服務不可用算法
全文搜索功能較弱 關係型數據庫下只可以進行子字符串的匹配查詢,當表的數據逐漸變大的時候,like查詢的匹配會很是慢,即便在有索引的狀況下。何況關係型數據庫也不該該對文本字段進行索引sql
存儲和處理複雜關係型數據功能較弱 許多應用程序須要瞭解和導航高度鏈接數據之間的關係,才能啓用社交應用程序、推薦引擎、欺詐檢測、知識圖譜、生命科學和 IT/網絡等用例。然而傳統的關係數據庫並不善於處理數據點之間的關係。它們的表格數據模型和嚴格的模式使它們很難添加新的或不一樣種類的關聯信息。數據庫
NoSQL,泛指非關係型的數據庫,能夠理解爲SQL的一個有力補充。編程
在NoSQL許多方面性能大大優於非關係型數據庫的同時,每每也伴隨一些特性的缺失,比較常見的,是事務庫事務功能的缺失。 數據庫事務正確執行的四個基本要素:ACID以下:緩存
名稱 | 描述 | |
---|---|---|
A | Atomicity (原子性) |
一個事務中的全部操做,要麼所有完成,要麼所有不完成,不會在中間某個環節結束。 事務在執行過程當中發生錯誤,會被回滾到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。 |
C | Consistency 一致性 |
在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。 |
I | Isolation 隔離性 |
數據庫容許多個併發事務同時對數據進行讀寫和修改的能力。隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。 |
D | Durability 持久性 |
事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。 |
下面介紹5大類NoSQL數據針對傳統關係型數據庫的缺點提供的解決方案:安全
列式數據庫是以列相關存儲架構進行數據存儲的數據庫,主要適合於批量數據處理和即時查詢。相對應的是行式數據庫,數據以行相關的存儲體系架構進行空間分配,主要適合於小批量的數據處理,經常使用於聯機事務型數據處理。
基於列式數據庫的列列存儲特性,能夠解決某些特定場景下關係型數據庫I/O較高的問題
傳統關係型數據庫是按照行來存儲數據庫,稱爲「行式數據庫」,而列式數據庫是按照列來存儲數據。
將表放入存儲系統中有兩種方法,而咱們絕大部分是採用行存儲的。 行存儲法是將各行放入連續的物理位置,這很像傳統的記錄和文件系統。 列存儲法是將數據按照列存儲到數據庫中,與行存儲相似,下圖是兩種存儲方法的圖形化解釋:
HBase是一個開源的非關係型分佈式數據庫(NoSQL),它參考了谷歌的BigTable建模,實現的編程語言爲 Java。它是Apache軟件基金會的Hadoop項目的一部分,運行於HDFS文件系統之上,爲 Hadoop 提供相似於BigTable 規模的服務。所以,它能夠容錯地存儲海量稀疏的數據。
BigTable是一種壓縮的、高性能的、高可擴展性的,基於Google文件系統(Google File System,GFS)的數據存儲系統,用於存儲大規模結構化數據,適用於雲端計算。
優勢以下:
列式數據庫因爲其針對不一樣列的數據特徵而發明的不一樣算法使其每每有比行式數據庫高的多的壓縮率,普通的行式數據庫通常壓縮率在3:1 到5:1 左右,而列式數據庫的壓縮率通常在8:1到30:1 左右。 比較常見的,經過字典表壓縮數據: 下面中才是那張表原本的樣子。通過字典表進行數據壓縮後,表中的字符串才都變成數字了。正由於每一個字符串在字典表裏只出現一次了,因此達到了壓縮的目的(有點像規範化和非規範化Normalize和Denomalize)
讀取多條數據的同一列效率高,由於這些列都是存儲在一塊兒的,一次磁盤操做能夠數據的指定列所有讀取到內存中。 下圖經過一條查詢的執行過程說明列式存儲(以及數據壓縮)的優勢
執行步驟以下:
i. 去字典表裏找到字符串對應數字(只進行一次字符串比較)。
ii. 用數字去列表裏匹配,匹配上的位置設爲1。
iii. 把不一樣列的匹配結果進行位運算獲得符合全部條件的記錄下標。
iv. 使用這個下標組裝出最終的結果集。
複製代碼
適合作聚合操做
適合大量的數據而不是小數據
缺點以下:
以HBase爲例說明:
指的是使用鍵值(key-value)存儲的數據庫,其數據按照鍵值對的形式進行組織、索引和存儲。
KV 存儲很是適合不涉及過多數據關係業務關係的數據,同時能有效減小讀寫磁盤的次數,比 SQL 數據庫存儲擁有更好的讀寫性能,可以解決關係型數據庫沒法存儲數據結構的問題。
Redis是一個使用ANSI C編寫的開源、支持網絡、基於內存、可選持久性的鍵值對存儲數據庫。從2015年6月開始,Redis的開發由Redis Labs贊助,而2013年5月至2015年6月期間,其開發由Pivotal贊助。在2013年5月以前,其開發由VMware贊助。根據月度排行網站DB-Engines.com的數據顯示,Redis是最流行的鍵值對存儲數據庫。
Apache Cassandra(社區內通常簡稱爲C*)是一套開源分佈式NoSQL數據庫系統。它最初由Facebook開發,用於儲存收件箱等簡單格式數據,集Google BigTable的數據模型與Amazon Dynamo的徹底分佈式架構於一身。Facebook於2008將 Cassandra 開源,此後,因爲Cassandra良好的可擴展性和性能,被 Apple, Comcast,Instagram, Spotify, eBay, Rackspace, Netflix等知名網站所採用,成爲了一種流行的分佈式結構化數據存儲方案。
以Redis爲例: 優勢以下:
缺點以下: 針對ACID,Redis事務不能支持原子性和持久性(A和D),只支持隔離性和一致性(I和C) 特別說明一下,這裏所說的沒法保證原子性,是針對Redis的事務操做,由於事務是不支持回滾(roll back),而由於Redis的單線程模型,Redis的普通操做是原子性的
大部分業務不須要嚴格遵循ACID原則,例如遊戲實時排行榜,粉絲關注等場景,即便部分數據持久化失敗,其實業務影響也很是小。所以在設計方案時,須要根據業務特徵和要求來作選擇
文檔數據庫(也稱爲文檔型數據庫)是旨在將半結構化數據存儲爲文檔的一種數據庫。文檔數據庫一般以 JSON 或 XML 格式存儲數據。
因爲文檔數據庫的no-schema特性,能夠存儲和讀取任意數據。
因爲使用的數據格式是JSON或者BSON,由於JSON數據是自描述的,無需在使用前定義字段,讀取一個JSON中不存在的字段也不會致使SQL那樣的語法錯誤,能夠解決關係型數據庫表結構schema擴展不方便的問題
MongoDB是一種面向文檔的數據庫管理系統,由C++撰寫而成,以此來解決應用程序開發社區中的大量現實問題。2007年10月,MongoDB由10gen團隊所發展。2009年2月首度推出。
Apache CouchDB是一個開源數據庫,專一於易用性和成爲"徹底擁抱web的數據庫"。它是一個使用JSON做爲存儲格式,JavaScript做爲查詢語言,MapReduce和HTTP做爲API的NoSQL數據庫。其中一個顯著的功能就是多主複製。CouchDB的第一個版本發佈在2005年,在2008年成爲了Apache的項目。
以MongoDB爲例進行說明
優勢以下:
相比傳統關係型數據庫,文檔數據庫的缺點主要是對多條數據記錄的事務支持較弱,具體體現以下:
MongonDB仍是支持多文檔事務的Consistency(一致性)和Durability(持久性)
雖然官方宣佈MongoDB將在4.0版本中正式推出多文檔ACID事務支持,最後落地狀況還有待見證。
適用場景:
不適用場景:
傳統關係型數據庫主要經過索引來達到快速查詢的目的,在全文搜索的業務下,索引也無能爲力,主要體如今:
而全文搜索引擎的出現,正是解決關係型數據庫全文搜索功能較弱的問題
全文搜索引擎的技術原理稱爲「倒排索引」(inverted index),是一種索引方法,其基本原理是創建單詞到文檔的索引。與之相對是,是「正排索引」,其基本原理是創建文檔到單詞的索引。
如今有以下文檔集合:
正排索引獲得索引以下:
可見,正排索引適用於根據文檔名稱查詢文檔內容
簡單的倒排索引以下:
帶有單詞頻率信息的倒排索引以下:
可見,倒排索引適用於根據關鍵詞來查詢文檔內容
Elasticsearch
Elasticsearch是一個基於Lucene的搜索引擎。它提供了一個分佈式,多租戶 -可以全文搜索與發動機HTTP Web界面和無架構JSON文件。Elasticsearch是用Java開發的,並根據Apache License的條款做爲開源發佈。根據DB-Engines排名,Elasticsearch是最受歡迎的企業搜索引擎,後面是基於Lucene的Apache Solr。Solr
Solr是Apache Lucene項目的開源企業搜索平臺。其主要功能包括全文檢索、命中標示、分面搜索、動態聚類、數據庫集成,以及富文本(如Word、PDF)的處理。Solr是高度可擴展的,並提供了分佈式搜索和索引複製以Elasticsearch爲例: 優勢以下:
缺點以下:
適用場景以下:
不適用場景以下:
圖形數據庫應用圖形理論存儲實體之間的關係信息。最多見例子就是社會網絡中人與人之間的關係。關係型數據庫用於存儲「關係型」數據的效果並很差,其查詢複雜、緩慢、超出預期,而圖形數據庫的獨特設計偏偏彌補了這個缺陷,解決關係型數據庫存儲和處理複雜關係型數據功能較弱的問題。
Neo4j是由Neo4j,Inc。開發的圖形數據庫管理系統。由其開發人員描述爲具備原生圖存儲和處理的符合ACID的事務數據庫,根據DB-Engines排名, Neo4j是最流行的圖形數據庫。
ArangoDB是由triAGENS GmbH開發的原生多模型數據庫系統。數據庫系統支持三個重要的數據模型(鍵/值,文檔,圖形),其中包含一個數據庫核心和統一查詢語言AQL(ArangoDB查詢語言)。查詢語言是聲明性的,容許在單個查詢中組合不一樣的數據訪問模式。ArangoDB是一個NoSQL數據庫系統,但AQL在不少方面與SQL相似。
Titan是一個可擴展的圖形數據庫,針對存儲和查詢包含分佈在多機羣集中的數百億個頂點和邊緣的圖形進行了優化。Titan是一個事務性數據庫,能夠支持數千個併發用戶實時執行復雜的圖形遍歷。
以Neo4j爲例:
Neo4j 使用數據結構中圖(graph)的概念來進行建模。 Neo4j 中兩個最基本的概念是節點和邊。節點表示實體,邊則表示實體之間的關係。節點和邊均可以有本身的屬性。不一樣實體經過各類不一樣的關係關聯起來,造成複雜的對象圖。
針對關係數據,2種2數據庫的存儲結構不一樣:
Neo4j中,存儲節點時使用了」index-free adjacency」,即每一個節點都有指向其鄰居節點的指針,可讓咱們在O(1)的時間內找到鄰居節點。另外,按照官方的說法,在Neo4j中邊是最重要的,是」first-class entities」,因此單獨存儲,這有利於在圖遍歷的時候提升速度,也能夠很方便地以任何方向進行遍歷
以下優勢:
高性能表現 圖的遍歷是圖數據結構所具備的獨特算法,即從一個節點開始,根據其鏈接的關係,能夠快速和方便地找出它的鄰近節點。這種查找數據的方法並不受數據量的大小所影響,由於鄰近查詢始終查找的是有限的局部數據,不會對整個數據庫進行搜索
設計的靈活性 數據結構的天然伸展特性及其非結構化的數據格式,讓圖數據庫設計能夠具備很大的伸縮性和靈活性。由於隨着需求的變化而增長的節點、關係及其屬性並不會影響到原來數據的正常使用
開發的敏捷性 直觀明瞭的數據模型,從需求的討論開始,到程序開發和實現,以及最終保存在數據庫中的樣子,它的模樣彷佛沒有什麼變化,甚至能夠說原本就是如出一轍的
徹底支持ACID 不像別的NoSQL數據庫Neo4j還具備徹底事務管理特性,徹底支持ACID事務管理
缺點以下:
適用場景以下:
不適用場景以下:
關係型數據庫和NoSQL數據庫的選型,每每須要考慮幾個指標:
常見軟件系統數據庫選型參考以下:
設計實踐中,要基於需求、業務驅動架構,不管選用RDB/NoSQL/DRDB,必定是以需求爲導向,最終數據存儲方案必然是各類權衡的綜合性設計
NoSQL Databases, why we should use, and which one we should choose