NoSQL初探

jopen 10年前發布 | 18K 次閱讀 NoSQL數據庫 NOSQL

一般數據庫的使用方式

  1. 集成數據庫:數據共享與數據通信

  2. 應用程序數據庫:數據只由某個應用程序負責,交互采用應用程序接口(Web服務形式,被很多叫為SOA)

 

NoSQL的來源與規范

NoSQL這個名字本身來自于一個聚會,該聚會為了推ter的話題便于搜索,起了這個名字。

NoSQL目前沒有官方的規范,幾個典型的特征是:

  1. 非關系型數據庫

  2. 一般是面向集群的

  3. 一般是開源的

  4. 數據存儲無需聲明和保持一致的格式(無模式)

 

NoSQL數據庫分類

主要有四類:

  1. 列族(HBase,Cassandra,Amazon SimpleDB,Hypertable)

  2. 文檔(MongoDB,CouchDB,Terrastore、OrientDB、RavenDB)

  3. 鍵值(Riak,Redis,LevelDB, Memcached DB, HamsterDB)

  4. 圖(HyperGraphDB,Neo4J,Infinite Graph,OrientDB,FlockDB)

詳細可以參考

http://nosql-database.org/

 

鍵值數據庫

類似一張HASH表。有兩列,存放鍵、值。

只對單個鍵的操作具備一致性

查詢方式以關鍵字查詢為主,所以可能大部分精力花在設計鍵名上。

適合場景:存放會話信息,以session id為鍵;用戶配置信息,user id;購物車;

不適合場景:不同數據集間欲建立關系;含有多項操作,比如需要聯動回滾;查詢數據為主;操作多個關鍵字

 

文檔數據庫

文檔的格式可以是XML, JSON, BSON(BinaryJSON,MongoDB所用的二進制數據文件)。文檔數據庫存放的“文檔”可以類比鍵值數據庫中的“值”

MongoDB中以replica set的方式解決一致性問題,寫入操作必須等待所寫數據復制到全部或是給定數量的從節點之后,才能返回。

文檔數據庫可以查詢文檔中的數據,而不用像鍵值數據庫,必須根據關鍵字獲取整個文檔,然后再檢索其內容。各文檔數據庫提供了不同的查詢功能。CouchDB可通過視圖查詢,物化視圖或動態視圖。 MongoDB支持一種JSON格式的查詢語言,包括MYMquery實現where語句,MYMorderby實現排序,MYMexplain列出執行計劃等。如SQL中select * from A 等價的Mongo Shell為db.A.find()。

適用場景:事件記錄;內容管理系統或博客系統;網站分析或實時分析,如頁面瀏覽量;電子商務應用,存貯訂單等

不適合場景:包含多項操作的復雜事務;查詢持續變化的聚合節奏,即類似SQL語句外連接的表總變動。

列族數據庫

列族數據庫將數據存貯在列族中,列族里的行把許多列數據與本行的行健(row key)關聯起來。可以存儲關鍵字及其映射值,病可以把值分成多個列族,讓每個列族代表一張數據映射表。

列族與關系數據庫的行容器對照,都有關鍵字表示行,每行由多列組成,但是區別在于列族數據庫的每行不一定有相同的列。如果列中包含小列組成的映射表,這就是“超列”。用超列構建的列族叫“超列族”。

Cassandra收到寫入請求后,先將待寫入數據錄入“commit log”,然后將其寫入內存中的“memtable”,寫入操作在這兩步完成表明寫入成功。寫入請求定期寫入SSTable中,SSTable中的緩存一旦寫入數據庫,就不會繼續寫入了。如果數據變動,則重新寫一張SSTable。無用的SStable用compaction操作回收。一致性的高低級別取決于設置幾個節點的commit log寫入成功才返回。

Cassandra基本查詢有GET, SET, DEL。查詢前必須指定鍵空間:use ecommerce。插入數據的語句舉例:SET Customer['lin']['city']='shenzhen';查詢GET Customer['lin'];GET Customer['lin']['city'];也可以建立索引。Cassandra也支持一種CQL的類SQL語句,但是不支持jion和子查詢,而且where語句的功能不是特別強大

 

適用場景:事件記錄,可以使用appname:timestamp為行健,自定義列的方式;博客系統,可以把tag,分類等屬性放在不同列中;計數器,如廣告展示時間等。

不適合場景:根據數據查詢結果來聚合數據的操作,如SUM, AVG;查詢模式探索的項目,因為查詢模式的改變,列族的設計也需要改變。

 

圖數據庫

圖數據庫可以存放實體與實體間的關系。實體對應“節點”,并擁有屬性;關系對應“邊”,具有方向性;

圖數據庫遍歷“關系”的速度非常快。節點間的關系不在查詢時計算,而是在創建時就持久化了。遍歷持久化后的關系,要比每次查詢實時計算關系快得多。節點間關系可以是domain之間的關系,也可以是secondary關系。

大部分圖數據庫不支持分布式,Neo4J兼容ACID事務。

圖數據庫可以使用Gremlin等查詢語言。Gremlin是一個可以遍歷圖的領域特定語言,可以遍歷所有市縣了Blueprints屬性圖的圖數據庫。Neo4J也可以用Cypher查詢語言來查詢圖。查詢節點的直接關系,關系數據庫也可以做。但是如果關系深度大于1時,圖數據庫才顯示出優勢。查詢關系時還可以指定單、雙向方向。可以計算節點間的最小跳數,即最短路徑。

適用場景:互聯網數據,尤其是社交數據存儲;GIS、路線分配等業務;購物的推薦引擎。

不適合場景:實體屬性變更頻繁,且影響全局操作。

 

分布式模型

分片。NoSQL數據庫大都提供了“自動分片”的功能,可以讓數據庫自己負責把數據分布到各分片。分片對讀取和寫入操作的效率提升明顯,但是對故障恢復幫助不大。

主從復制。主節點負責存放權威數據,通常負責處理數據的更新。主從復制就是從主節點到從節點的同步。主從復制明顯改善需要頻繁讀取數據的場景性能。主節點出錯,從節點依然可以處理讀取請求,并可以指定從節點代替出錯的主節點。

對等復制。對等復制主要解決主從復制的寫入故障恢復能力弱的問題。沒有主節點的概念,所有節點都可以處理寫入請求。對等復制的最大問題在于數據的一致性,兩個節點同時處理寫入操作,可能引發寫入沖突。兩種思路解決一致性的問題,一個是寫入前各節點進行協調;另一個是數據庫自動處理沖突數據。

一致性的CAP定理。給定一致性Consistency,可用性Availability,分區耐受性Partition tolerance,我們只能同時滿足其中的兩個屬性。一致性無需解釋。可用性是指如果客戶可以同集群中的某個節點通信,那么該節點就必然能處理讀取及寫入操作。分區耐受性指,如果發生故障,導致整個集群分為多個無法互相通信的分區時,集群依然可用。一般的分布式系統都在一致性和可用性間平衡或取舍。

版本戳version stamp。NoSQL數據庫大都不支持事務,但是可用版本戳來維護數據的一致性。版本戳可以采用計數器實現,也可以是一個很大隨機唯一的數字,可以是根據內容生成的hash碼,也可以用time stamp。CouchDB的版本戳就是結合了計數器和內容hash碼。對等復制的數據庫沒有統一生成版本戳的地方,需要改進。一個方法是分布式版本控制系統一樣,每個節點都有一份版本戳,這種情況需要客戶端保存版本戳記錄。最常用的一個方法是采用數組式版本戳Vector Stamp。這種版本戳由一系列計數器組成,每個代表一個節點,如[A:43,B:12, C:54]。兩個節點同步時,判斷兩個版本戳,如果新版本戳中有一個變量比舊的小,則表明有版本沖突,需要處理。

 

混合持久化

不同的數據庫用來解決不同的問題。只用一種database engine應對所有需求,這種解決版本比較低效。傳統關系數據庫領域的OLAP(聯機分析處理Online analytical processing)和OLTP(聯機交易系統Online transaction  processing)差別其實也很大。不同領域數據,如商業邏輯處理引擎,會話,報表,日志的可用性、一致性、備份策略不一定相同,所以需要混合持久化處理。舉例來說,以電子商務來說,可以用鍵值數據庫存儲購物車信息,用圖數據庫處理商品推薦。

混合持久化的一個比較好的實現方式就是封裝數據庫操作為服務。事實上,Riak和Neo4J等數據庫都提供了現成的REST API。

企業決定采用混合持久化前,需要考慮許可、支持、工具、升級、驅動、安全等問題。也要考慮不同數據庫的監測、備份數據、部署復雜性等技術問題。

NoSQL數據庫畢竟還不如關系數據庫那么成熟,所以考慮做數據庫抽離,或隔離層的考慮。但是如果隔離層的成本過高,還不如直接實現,這個需要具體考量。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!