淺談常見的NoSQL技術方案和選型

前言

在互聯網和大數據的背景下,愈來愈多的網站、應用系統須要支撐 海量數據存儲高併發請求高可用高可擴展性 等特性要求。傳統的 關係型數據庫 已經難以應對相似的需求,各類各樣的 NoSQLNot Only SQL)數據庫所以而產生。程序員

本文將分析 傳統數據庫 的存在的問題,以及幾類 NoSQL 如何解決這些問題。在不一樣的 業務場景 下,做出正確的 數據存儲 技術選型。web

正文

1. 傳統數據庫缺點

缺點 解釋說明
大數據場景下 I/O 較高 由於數據是按 行存儲,即便只針對其中 某一列 進行運算,關係型數據庫也會對 整行數據 進行掃描,從存儲設備中 讀入內存,致使 I/O 較高
結構化存儲 不夠靈活 存儲的是 行記錄,沒法存儲 靈活的數據結構
表結構 schema 擴展不方便 如要須要修改 表結構,須要執行執行 DDLdata definition language)語句修改,修改期間會致使 鎖表,部分服務不可用
全文搜索 功能較弱 關係型數據庫只可以進行 子字符串匹配查詢,當表的數據逐漸變大的時候,即便在有 索引 的狀況下,like 掃表查詢的匹配會 很是慢
難以 存儲處理 複雜 關係型數據 傳統的關係數據庫,並不擅長處理 數據點之間 的關係

2. NoSQL簡介

NoSQL,泛指 非關係型 的數據庫,能夠理解爲 關係型 數據庫的一個有力補充。算法

NoSQL 在許多方面性能大大優於 非關係型 數據庫的同時,每每也伴隨一些特性的缺失。比較常見的是 事務功能 的缺失。 數據庫事務正確執行的四個基本要素 ACID 以下:數據庫

名稱 描述
A Atomicity(原子性) 一個事務中的全部操做,要麼所有完成,要麼所有不完成,不會在中間某個環節結束。事務在執行過程當中發生錯誤,會被回滾到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。
C Consistency一致性 在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。
I Isolation隔離性 數據庫容許多個併發事務同時對數據進行讀寫和修改的能力。隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。
D Durability持久性 事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。

針對傳統 關係型數據庫 的不足,下面介紹常見的 5 大類 NoSQL 解決方案:編程

3. 列式數據庫

列式數據庫 是以 列相關存儲架構 進行數據存儲的數據庫,主要適合於 批量數據處理即時查詢。相對應的是 行式數據庫,數據以 行相關的存儲架構 進行空間分配,主要適合於 小批量數據處理,經常使用於 聯機事務型數據處理後端

基於列式數據庫的 列存儲特性,能夠解決某些特定場景下 關係型數據庫I/O 的問題。緩存

3.1. 基本原理

傳統關係型數據庫是 按照行 來存儲數據庫,稱爲 行式數據庫,而 列式數據庫按照列 來存儲數據。安全

將表放入存儲系統中有兩種方法,而咱們絕大部分是採用 行存儲 的。行存儲法是將 各行 放入 連續的物理位置,這很像傳統的記錄和文件系統。服務器

列存儲法 是將數據 按照列 存儲到數據庫中,與 行存儲 相似,下圖是兩種存儲方法的圖形化解釋:網絡

3.2. 常見列式數據庫

3.2.1. HBase

HBase 是一個開源的 非關係型分佈式數據庫NoSQL),它參考了 谷歌BigTable 建模,實現的編程語言爲 Java。它是 Apache 軟件基金會的 Hadoop 項目的一部分,運行於 HDFS 文件系統之上,爲 Hadoop 提供相似於 BigTable 規模的服務。所以,它能夠 容錯地 存儲 海量稀疏 的數據。

3.2.2. BigTable

BigTable 是一種 壓縮的高性能的高可擴展性的,基於 Google 文件系統(Google File SystemGFS)的數據存儲系統,用於存儲 大規模結構化數據,適用於雲計算。

3.3. 相關特性

3.3.1. 優勢

  • 高效的儲存空間利用率

列式數據庫 針對不一樣列的 數據特徵 而發明了 不一樣算法,使其比 行式數據庫 高的多的 壓縮率。普通的 行式數據庫 通常壓縮率在 3:15:1 左右,而 列式數據庫 的壓縮率通常在 8:130:1 左右。

比較常見的,經過 字典表 壓縮數據:

下面纔是那張表原本的樣子。通過 字典表 進行 數據壓縮 後,表中的 字符串 才都變成 數字。正由於每一個字符串在 字典表 裏只 出現了一次,因此達到了 壓縮 的目的。

  • 查詢效率高

讀取多條數據的 同一列效率高,由於這些列都是 存儲在一塊兒的,一次磁盤操做能夠數據的 指定列 所有讀取到 內存 中。 下圖經過 一條查詢 的執行過程說明 列式存儲 (以及 數據壓縮)的優勢。

執行步驟以下:

  1. 字典表 裏找到 字符串對應數字(只進行一次字符串比較)。
  2. 數字 去列表裏匹配,匹配上的位置設爲 1
  3. 不一樣列匹配結果 進行 位運算 獲得符合全部條件的 記錄下標
  4. 使用這個 下標組裝 出最終的 結果集
  • 適合作聚合操做

  • 適合大量的數據而不是小數據

3.3.2. 缺點

  • 不適合掃描 小量數據

  • 不適合 隨機的更新

  • 不適合作含有刪除和更新的 實時操做

  • 單行數據 支持 ACID事務操做多行數據事務操做,不支持事務的 正常回滾,支持 (Isolation)隔離性、(Durability)持久性,不能保證 (Atomicity)原子性、(Consistency)一致性。

3.4. 應用場景

列數據庫的適用場景,以 HBase 爲例說明:

  • 適合 大數據量 (100TB 級數據),有 快速隨機訪問 的需求。

  • 適合 寫密集型 應用,天天寫入量巨大,而 讀數量相對較小 的應用,好比 IM歷史消息遊戲日誌 等等。

  • 適合不須要 複雜查詢 條件來查詢數據的應用。HBase 只支持基於 rowkey 的查詢,對於 HBase 來講,單條記錄 或者 小範圍的查詢 是能夠接受的。大範圍 的查詢因爲 分佈式 的緣由,可能在 性能 上有點影響。HBase 不適用於有 join多級索引表關係複雜 的數據模型。

  • 性能可靠性 要求很是高的應用。

  • 因爲 HBase 自己沒有 單點故障可用性 很是高。

  • 適合 數據量較大,並且 增加量 沒法預估的應用,須要進行優雅的數據擴展的應用。HBase 支持 在線擴展,即便在一段時間內,數據量呈 井噴式增加,也能夠經過 HBase 橫向擴展 來知足功能。

  • 存儲 結構化半結構化 的數據。

4. K-V數據庫

4.1. 基本概念

指的是使用 鍵值key-value)存儲的數據庫,其數據按照 鍵值對 的形式進行 組織索引存儲

KV 存儲很是適合不涉及過多 數據關係 業務的數據。它可以有效減小 讀寫磁盤 的次數,比 SQL 數據庫存儲 擁有更好的 讀寫性能,可以解決 關係型數據庫 沒法存儲 數據結構 的問題。

4.2. 常見K-V數據庫

4.2.1. Redis

Redis 是一個使用 ANSI C 編寫的 開源支持網絡基於內存可選持久性鍵值對存儲 數據庫。Redis 是目前最流行的 鍵值對存儲 數據庫之一。

4.2.2. Cassandra

Apache Cassandra(社區內通常簡稱爲 C*)是一套 開源的分佈式 NoSQL 數據庫系統。它最初由 Facebook 開發,用於儲存 收件箱 等簡單格式數據,集 Google BigTable數據模型Amazon Dynamo徹底分佈式 架構於一身。Cassandra 是一種流行的 分佈式結構化 數據存儲方案。

4.2.3. Memcached

Memcached 是一個 開放源代碼高性能、分配的 內存對象緩存系統。用於加速動態 web 應用程序,減輕關係型數據庫負載。它能夠應對 任意多個鏈接,使用 非阻塞的網絡 IO。因爲它的工做機制是在內存中開闢一塊空間,而後創建一個 Hash 表,Memcached 自管理這些 Hash 表。

Memcached 簡單而強大。它簡單的設計促進 迅速部署,易於發現所面臨的問題,解決了不少 大型數據緩存

4.2.4. LevelDB

LevelDB 是一個由 Google 所研發的 鍵/值對Key/Value Pair嵌入式 數據庫管理系統 編程庫,以開源的 BSD 許可證發佈。

4.3. 相關特性

K-V 數據庫的相關特性,以 Redis 爲例說明:

4.3.1. 優勢

  • 性能極高

Redis 單機最高能支持超過 10WTPS

  • 豐富的數據類型

Redis 支持包括 StringHashListSetSorted SetBitmapHyperloglog 等數據結構。

  • 豐富的特性

Redis 還支持 publish/subscribe通知key 過時 等特性。

4.3.2. 缺點

  • Redis 事務 不能支持 原子性持久性AD),只支持 隔離性一致性IC)。

這裏所說的 沒法保證原子性,是針對 Redis事務操做,由於事務是 不支持回滾roll back),而由於 Redis單線程模型Redis 的普通操做是 原子性的

4.4 應用場景

4.4.1. 適用場景

  • 適合存儲 用戶信息(好比 會話)、配置文件參數購物車 等等。這些信息通常都和 ID 掛鉤。

4.4.2. 不適用場景

  • 不適合須要經過 來查詢,而不是 來查詢。Key-Value 數據庫中根本沒有經過 值查詢 的途徑。

  • 不適合須要儲存 數據之間的關係。在 Key-Value 數據庫中不能經過 兩個或以上 的鍵來 關聯數據

  • 不適合須要支持 事務 的場景。在 Key-Value 數據庫中 故障產生 時不能夠進行 回滾

5. 文檔型數據庫

5.1. 基本概念

文檔數據庫 用於將 半結構化數據 存儲爲 文檔 的一種數據庫。文檔數據庫一般以 JSONXML 格式存儲數據。

  • 因爲文檔數據庫的 no-schema 特性,能夠 存儲讀取 任意數據。

  • 因爲使用的 數據格式JSON 或者 BSON,由於 JSON 數據是 自描述的,無需在使用前定義字段,讀取一個 JSON不存在的字段 也不會致使 SQL 那樣的語法錯誤,能夠解決關係型數據庫 表結構 schema 擴展不方便 的問題。

5.2. 常見文檔數據庫

5.2.1. MongoDB

MongoDB 是一個基於 分佈式文件存儲 的數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的 高性能 數據存儲解決方案。

MongoDB 是一個介於 關係數據庫非關係數據庫 之間的產品,是非關係數據庫當中功能 最豐富,最像關係數據庫的 NoSQL

5.2.2. CouchDB

CouchDB 是用 Erlang 開發的 面向文檔分佈式 數據庫,用於存儲 半結構化 的數據,比較相似 luceneindex 結構。

CouchDB 支持 RESTful API,它使用 JSON 做爲 存儲格式JavaScript 做爲 查詢語言MapReduceHTTP 做爲 APINoSQL 數據庫。其中一個顯著的功能就是 多主複製 功能。除此以外,CouchDB 構建在強大的 B- 樹儲存引擎 之上。

5.3. 相關特性

文檔型數據庫 的相關特性,以 MongoDB 爲例進行說明:

5.3.1. 優勢

  • 新增字段簡單不須要像關係型數據庫同樣,先執行 DDL 語句 修改表結構,程序代碼 直接讀寫 便可。

  • 容易兼容 歷史數據。對於歷史數據,即便沒有新增的字段,也不會致使錯誤,只會返回 空值,此時 代碼兼容處理 便可。

  • 容易存儲複雜數據。JSON 是一種強大的 描述語言,可以描述複雜的 數據結構

5.3.2. 缺點

相比 傳統關係型數據庫,文檔數據庫的缺點,主要是對 多條數據記錄事務支持較弱,具體體現以下:

  • Atomicity(原子性):僅支持 單行/文檔級原子性,不支持 多行多文檔多語句原子性

  • Isolation(隔離性):隔離級別僅支持 已提交讀Read committed)級別,可能致使 不可重複讀幻讀 的問題。

  • 不支持 複雜查詢。例如 join 查詢,若是須要 join 查詢,須要 屢次操做數據庫

5.4. 應用場景

5.4.1. 適用場景

  • 數據量 很大或者將來會變得很大。

  • 表結構不明確,且 字段不斷增長,例如內容管理系統,信息管理系統。

5.4.2. 不適用場景

  • 在不一樣的文檔上須要添加 事務Document-Oriented 數據庫並不支持 文檔間的事務

  • 多個文檔之間須要 複雜的查詢,例如 join 操做。

6. 全文搜索引擎

6.1. 基本概念

傳統關係型數據庫,主要經過 索引 來達到 快速查詢 的目的。在 全文搜索 的業務下,索引 也無能爲力,主要體如今如下幾方面:

  • 全文搜索的條件,能夠隨意 排列組合,若是經過索引來知足,則索引的 數量很是多

  • 全文搜索的 模糊匹配方式,索引 沒法知足,只能用 like 進行查詢,而 like 查詢是 整表掃描效率很是低

全文搜索引擎的出現,正是解決關係型數據庫 全文搜索較弱 的問題。

6.2. 基本原理

全文搜索引擎 的技術原理稱爲 倒排索引inverted index),是一種 索引方法,其基本原理是創建 單詞文檔 的索引。與之相對是,是 正排索引,其基本原理是創建 文檔單詞 的索引。

  • 如今有以下文檔集合:

  • 正排索引 獲得索引以下:

可見,正排索引 適用於根據 文檔名稱 查詢 文檔內容

  • 簡單的 倒排索引 以下:

  • 帶有 單詞頻率 信息的 倒排索引 以下:

可見,倒排索引 適用於根據 關鍵詞 來查詢 文檔內容

6.3. 常見全文搜索引擎

6.3.1. ElasticSearch

ElasticSearch 是一個基於 Apache Lucene搜索引擎。它提供了一個 分佈式多租戶 對全文搜索引擎。ElasticSearch 是用 Java 開發的,對外提供 RESTful Web 接口。根據 DB-Engines 排名,ElasticSearch 是最受歡迎的 企業搜索引擎

6.3.2. Solr

SolrApache Lucene 項目的 開源企業搜索平臺。其主要功能包括 全文檢索命中標示分面搜索動態聚類數據庫集成,以及 富文本(好比 WordPDF)處理等等。Solr 是高度 可擴展 的,並提供了 分佈式搜索索引複製

6.4. 相關特性

全文搜索引擎,以 ElasticSearch 爲例說明:

6.4.1. 優勢

  • 查詢效率高,適用於對 海量數據 進行 近實時 的處理。

  • 可擴展性

  • 基於 集羣 環境能夠方便 橫向擴展,能夠承載 PB 級的數據。

  • 支持 高可用ElasticSearch 集羣彈性靈活,能夠發現新的或失敗的節點,重組從新平衡 數據,確保數據是 安全可訪問的

6.4.2. 缺點

  • 事務的 ACID 支持不足,單一文檔 的數據是支持 ACID 的。對於 多個文檔事務操做,不支持事務的 正常回滾。支持(Isolation)隔離性(基於 樂觀鎖機制)和(Durability)持久性,不支持(Atomicity)原子性,(Consistency)一致性。

  • 對相似數據庫中,經過 外鍵 進行 多表關聯的複雜操做支持較弱。

  • 讀寫 有必定 延時,寫入的數據,最快 1s 中能被檢索到。

  • 更新 性能較低,底層實現是 先刪數據,再 插入新數據

  • 內存佔用大,由於 Lucene索引部分 加載到 內存 中。

6.5. 應用場景

6.5.1. 適用場景

  • 分佈式的 搜索引擎數據分析引擎
  • 全文檢索結構化檢索 以及 數據分析
  • 對海量數據進行 近實時 的處理,能夠將 海量數據 分散到 多臺服務器 上去 存儲檢索

6.5.2. 不適用場景

  • 數據須要 頻繁更新

  • 須要 複雜關聯查詢

7. 圖形數據庫

7.1. 基本概念

圖形數據庫 應用 圖形理論 存儲 實體 之間的 關係信息。最多見例子就是 社會網絡中人與人之間的關係。關係型數據庫 用於存儲這種 關係型數據 的效果並很差,其查詢 複雜緩慢超出預期

圖形數據庫 的獨特設計彌補了這個缺陷,解決 關係型 數據庫 存儲處理複雜關係型數據 功能較弱的問題。

7.2. 常見圖形數據庫

7.2.1. Neo4j

Neo4j 是一個 高性能的NOSQL 圖形數據庫,它將 結構化數據 存儲在 「圖形網絡上」 而不是 「表中」。它是一個 嵌入式的基於磁盤的、具有徹底的 事務特性Java 持久化引擎

Neo4j 也能夠被看做是一個 高性能的圖引擎。程序員工做在一個 面向對象的靈活的網絡結構 下而不是 嚴格靜態表中

7.2.2. ArangoDB

ArangoDB 是一個 原生多模型 數據庫系統。數據庫系統支持 三個 重要的 數據模型鍵/值文檔圖形)。

ArangoDB 包含一個 數據庫核心統一查詢語言 AQLArangoDB 查詢語言)。查詢語言是 聲明性的,容許在 單個查詢組合 不一樣的 數據訪問模式ArangoDB 是一個 NoSQL 數據庫系統,但 AQL 在不少方面與 SQL 都相似。

7.3. 基本原理

圖形數據庫,以 Neo4j 爲例說明:

  • Neo4j 使用 數據結構 中圖(graph)的概念來進行 建模

  • Neo4j 中兩個最基本的概念是 節點節點 表示 實體 則表示 實體之間的關係節點 均可以有本身的 屬性。不一樣 實體 經過各類不一樣的 關係 關聯起來,造成複雜的 對象圖

針對關係數據,兩種數據庫的 存儲結構 分別以下:

Neo4j 中,存儲節點 時使用了 index-free adjacency,即 每一個節點 都有指向其 鄰居節點指針。這樣就能夠在 O(1)複雜度 內找到 鄰居節點。另外,按照官方的說法,在 Neo4j s是最重要的,是 first-class entities,須要 單獨存儲。這有利於在 圖遍歷 的時候 提升速度,也能夠很方便地以 任何方向 進行遍歷。

7.4. 相關特性

7.4.1. 優勢

  • 高性能表現

圖的遍歷圖數據結構 所具備的獨特算法,即從 一個節點 開始,根據其鏈接的 關係,能夠快速和方便地找出它的 鄰近節點。這種查找數據的方法不受 數據量大小 的影響,由於 鄰近查詢 始終查找的是 有限的局部數據,不會對 整個數據庫 進行搜索。

  • 設計的靈活性

數據結構 的天然伸展特性,以及其 非結構化數據格式,讓圖數據庫設計能夠具備很大的 伸縮性靈活性。由於隨着需求的變化而增長的 節點關係 及其 屬性,並不會影響到 原來數據 的正常使用。

  • 開發的敏捷性

數據模型 直接明瞭,從需求的討論開始,到程序開發和實現,基本上不會有大的變化。

  • 徹底支持ACID

不像別的 NoSQL 數據庫,Neo4j 還徹底具備 事務管理特性,徹底支持 ACID 事務管理。

7.4.2. 缺點

  • 節點關係 和它們的 屬性 的數量被 限制

  • 不支持 拆分

7.5. 應用場景

7.5.1. 適用場景

  • 在一些 關係性強 的數據應用,例如 社交網絡

  • 推薦引擎,將數據以 圖的形式 表現,很是有益於推薦的制定。

7.5.2. 不適用場景

  • 記錄大量 基於事件 的數據,如日誌記錄、傳感器數據。

  • 對大規模 分佈式數據 進行處理,相似於 Hadoop

  • 不適用於應該保存在 關係型數據庫 中的 結構化數據

  • 二進制數據存儲

小結

關於 關係型數據庫NoSQL 數據庫 的選型,每每須要考慮幾個指標:

  • 數據量
  • 併發量
  • 實時性
  • 一致性要求
  • 讀寫分佈
  • 數據類型
  • 安全性
  • 運維成本

常見的系統數據庫選型參考以下:

系統類型 數據庫選型
企業內部管理系統 例如運營系統,數據量少,併發量小,首選考慮 關係型數據庫
互聯網大流量系統 例如電商單品頁,後臺考慮選 關係型數據庫,前臺考慮選 內存型數據庫
日誌型系統 原始數據 考慮選 列式數據庫日誌搜索 考慮選 倒排索引
搜索型系統 例如站內搜索,非通用搜索,商品搜索,後臺考慮選 關係型數據庫,前臺考慮選 倒排索引
事務型系統 例如庫存管理,交易,記帳,考慮選 關係型數據庫 + 緩存數據庫 + 一致性型協議
離線計算 例如大量數據分析,考慮選 列式數據庫 或者 關係型數據庫 均可以
實時計算 例如實時監控,能夠考慮選 內存型數據庫 或者 列式數據庫

設計實踐中,要基於需求、業務驅動架構,不管選用 RDB/NoSQL/DRDB。必定是以需求爲導向,最終數據存儲方案,必然是考慮各類 權衡 的綜合性設計。


歡迎關注技術公衆號: 零壹技術棧

零壹技術棧

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索