NoSQL經典詳解

NoSQL經典詳解mysql

第一章 關係型數據庫程序員

  傳統的關係數據庫具備不錯的性能,高穩定性,久經歷史考驗,並且使用簡單,功能強大,同時也積累了大量的成功案例。經常使用的數據庫軟件有Mysql、Oracle、SQL Server等。在互聯網領域,MySQL應用普遍,爲互聯網的發展作出了卓越的貢獻。
  
關係型數據庫做爲應用普遍的通用型數據庫,它的突出優點主要有如下幾點:   
  • 保持數據的一致性(事務處理)  acid原子性 一致性 隔離性 持久性
  • 因爲以標準化爲前提,數據更新的開銷很小(相同的字段基本上都只有一處)
  • 能夠進行JOIN等複雜查詢:在Join操做中,分別爲Join(Join查詢), SelectMany(Select一對多選擇)和GroupJoin(分組Join查詢)。
要熟練的掌握Join的特性。兩個錶鏈接方式主要分爲內鏈接(inner join)和外鏈接(outer join)。外鏈接又分爲三種,left outer join、right outer join和full outer join。存在不少實際成果和專業技術信息(成熟的技術)‚
在90年代,一個網站的訪問量通常都不大,用單個數據庫徹底能夠輕鬆應付。在那個時候,更多的都是靜態網頁,動態交互類型的網站很少。
到了2000年之後,網站開始快速發展。論壇、博客、sns、微博逐漸引領web領域的潮流。
隨着訪問量的上升,幾乎大部分使用MySQL架構的網站在數據庫上都開始出現了性能問題,這時候web程序再也不僅僅專一在功能上,同時也在追求性能。程序員們開始大量的使用緩存技術來緩解數據庫的壓力,優化數據庫的結構和索引。開始比較流行的是經過文件緩存來緩解數據庫壓力,可是當訪問量繼續增大的時候,多臺web機器經過文件緩存不能共享,大量的小文件緩存也帶了了比較高的IO壓力。在這個時候,Memcached就天然的成爲一個很是時尚的技術產品。Memcached做爲一個獨立的分佈式的緩存服務器,爲多個web服務器提供了一個共享的高性能緩存服務。

 

緩存的實質是替數據庫擋了一層。頻繁被訪問的數據能夠被放置於緩存當中,以供頻繁訪問。
Mysql主從讀寫分離
因爲數據庫的寫入壓力增長,Memcached只能緩解數據庫的讀取壓力。讀寫集中在一個數據庫上讓數據庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提升讀寫性能和讀庫的可擴展性。Mysql的master-slave模式被普遍應用。
什麼是主從複製?
   多增長几個數據庫來存儲數據,假設有三臺數據庫,一主二從,即一臺主服務器,兩臺從服務器,當新增數據至主數據庫服務器的時候,那麼同時複製此數據進入到從數據庫服務器當中。數據複製是爲了容災備份,緩存備份,保證數據的完整性。

總體上來講,複製有3個步驟:   web

       (1)    master將改變記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件,binary log events);
       (2)    slave將master的binary log events拷貝到它的中繼日誌(relay log);
        (3)    slave重作中繼日誌中的事件,將改變反映它本身的數據。sql

下圖描述了複製的過程:數據庫

 

什麼是讀寫分離?
   增刪改是寫,查爲讀。
   分工明確,結合緩存能實現性能的一大提高
 

 

其中的M是master 即主DB Server ,S爲slaver即從屬DB Server,各有分工。編程

寫操做在 M,讀操做在S。S的數據是從master複製的。
與此同時,開始流行使用分庫分表來緩解寫壓力和數據增加的擴展問題。這個時候,MySQL推出了還不太穩定的表分區,這也給技術實力通常的公司帶來了但願。雖然MySQL推出了MySQL cluster集羣,但性能也不能很好的知足互聯網的要求,只是在高可靠性上提供了很是大的保證。
1 基本思想之什麼是分庫分表?
   從字面上簡單理解,就是把本來存儲於一個庫的數據分塊存儲到多個庫上,把本來存儲於一個表的數據分塊存儲到多個表上。
2 基本思想之爲何要分庫分表?
   分庫分表主要是由於數據庫中的數據量不必定是可控的,在未進行分庫分表的狀況下,隨着時間和業務的發展,庫中的表會愈來愈多,表中的數據量也會愈來愈大,相應地,數據操做,增刪改查的開銷也會愈來愈大;另外,因爲沒法進行分佈式部署,而一臺服務器的資源(CPU、磁盤、內存、IO等)是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。
3 分庫分表的實施策略。
分庫分表有垂直切分和水平切分兩種。
3.1 何謂垂直切分:
   即將表按照功能模塊、關係密切程度劃分出來,部署到不一樣的庫上。例如,咱們會創建定義數據庫workDB、商品數據庫payDB、用戶數據庫userDB、日誌數據庫logDB等,分別用於存儲項目數據定義表、商品定義表、用戶數據表、日誌數據表等。
3.2 何謂水平切分:
   當一個表中的數據量過大時,咱們能夠把該表的數據按照某種規則,例如userID散列,進行劃分,而後存儲到多個結構相同的表,和不一樣的庫上。例如,咱們的userDB中的用戶數據表中,每個表的數據量都很大,就能夠把userDB切分爲結構相同的多個userDB:part0DB、part1DB等,再將userDB上的用戶數據表userTable,切分爲不少userTable:userTable0、userTable1等,而後將這些表按照必定的規則存儲到多個userDB上。

 

MySQL的擴展性瓶頸
分庫分表的規則把握都是須要經驗的,並且分庫分表的子庫到必定階段又面臨擴展問題。還有就是需求的變動,可能又須要一種新的分庫方式。
分庫分表缺點:
(1)受業務規則影響,需求變更致使分庫分表的維護複雜
(2)系統數據訪問層代碼須要修改
Master-Slave缺點
(1)Slave實時性的保障,對於實時性很高的場合可能須要作一些處理
(2)高可用性問題,Master就是那個致命點,容易產生單點故障
關係數據庫很強大,可是它並不能很好的應付全部的應用場景。因此這個時候NoSQL的應用就顯得格外重要。

第二章 爲何要是有NoSQL

  NoSQL概念在2009年被提了出來。NoSQL最多見的解釋是「non-relational」,「Not Only SQL」也被不少人接受。(「NoSQL」一詞最先於1998年被用於一個輕量級的關係數據庫的名字。)關係型數據庫應用普遍,能進行事務(acid特性)處理和錶鏈接等複雜查詢。相對地,NoSQL數據庫只應用在特定領域,基本上不進行復雜的處理,但它偏偏彌補了關係型數據庫的不足之處。

 

  各個數據之間存在關聯是關係型數據庫得名的主要緣由,爲了進行join處理,關係型數據庫不得不把數據存儲在同一個服務器內,這不利於數據的分散,這也是關係型數據庫並不擅長大數據量的寫入處理的緣由。相反NoSQL數據庫本來就不支持Join處理,各個數據都是獨立設計的,很容易把數據分散在多個服務器上,故減小了每一個服務器上的數據量,即便要處理大量數據的寫入,也變得更加容易,數據的讀入操做也很容易。
例如:谷歌和Facebook天天爲他們的用戶收集萬億比特的數據。這些數據的存儲不須要固定的模式,無需多餘的操做就能夠橫向擴展。
 
CAP,BASE和最終一致性是NoSQL數據庫存在的三大基石。
CAP理論

 

1. 一致性(Consistency):任何一個讀操做老是能讀取到以前完成的寫操做結果,也就是在分佈式環境中,多點的數據是一致的; , 數據一致更新,全部數據變更都是同步的 ,客戶可以感知到一系列操做會一會兒執行完畢。
即更新操做成功並返回客戶端完成後,全部節點在同一時間的數據徹底一致。
2. 可用性(Availability):每個操做老是可以在肯定的時間內返回,也就是系統隨時都是可用的。 好的響應性能 ,每個操做必須有意想中的響應並終止。
即服務一直可用,並且是正常響應時間。
3. 分區容忍性(Partition Tolerance): 在出現網絡分區(好比斷網)的狀況下,分離的系統也能正常運行。具備很高的可靠性 ,操做均可以執行完畢,即便個別組件不可用。
即分佈式系統在遇到某節點或網絡分區故障的時候,仍然可以對外提供知足一致性和可用性的服務
 
 注意:可用性與分區容忍性在一些狀況下很容易混淆。舉個例子,假設系統中有若干個節點宕機了,系統仍然能正常運行,那麼應該說是系統的可用性高仍是分區容忍性高呢?我的的理解是,這種應該理解爲系統的分區容忍性高。由於若干個節點宕機,能夠理解爲這幾個節點與其它正常的節點失去聯繫了,也就是出現了網絡分區,按照定義,這屬於分區容忍性的範疇。那麼可用性是什麼?我的的理解可用性更多強調的是,系統對於讀寫操做的反應快慢,反應越快,可用性越高。
CAP原理的意思是,一個分佈式系統不能同時知足一致性,可用性和分區容忍性這三個需求,最多隻能同時知足兩個。因此大多數NoSQL系統都會根據本身的設計理念來進行相應的選擇,但因爲許多NoSQL數據庫都以水平擴展著稱,因此在CAP的選擇上面,都傾向於堅持分區容忍性,而放棄一致性或者可用性,它們的作法主要是消減關係型和事務相關的功能。
 
拓展:經過CAP理論,咱們知道沒法同時知足一致性、可用性和分區容錯性這三個特性,那要捨棄哪一個呢?
對於多數大型互聯網應用的場景,主機衆多、部署分散,並且如今的集羣規模愈來愈大,因此節點故障、網絡故障是常態,並且要保證服務可用性達到N個9,即保證P和A,捨棄C(退而求其次保證最終一致性)。雖然某些地方會影響客戶體驗,但沒達到形成用戶流程的嚴重程度。
對於涉及到錢財這樣不能有一絲讓步的場景,C必須保證。網絡發生故障寧肯中止服務,這是保證CA,捨棄P。貌似這幾年國內銀行業發生了不下10起事故,但影響面不大,報到也很少,廣大羣衆知道的少。還有一種是保證CP,捨棄A。例如網絡故障事只讀不寫。
孰優孰略,沒有定論,只能根據場景定奪,適合的纔是最好的。
 
BASE理論
BASE理論是對CAP理論的延伸,核心思想是即便沒法作到強一致性(Strong Consistency,CAP的一致性就是強一致性),但應用能夠採用適合的方式達到最終一致性(Eventual Consitency)。
 
關係數據庫的ACID模型擁有 高一致性 + 可用性 很難進行分區:
 
(1) 原子性(Atomicity)
事務的原子性指的是,事務中包含的程序做爲數據庫的邏輯工做單位,它所作的對數據修改操做要麼所有執行,要麼徹底不執行。這種特性稱爲原子性。
例如銀行取款事務分爲2個步驟(1)存摺減款(2)提取現金。不可能存摺減款,卻沒有提取現金。2個步驟必須同時完成或者都不完成。
(2)一致性(Consistency)    
事務的一致性指的是在一個事務執行以前和執行以後數據庫都必須處於一致性狀態。這種特性稱爲事務的一致性。假如數據庫的狀態知足全部的完整性約束,就說該數據庫是一致的。
例如完整性約束a+b=10,一個事務改變了a,那麼b也應隨之改變。
(3)隔離性(亦稱獨立性Isolation)
隔離性指併發的事務是相互隔離的。即一個事務內部的操做及正在操做的數據必須封鎖起來,不被其它企圖進行修改的事務看到。假如併發交叉執行的事務沒有任何控制,操縱相同的共享對象的多個併發事務的執行可能引發異常狀況。
(4)持久性(Durability)
持久性意味着當系統或介質發生故障時,確保已提交事務的更新不能丟失。即一旦一個事務提交,DBMS保證它對數據庫中數據的改變應該是永久性的,即對已提交事務的更新能恢復。持久性經過數據庫備份和恢復來保證。
 
BASE模型反ACID模型,徹底不一樣ACID模型,犧牲高一致性,得到可用性:
Basically Available基本可用。
基本可用是指分佈式系統在出現故障的時候,容許損失部分可用性,即保證核心可用。
電商大促時,爲了應對訪問量激增,部分用戶可能會被引導到降級頁面,服務層也可能只提供降級服務。這就是損失部分可用性的體現。
經歷過12306搶票的人應該常常會遇到這個問題:在搶票高峯的時候,明明票還有,可是查詢出來的列表倒是爲空的(若是沒票列表也應該會呈現);等高峯事後再查詢,列表又恢復正常。我的猜想應該是查詢過程當中出現了問題,要麼超時,要麼網絡問題致使查詢失敗採用的服務降級處理。因此,最終呈現給用戶的並非內部系統出錯之類的提示,而是一個空的列表。
Soft state軟狀態 狀態能夠有一段時間不一樣步,異步。
軟狀態是指容許系統存在中間狀態,而該中間狀態不會影響系統總體可用性。分佈式存儲中通常一份數據至少會有三個副本,容許不一樣節點間副本同步的延時就是軟狀態的體現。mysql replication的異步複製也是一種體現。
對關係型數據庫來講,插入一條數據後馬上查詢,是確定能夠讀出來這條數據的,可是對於不少Web應用而言,並不要求這麼高的實時性,比方說我發一條微博以後,過幾秒乃至十幾秒後,別人才提示有新微博,這是徹底能夠的。
Eventually consistent最終一致,最終數據是一致的就能夠了,而不是時時高一致。
最終一致性是指系統中的全部數據副本通過必定時間後,最終可以達到一致的狀態。弱一致性和強一致性相反,最終一致性是弱一致性的一種特殊狀況。
 
NoSQL的優點:
易擴展
NoSQL數據庫種類繁多,可是一個共同的特色都是去掉關係數據庫的關係型特性。數據之間無關係,這樣就很是容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。
大數據量,高性能
NoSQL數據庫都具備很是高的讀寫性能,尤爲在大數據量下,一樣表現優秀。這得益於它的無關係性,數據庫的結構簡單。通常MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache(大粒度鎖:一個url得到了鎖,其餘的url都不能得到),在針對web2.0的交互頻繁的應用,Cache性能不高。而NoSQL的Cache是記錄級的,是一種細粒度的Cache,因此NoSQL在這個層面上來講就要性能高不少了。
靈活的數據模型
NoSQL無需事先爲要存儲的數據創建字段,隨時能夠存儲自定義的數據格式。而在關係數據庫裏,增刪字段是一件很是麻煩的事情。若是是很是大數據量的表,增長字段簡直就是一個噩夢。這點在大數據量的web2.0時代尤爲明顯。
高可用
NoSQL在不太影響性能的狀況,就能夠方便的實現高可用的架構。
 
第三章 NoSQL數據庫
 
列存儲 Hbase
Cassandra
Hypertable
顧名思義,是按列存儲數據的。最大的特色是方便存儲結構化和半結構化數據,方便作數據壓縮,對針對某一列或者某幾列的查詢有很是大的IO優點。
文檔存儲 MongoDB
CouchDB
文檔存儲通常用相似json的格式存儲,存儲的內容是文檔型的。這樣也就有機會對某些字段創建索引,實現關係數據庫的某些功能。
key-value存儲 Tokyo Cabinet / Tyrant
Berkeley DB
MemcacheDB
Redis
能夠經過key快速查詢到其value。通常來講,存儲無論value的格式,照單全收。(Redis包含了其餘功能)
圖存儲 Neo4J
FlockDB
InfoGrid
圖形關係的最佳存儲。使用傳統關係數據庫來解決的話性能低下,並且設計使用不方便。
對象存儲 db4o
Versant
經過相似面嚮對象語言的語法操做數據庫,經過對象的方式存取數據。
xml數據庫 Berkeley DB XML
BaseX
高效的存儲XML數據,並支持XML的內部查詢語法,好比XQuery,Xpath。

 

面向列的數據庫
   Cassandra、HBase、HyperTable屬於這種類型。
   普通的關係型數據庫都是以行爲單位來存儲數據的,擅長以行爲單位的讀入處理,好比特定條件數據的獲取。所以,關係型數據庫也被稱爲面向行的數據庫。相反,面向列的數據庫是以列爲單位來存儲數據的,擅長以列爲單位讀入數據。
面向列的數據庫具備高擴展性,即便數據增長也不會下降相應的處理速度(特別是寫入速度),因此它主要應用於須要處理大量數據的狀況。另外,把它做爲批處理程序的存儲器來對大量數據進行更新也是很是有用的。但因爲面向列的數據庫跟現行數據庫存儲的思惟方式有很大不一樣,故應用起來十分困難。
 
面向文檔的數據庫
   MongoDB、CouchDB屬於這種類型,它們屬於NoSQL數據庫,但與鍵值存儲相異。
   (1)不定義表結構
     即便不定義表結構,也能夠像定義了表結構同樣使用,還省去了變動表結構的麻煩。
   (2)可使用複雜的查詢條件 
     跟鍵值存儲不一樣的是,面向文檔的數據庫能夠經過複雜的查詢條件來獲取數據,雖然不具有事務處理和Join這些關係型數據庫所具備的處理能力,但除此之外的其餘處理基本上都能實現。
鍵值存儲
 
鍵值存儲
它的數據是以鍵值的形式存儲的,雖然它的速度很是快,但基本上只能經過鍵的徹底一致查詢獲取數據,根據數據的保存方式能夠分爲臨時性、永久性和二者兼具 三種。
(1)臨時性
  所謂臨時性就是數據有可能丟失,memcached把全部數據都保存在內存中,這樣保存和讀取的速度很是快,可是當memcached中止時,數據就不存在了。因爲數據保存在內存中,因此沒法操做超出內存容量的數據,舊數據會丟失。總結來講:
  。在內存中保存數據
  。能夠進行很是快速的保存和讀取處理
  。數據有可能丟失
 (2)永久性
   所謂永久性就是數據不會丟失,這裏的鍵值存儲是把數據保存在硬盤上,與臨時性比起來,因爲必然要發生對硬盤的IO操做,因此性能上仍是有差距的,但數據不會丟失是它最大的優點。總結來講:
  。在硬盤上保存數據
。能夠進行很是快速的保存和讀取處理(但沒法與memcached相比)
  。數據不會丟失
(3) 二者兼備
  Redis屬於這種類型。Redis有些特殊,臨時性和永久性兼具。Redis首先把數據保存在內存中,在知足特定條件(默認是 15分鐘一次以上,5分鐘內10個以上,1分鐘內10000個以上的鍵發生變動)的時候將數據寫入到硬盤中,這樣既確保了內存中數據的處理速度,又能夠經過寫入硬盤來保證數據的永久性,這種類型的數據庫特別適合處理數組類型的數據。總結來講:
  。同時在內存和硬盤上保存數據
  。能夠進行很是快速的保存和讀取處理
  。保存在硬盤上的數據不會消失(能夠恢復)
  。適合於處理數組類型的數據
 NoSQL數據庫面臨的挑戰
1.成熟度
RDBMS系統由來已久。NoSQL擁護者們會說RDBMS的高齡是其衰退的標誌,不過對於大多數CIO來講,RDBMS的成熟讓人放心。對於大多數狀況來講,RDBMS系統是穩定且功能豐富的。相比較而言,大多數NoSQL數據庫則還有不少特性有待實現。
2.支持
企業須要的是安心,若是關鍵系統出現了故障,他們能夠得到即時的支持。全部RDBMS廠商都在竭盡全力地提供良好的企業支持。與之相反,大多數NoSQL系統都是開源項目,雖然每種數據庫都有那麼幾家公司提供支持,不過這些公司大多都是小的初創公司,沒有全球支持資源,也沒有Oracle、微軟或是IBM那種使人放心的公信力。
3.分析與商業智能
NoSQL數據庫在Web 2.0應用時代開始出現。所以,大多數特性都是面向這些應用的須要的。然而,應用中的數據對於業務來講是有價值的,這種價值遠遠超出了Web應用那種CRUD。企業數據庫中的業務信息能夠幫助改進效率並提高競爭力,商業智能對於大中型企業來講是個很是關鍵的IT問題。
4.管理
大多數NoSQL系統都是開源項目,雖然每種數據庫都有那麼幾家公司提供支持,不過這些公司大多都是小的初創公司,沒有全球支持資源,也沒有Oracle、微軟或是IBM那種使人放心的公信力。
5.專業
全球有不少開發者,每一個業務部門都會有熟悉RDBMS概念與編程的人。相反,幾乎每一個NoSQL開發者都處於學習模式。這種情況會隨着時間的流逝而發生改觀。但如今,找到一個有經驗的RDBMS程序員或是管理員要比NoSQL專家容易多了。 
 
NoSQL仍是關係型數據庫

 

 NoSQL應用場景

♣ 頻繁的寫入操做,相對較少的讀取統計信息的操做(好比一個web訪問計數器)應該使用基於內存的key/value存儲系統,好比Redis,或者是具有本地更新特性的文檔存儲系統,如MongoDB。json

♣ 海量數據(好比數據倉庫中須要分析的數據)適合與存儲在一個schmaless,分佈式的文件存儲系統中,如Hadoop。數組

♣ 存儲二進制文件(好比mp3或者pdf文檔)而且可以直接爲用戶的瀏覽器提供下載功能,可使用Amazon S3。瀏覽器

♣ 臨時性的數據(好比網站的session,緩存HTML頁面信息,等等)適合存儲在Memcache。緩存

 

們能夠在一個網站中使用下面四款數據產品來提供服務:

MySQL用於存儲敏感的數據,好比用戶的資料,交易的信息等等。

MongoDB用於存儲大量的,相對不敏感的數據,好比博客文章的內容,文章訪問次數等等。

Amazon S3用於存儲用戶上傳的文檔,圖片,音樂等等數據。

Memcached用於存儲臨時性的信息,好比緩存HTML頁面等。

 
總結
NoSQL數據庫的出現,彌補了關係數據(好比MySQL)在某些方面的不足,在某些方面能極大的節省開發成本和維護成本。
關係數據(好比MySQL)和NoSQL都有各自的特色和使用的應用場景,二者的緊密結合將會給web2.0的數據庫發展帶來新的思路。讓關係數據庫關注在關係上,NoSQL關注在存儲上。
相關文章
相關標籤/搜索