[NoSQL]-NoSQL解決資料庫暴量的新方法

摘要:NOSQL

本文轉自ITHOME

http://www.ithome.com.tw/itadm/article.php?c=63360&s=1

NoSQL解決資料庫暴量的新方法

 

在臺灣,開發社交遊戲的力可科技,因為關聯式資料庫無法應付每日2GB的資料量增長,而改採NoSQL資料庫來解決資料庫寫入暴量的問題。
NoSQL儼然成為資料庫的一股新威力

Facebook、Google、Twitter這些國外大型網站,為了解決資料庫大量資料存取的問題,近 年來紛紛捨棄了關聯式資料庫技術,
改以NoSQL資料庫來提升效能與擴充彈性;在臺灣,開發社交遊戲的力可科技,也因為關聯式資料庫無法應付每日2GB的 資料量增長,
而改採NoSQL資料庫來解決資料庫寫入暴量的問題。面對社交型態的網站興起,NoSQL儼然成為資料庫的一股新威力。

 

NoSQL臺灣實例:每日2GB資料成長的挑戰(1)
社交遊戲的互動會造成大量寫入資料的需求,一天就會產生2GB資料量,力可科技因而導入NoSQL資料庫來解決資料暴量的問題

NoSQL臺灣實例:每日2GB資料成長的挑戰(2)
NoSQL資料庫是一個統稱的名詞,泛指哪些非關聯式資料庫的資料庫技術,包括了數十種不同類型的資料庫系統,
因為這些資料庫大多沒有支援標準的SQL, 例如知名的Google BigTable、Amazon S3的Dynamo資料庫,或是微軟Azure平臺儲存資料的方式

了解NoSQL不可不知的5項觀念
透過這5個關鍵可以讓你快速了解NoSQL資料庫的特性、用途和限制

快速認識4類主流NoSQL資料庫
這4大類型包括了Key-Value資料庫、記憶體資料庫、圖學資料庫和文件資料庫

NoSQL臺灣實例:每日2GB資料成長的挑戰 今年3月初,力可科技總經理馮彥文既興奮又擔心地看著MySQL資料庫的統計數據,
他發現公司新推出的Facebook社群遊戲越來越受歡迎,記錄遊戲資 訊的資料庫容量也快速暴增。一天內產生的遊戲資訊高達2GB,
1個月就會增加60GB的資料量,按照這個增長速度,不用幾個月,就會用完資料庫伺服器上的硬碟。

Facebook、Twitter等知名社群網站都曾經發生過這種資料量暴增的難題,為了解決這個問題,
力可科技決定學習Facebook的經驗,導入一種和關聯式資料庫不一樣的NoSQL資料庫。

力可科技是臺灣少數專職開發社群遊戲的軟體公司,雖然規模只有11人,卻在Facebook上推出了十幾款Flash遊戲。
該公司的遊戲平臺擁有3百多萬個註冊用戶,每月上站人數達到50萬人次,同時上線玩遊戲的人數最多超過8千人。

剛開始,力可科技推出的遊戲都是回合制的Flash遊戲,像是寵物連連看、坦克對戰遊戲等。遊戲啟動時先下載需要的Flash程式和畫面元件,
結束時,再 將結果傳送回伺服器。除了遊戲過程中需要即時將各種狀態資訊傳遞給參與遊戲的每一個人,力可科技資深軟體架構師陳彥任表示,
回合制遊戲需要寫入的資料其實 不多,資料存取方式比較簡單。

社交遊戲的互動造成資料寫入量暴增
不過,今年初,力可科技推出了非回合制的社交遊戲(Social Game)寵物秘境,就像是去年流行的開心農場一樣,
讓玩家彼此可以進行各種社交互動。玩家除了擁有自己的房間可以養各式各樣的寵物之外,還能到朋友房間中和對方的寵物互動。

例如,玩家可以到朋友家中餵食他的寵物、收集寵物產生的物品等。就像是開心農場的玩法一樣,除了自己種菜以外,
還能去偷別人的菜。一個人擁有的朋友越多,在自己的房間中,就會看到越多人同時和自己的寵物互動。

從軟體開發角度來看,這種互動頻繁的社交遊戲和回合制的遊戲有很大的不同。就像是開心農場的偷菜行為一樣,
偷菜者點選滑鼠來偷菜,每按一次,菜的數量會減 少1份,偷菜者擁有的數量則會增加1份,而偷菜記錄也會增加一筆。
也就是說,「使用者每按下一個滑鼠Click,就要寫入資料庫一次。」陳彥任表示:「社 交遊戲的資料庫寫入次數比回合制遊戲增加了很多次。」

不僅資料寫入次數大增,使用者搶先的行為還會加快寫入資料庫的頻率。因為擔心其他人先來這個農場偷菜,
「使用者會持續一直按滑鼠,甚至在1秒鐘內就連續點選了20次。」陳彥任表示,等於1秒內就要寫入資料庫20次。

馮彥文指出,社交遊戲和傳統網站在資料庫使用上最大的不同點,正是讀取和寫入資料的比例。在傳統的網站中,
多數人只是瀏覽網頁而非貢獻內容,資料庫存取的運作中,讀取往往占了99%,只有1%的指令用來寫入資料,應付讀取的需求遠高於寫入的需求。

但是,在社交遊戲中,寫入資料庫的頻率很高,甚至會高於讀取資料庫的次數,以力可科技的社交遊戲為例,寫入和讀取的比例大約是1.5比1。
而國外知名 Facebook遊戲開發商Zynga所開發的遊戲,寫入與讀取的比例則介於1:3到1:10之間,也都比傳統網站1%的寫入比例高很多。

即使是透過群組方式,將多筆資料打包成一筆一次寫入,社交遊戲的程式還是得立刻將資料寫到後端資料庫中。一方面,
社交遊戲不像回合制遊戲有一個結束階段, 使用者會隨時會進入社交遊戲,也隨時會關閉瀏覽器結束遊戲。因為難以判斷使用者結束遊戲的時間,
如果沒有立即儲存,使用者互動的資料很容易就會遺失。

另一方面,在社交遊戲中,所有人都要能夠彼此看到對方,即時地將遊戲資訊寫入資料庫,其他使用者才能看到場景最新的變動狀態。

而且,在這種所有人能彼此看到的社交遊戲中,同時互動的使用者人數往往比一般線上遊戲更多。線上遊戲雖然同時有數十萬人上線,
但是這些使用者其實分散在不 同的伺服器。一套遊戲會安裝在多臺伺服器中,每一臺伺服器都是一個獨立的遊戲環境,
使用者必須登入其中一臺進行遊戲,也只能和那一臺伺服器中的使用者互 動,無法和其他伺服器中的使用者溝通。

在社交遊戲中,系統設計上還必須考量到每一個人具有和所有使用者互動的能力,即使使用者的好友沒有登入系統,
使用者也能夠進去好友建立的房間中,和同在這個房間裡的其他使用者互動,就像同事朋友可以一起到沒上線者的農地偷菜一樣。

上述這些社交遊戲的互動特性,都是造成資料庫資料量快速成長的原因,也是開發社交遊戲最大的挑戰之一。
力可科技的遊戲中用來記錄使用者狀態的資料表就有上億筆記錄,這個資料庫光是索引檔就高達25GB。

力可科技當時的資料庫伺服器只安裝了32GB的記憶體,資料庫系統有時無法載入足夠的索引檔資料,導致程式讀取資料庫的速度下降,
也連帶影響了遊戲的穩定性和順暢度。陳彥任估算,如果資料庫按照這樣的成長速度,不只是伺服器硬碟空間不夠,資料查詢效率也會越來越差。

為了預防未來資料庫檔案過大的問題,力可科技打算切割資料庫,將資料表分開儲存到不同的資料庫系統中,分別安裝在2臺伺服器上,
來提高單一資料庫的效率。 為了將最慢的幾個資料表切割到另一個資料庫,陳彥任先進行去正規化(Denormalization),
在現有資料表中增加一個新的欄位來建立新資料庫所 需要的欄位架構(Schema)。

力可科技為了降低營運成本,沒有另外先建立一套相同環境的測試資料庫系統,而是直接在上線的資料庫系統上執行這項新增欄位的指令,
原本預計1~2個小時就能完成這項資料表結構異動,但後來資料庫系統卻花了1天還沒有執行完,導致使用者一整天都無法登入。

後來又發生了幾次資料庫效能不足的當機事件,讓力可科技開始尋找不一樣的資料庫擴充方法。馮彥文希望能一次解決資料庫長期的擴充需求,
避免未來再遇到資料庫檔案太大時,又得面臨切割資料庫的問題。

後來,力可科技在NoSQL這類資料庫中找到Cassandra資料庫,可以解決資料快速擴充的問題,
馮彥文說:「理論上,未來只要增加一臺機器,舊資料庫之間就可以自動建立負載平衡,不用人工搬移和切割資料庫。」


力可科技導入NoSQL資料庫Cassandra,來解決今年推出社交遊戲「寵物祕境」後資料暴量的問題。

 

 

用NoSQL解決資料庫不斷擴充的維護問題
NoSQL資料庫是一個統稱的名詞,泛指哪些非關聯式資料庫的資料庫技術,包括了數十種不同類型的資料庫系統,
因為這些資料庫大多沒有支援標準的SQL, 例如知名的Google BigTable、Amazon S3的Dynamo資料庫,
或是微軟Azure平臺儲存資料的方式,都屬於NoSQL資料庫的其中一種。

常見的NoSQL資料庫有4類,分別是
圖學資料庫(Graph Database)、
文件導向的資料庫(Document-Oriented Database)、
Key-Value Store分散式資料庫、
記憶體快取為主的資料庫,
其中大多數是開源資料庫系統。

力可科技採取混用的作法,將成長速度最快、檔案最大的幾個資料表,搬移到NoSQL的分散式資料庫中,
其餘資料表則是還儲存在免費的MySQL資料庫中。用NoSQL解決龐大資料的擴充需求,
另一方面則能保留用SQL語法來查詢其他資料的便利性。

因為力可科技慣用的開發平臺是Java,所以,陳彥任在Java平臺的分散式NoSQL資料庫中,
找到一套有Key-Value Store類型的Cassandra資料庫,資料結構可以符合力可科技的遊戲需求,所以,他決定導入Cassandra。

Cassandra是Facebook開發的分散式資料庫,2008年時,Facebook為了儲存高達120TB的站內信箱(inbox)資料,
開發出Cassandra這套分散式資料庫,2009年3月成為Apache基金會重點發展的頂級計畫之一。

要建置分散式資料庫,Cassandra只要建立2個伺服器節點就能執行,這兩個節點的功能和角色幾乎一模一樣,
只需要在設定檔中指定好彼此溝通的IP網址即可。啟動資料庫以後,這兩個節點會自行複製資料、分散儲存、平衡資料庫存取的負載。

陳彥任表示,未來要擴充資料庫的容量時,只要建妥另一個Cassandra的資料庫節點,啟動新節點後,
原有的節點就會自行將資料複製到新節點中,自動建立彼此的分散架構。「很容易就可以擴充資料庫。即使有一臺資料庫節點當機,
重新開啟後就能自動再加入。」

Cassandra屬於Key-Value Store類型的分散式資料庫,採用Key-Value資料模式來儲存資料。最簡單的Key-Value資料庫中,
每一筆記錄只有2個欄位,也就是Key 欄位和Value欄位,每一個Key對應到一個Value欄位,
沒有傳統關聯式資料庫的欄位架構(Schema),讀取資料的方式也只有設定值、取出值或 刪除值等簡單的操作,
沒有像SQL語言那樣可以進行Join的複雜查詢。但是Key-Value架構的好處正是因為沒有Schema,只要建立另一群 Key值,
就等於是建立了另一個資料表,而因為每一群資料之間沒有關連,可以任意切割或擴充。

不過,Key-Value資料庫後來也發展出不同的Key-Value結構,例如像Cassandra提供了ColumnFamily,
以及Column/SuperColumn的彈性資料結構。使用上可視為三層的Hash Key對應到一個值。

舉例來說,第一層Key是使用者帳號,帳號中有一項是個人資訊,第二層Key則是個人資訊。
在個人資訊中又可以分成很多種類,如性別、學歷、生日等,生日 就是第三層Key。
透過「使用者帳號」、「個人資訊」、「生日」這三個Key值,就可取得對應的Value內容,也就是這個人的生日。

陳彥任表示,力可科技開發的遊戲儲存資料時有3層結構,Cassandra提供的3層Key結構可以符合遊戲中組織資料的方式,
「雖然不能使用Where指令,但有3層結構就有比較大的彈性。」

3月發生資料庫當機事件後,力可科技在今年4月開始評估各種NoSQL資料庫技術,5月開始建置,花了1個月的時間分階段導入,
6月完成導入,資料庫正式 上線。採用2臺Dell的PowerEdge R710伺服器來安裝2個Cassandra資料庫節點,
將資料量最大的幾個資料表轉移到Cassandra中,例如高達1億筆記錄的User State資料表。

導入NoSQL要先拋開SQL觀念
陳彥任指出:「轉移過程的第一個挑戰是要拋棄原有的SQL觀念,學習新的資料存取方法。」他解釋,
因為Cassandra不能使用SQL語法,那些透過像 Select語法來查詢資料的程式全部要重新寫,
開發者的想法也要調整,必須學習改用Cassandra的API來存取資料庫。


力可科技總經理馮彥文(右)和該公司資深軟體架構師陳彥任(左)認為,
導入NoSQL資料庫的第一個挑戰是要拋棄原有的SQL觀念,學習新的資料存取方法。


以計數器功能為例,以前要計算使用者每一次偷菜得到的蔬果數量,可以透過Select sum()語法來加總每一次偷菜所得到的數量,
但改用Cassandra以後,不能使用Select語法,程式在寫入每一筆偷菜記錄時,
也同時要將蔬果數 量加總到一個特別用來儲存總數的資料記錄中,日後直接讀取這個總數的數值就可以得知使用者偷到的蔬果數量。
等於是要自己用程式寫出計數器功能,這也意味 著,原本透過SQL語法存取資料庫的程式碼,全部要重新改寫。

完成遊戲中相關程式碼的修改後,陳彥任分階段進行導入,每個階段大約進行1個禮拜,
採取並行作業,一筆記錄同時寫入原有的MySQL資料庫和新的 Cassandra資料庫,不過,
仍舊以原有資料庫上的數據為準。先測試寫入,待寫入的過程穩定後,才進行讀取的階段,
讓遊戲同時從兩個資料庫取得數據。

讀取階段同時開始進行資料比對,確保每一個遊戲動作中產生的資料儲存在兩邊資料庫中的紀錄相同。
最後確定資料一致後,才改以Cassandra資料庫為主,原有資料庫為輔,最後結束並行作業,完成資料庫的轉移。

為了避免導入過程影響了遊戲平臺,陳彥任還寫了一個切換模組,一旦導入過程發生問題,
可以立刻切斷遊戲程式和Cassandra資料庫之間的連結,讓遊戲程式改連結到舊有的MySQL資料庫,
「透過切換機制先確保系統可以繼續運作,再來處理問題。」

除了資料存取方式改變以外,陳彥任還遇到一些SQL資料庫不會發生的資料衝突問題。
分散式資料庫會將資料複製成好幾份放到不同的伺服器中,一般常見的作法 是複製成3份。
當程式更新其中一臺伺服器中的記錄時,還需要一段時間才會同步到其他伺服器中,
這段時間差內,若有另外一支程式到還未同步資料的伺服器中讀 取記錄,就會取得不一樣的舊數據。

即使是只有2臺伺服器,同樣也會發生資料不同步的情況。陳彥任的作法是一筆資料重複讀取兩次,
或者是設定要讀取不同伺服器的資料,再相互比對,如果相同就可以使用,若不相符,
表示其中一個數據是舊版本,暫緩一點時間再重新讀取。

除了資料讀取衝突外,寫入時也會發生衝突。因為社交遊戲是多人同時進行,可能會發生2個使用者同時寫入到同一筆資料的情況,
或者是有1個人寫入資料時,另一個人正要讀取該筆資料。這也會造成兩個使用者拿到不同的資料,或者是只有其中1個人的資料成功寫入。

NoSQL資料庫會發生資料衝突或遺失
陳彥任解釋,因為NoSQL資料庫沒有SQL資料庫的「交易」(Transaction)設計,在資料異動過程中,
NoSQL資料庫不會鎖住資料來阻止其他寫入或讀取動作,所以會發生資料衝突,造成資料錯誤或遺失。
像Cassandra的設計就是採取Eventual Consistency的原則,經過一段時間資料沒有更新時,
分散的各版本資料終究會達成一致,所以,陳彥任導入Cassandra資料庫的過程中,
每天 上百萬次的資料存取總會遇到幾次資料衝突的情況,他說,
開發者必須自行解決這些原本在SQL資料庫中會自動處理的問題。

在有些情況下,使用者不會在意資料錯誤或遺失,例如Facebook的「贊」功能,
同時有2名使用者對同一張照片按下「贊」按鈕時,即使只有更新1個贊,使用者也不會查覺遺失了一個。

不過,若是與錢有關的資訊,例如購物車中的商品數量,使用者就會非常注重資料衝突或遺失的問題,
即使使用者切換不同的瀏覽視窗來下訂單,購物車中的付款金 額也不能遺失或錯誤。陳彥任認為,
像金錢這類資訊比較適合關聯式資料庫,若要使用NoSQL資料庫,就需要特別處理資料一致性的問題。

陳彥任表示,使用這類NoSQL資料庫,開發者必須熟悉這類資料庫的設計會造成哪些影響?
了解影響有多大、資料版本會多舊等問題,才能在設計系統時,讓程式可以容忍這樣的錯誤。

採用Cassandra另外還有一個風險,因為Cassandra目前只釋出了0.6版,還是一個在發展中的資料庫系統,
基本架構和功能還沒穩定。陳彥任表示,更新版本時會遇到像資料庫檔案格式調整或API功能改變的情況,
就得修改程式碼。

不過,從管理角度來看,力可科技總經理馮彥文認為Cassandra最大的優點是可以降低維護成本。
使用者貢獻比例高的網站資料量通常很大,成長速度也很 快。若要採用MySQL來滿足資料庫不斷擴充的需求,
往往每隔一段時間就要會遇到資料庫空間不足,甚至得有專人負責切割和轉移資料庫。

導入Cassandra資料庫3個月來,陳彥任認為,這是一個穩定可用的資料庫系統,
也讓力可科技能放心地推出更大規模的社交遊戲。

隨著社群網站、社交遊戲的盛行,許多網站流行提供互動式的遊戲,iPhone和Android手機帶動的行動風潮,
會讓使用者更容易貢獻自己的內容,未來 這類使用者貢獻的網站將越來越多,
NoSQL資料庫可以成為企業或網站業者建置分散式資料庫來因應海量資料的另一種選擇。

 

了解NoSQL不可不知的5項觀念 早在1998年,就已經有人提出NoSQL資料庫的概念,不過,
這項技術沒有成為主流。直到最近幾年,出現了大量使用者貢獻資料的網站,帶動了分散式資料庫的需求,
這些網站擁有大量使用者貢獻的資料,而且還不斷成長。為了滿足資料成長的擴充需求,
傳統的商用關聯式資料庫借助資料庫叢級技術才能解決,然而這 就得投資高額的軟硬體擴充經費。

網站業者為了解決如TB等級甚至是PB等級的巨量資料儲存和擴充問題,開始研發各種建置成本較低的分散式開源資料庫,
Google自行研發的 BigTable就是其中最好的例子。其他如Amazon、Yahoo近幾年也都投入這類NoSQL資料庫的研發。
甚至連微軟的Azure雲端平臺也使用 了NoSQL技術來存取資料。

同樣情況,像Facebook、Twitter、Zynga這類社交型網站為了解決龐大的使用者互動資料,
也大量使用NoSQL資料庫技術。例如Facebook開發出Cassandra資料庫,在600多個運算核心的叢集系統上,
儲存了超過120TB的站內郵件。


為了解決使用者貢獻資料快速成長的問題,Facebook開發了一套NoSQL資料庫Cassandra,
在600多個運算核心的叢集系統上,儲存了超過120TB的站內郵件資料。


 

 

 

 

 

 

 

 

 

 

在2009年,開源社群重新使用NoSQL這個名詞來代表這些分散式非關聯式資料庫的統稱。

其實,NoSQL資料庫包括十幾種資料庫系統,也很不像關聯式資料庫那樣有一套通用的基礎資料庫理論。
不過,還是有幾項了解NoSQL資料庫不可不知的關鍵,只要掌握這些關鍵,就能對NoSQL資料庫有基本的了解。

觀念 1  NoSQL是Not Only SQL
因為SQL語言是關聯式資料庫的標準查詢語言,原本NoSQL資料庫用來代表那些無法提供SQL語言查詢的資料庫系統,
這些資料庫系統大多是開源的分散式資料庫系統,不過,也有少數商用資料庫系統具有NoSQL的特性,例如微軟Azure平臺上儲存資料的方式。

今年開源社群則出現了另外一個新的定義方式,將NoSQL視為「Not Only SQL」,不只是SQL的意思,
也就是說混用關聯式資料庫和NoSQL資料庫來達成最佳的儲存效果,
例如前面舉的力可科技就是用NoSQL資料庫來儲存資 料量大的用戶狀態資料,
但其他資料仍然使用關聯式資料庫,以便善用SQL語法的好處。

觀念 2 增加機器就能自動擴充資料庫容量
NoSQL資料庫的另一個重要特性是具有水平擴充能力,只要增加新的伺服器節點,就可以不斷擴充資料庫系統的容量。
而且可以利用低價的一般等級電腦就能進 行水平擴充,不像關聯式資料庫的叢集系統往往需要效能和容量較大的伺服器才能勝任。
NoSQL資料庫可以用更低的成本打造出TB等級或PB等級的大型資料 庫系統。

有些NoSQL資料庫甚至可以在不停機或不影響應用程式的情況下,線上就能直接擴充資料庫系統的容量。

舉例來說,Cassandra可以動態擴充新的資料庫節點,只要啟動新的資料庫節點,
舊有的資料庫節點會自動將資料複製到新節點中,平衡彼此的資料存取負載。
不用像常見的資料庫切割作法那樣,必須手動進行資料庫的去正規化、切割資料表、複製資料、指定應用程式連結等過程。

簡單來說,水平擴充能力的意思就是只要增加新的伺服器設備,就能自動增加資料庫的容量,
從管理角度來看,這也可以減少長期維護資料庫的人力。

觀念 3 打破Schema欄位架構的限制
關聯式資料庫必須透過資料庫的Schema欄位架構來確立資料表之間的關聯,Schema通常是事先設計好的架構,
上線以後要進行欄位變更非常麻煩,尤其 資料量龐大時要變更Schema的難度很高,例如Twitter為了調整資料欄位,
光是執行Alter Table指令來改變資料表的定義就跑了一個禮拜。

NoSQL資料庫則是改用Key-Value資料模式來解決龐大資料的異動困難。
Key-Value模式是將一筆資料的結構簡化到只有一個Key值對應到一個Value值,
每一筆資料之間沒有關連性,所以,可以任意切割或調整,
也可以分散到不同的伺服器中建立副本。

有些NoSQL資料庫則是增加了Column的觀念,用法上等於是可以用更多的Key值來對應Value,
例如Cassandra就提供了4層或5層 Key-Value的資料結構,可以用3個Key來對應1個Value值。
例如用「使用者帳號」、「個人檔案」、「生日」這三個Key值來取得某一個用戶 的生日日期。
採用Column設計的NoSQL資料庫會比只用Key-Value資料架構的資料庫更有彈性,減少資料存取程式的開發難度。

因為NoSQL資料庫沒有Schema架構,所以,也無法支援標準的SQL語法來查詢資料。
NoSQL資料庫通常是透過簡單的API來新增、更新或刪除資 料庫中的內容,有些資料庫則會提供類似SQL語法中的Select查詢機制,
不過通常也無法執行複雜的Join指令,例如Google App Engine就提供了GQL語法讓開發者查詢BigTable上的資料。

觀念 4 資料遲早會一致
為了確保資料的完整性,關聯式資料庫採用的交易(Transaction)的設計,讓資料存取或異動過程中不會受到干擾。
Transaction資料庫的 特性就是ACID,在SQL執行過程中,確保有交易作為最小運作單位(Atomicity)、
異動過程確保整體資料庫的一致性 (Consistency)、執行多筆交易時能隔離交易中的資料不受其他交易影響(Isolation)以及交易過程不會變動原始資料的持久性 (Durability)。

但是ACID架構的資料庫擴充不易,所以,NoSQL資料庫大多沒有交易的設計,而是採用了另外一個不同的CAP資料庫理論。

CAP理論有三個關鍵,包括資料一致性(Consistent)、可用性(Availability)和中斷容忍性(Partition Tolerance)。
理論上無法同時兼顧CAP這三種特性,所以,NoSQL資料庫通常會選擇其中兩種特性來設計,通常是選擇CP或AP。

多數NoSQL資料庫選擇的是CP的設計,不過,NoSQL資料庫中談的資料一致性和關聯式資料庫的意義不同。
NoSQL資料庫會採取 Eventually Consistency(資料遲早會一致)的作法,因為NoSQL的分散式設計會將資料分散複製到不同節點中,
每個節點各自也能異動資料,然後再彼此同 步。同步過程就會有時間落差,若同時讀取不同節點上的資料,會發生資料不一致的情況。

NoSQL資料庫為了保持分散式的擴充架構,容許這樣的情況,只有保證最後資料會達到一致。
而在資料尚未同步的短暫時間內就需要開發者自行解決資料衝突或 遺失的問題,
或者是用NoSQL資料庫來記錄那些對精確度要求較低的資料,例如Facebook的贊按鈕,即使少了幾個贊的記錄,
使用者也不容易發現,就 適合用NoSQL資料庫來儲存。導入NoSQL資料庫時,開發者得先評估資料的性質,是否能承擔資料遺失的風險。

觀念 5 成熟度不足,版本升級風險高
因為近幾年Web 2.0網站和社交網站的盛行,才開始出現用NoSQL資料庫解決使用者貢獻資料的暴漲問題。
很多NoSQL資料庫都是這2、3年內才出現,所以,資料庫本身的功能還不完整,也較少出現成熟穩定的版本,
版本升級過程中很容易會出現不相容的情形。

另一方面,這類資料庫大多透過API來存取資料,新的版本若增加了新的功能,也會改變這些API的參數或呼叫方式。
對開發者而言,等於得重新修改應用程 式,才能正確取得資料庫中的內容。甚至是資料庫本身儲存的檔案格式也會變化,
升級新版本資料庫後,反而無法讀取舊版檔案,必須進行格式轉檔的工作。

找到合適的NoSQL資料庫,一方面要挑選知名網站所使用的資料庫,因為這些知名網站通常也是這些資料庫的貢獻者,
他們為了解決自身的使用問題,會比較積極地完善資料庫。

另外,還要考慮自身的技術能力以及掌握外國技術發展的學習能力,雖然NoSQL資料庫提供了另外一種低成本的分散式資料庫,
自動擴充節點的功能可以節省資料庫維護人力,但是,相對地,也須承擔技術不夠成熟時的變動風險。

 

快速認識4類主流NoSQL資料庫
早在NoSQL資料庫這個名詞流行之前,就已經出現了很多種非關聯式資料庫,
這些資料庫各有不同的特徵,很難像關聯式資料庫那樣,用一套共同的觀念就可以全部了解。
只能逐一了解每個NoSQL資料庫的特性和用途。
目前有4種比較受到關注的NoSQL資料庫,分別是
Key-Value資料庫、
記憶體資料庫(In-memory Database)、
圖學資料庫(Graph Database)、
文件資料庫(Document Database)。

類型 1 Key-Value類型的資料庫最多
Key-Value資料庫是NoSQL資料庫中最大宗的類型,這類資料最大的特色就是採用Key-Value資料架構,
取消了原本關聯式資料庫中常用的欄位架構(Schema),每筆資料各自獨立,所以,可以打造出分散式和高擴充能力的特性。

包括像Google的BigTable、Hadoop的HBase、Amazon的Dynamo、Cassandra、Hypertable等都是這類Key-Value資料庫。

Google自行研發的BigTable建置在Google檔案系統GFS上,專供Google自家應用程式使用,
例如Gmail、Google Reader、Google地圖、YouTube等應用的資料都是儲存在BigTable中。
現在Google也透過Google App Engine服務開放其他人使用BigTable來儲存資料。

BigTable就像是一張整合大量機器的資料表,所有資料都存在同一張資料表中,單個資料表可以儲存PB等級的內容。
Google App Engine提供了一種GQL查詢語言,讓開發者使用Select語法來查詢BigTable中的資料,
不過,這種GQL語言不能像SQL語言那樣可以使 用Join語法來進行跨資料表查詢。

因為Google沒有釋出BigTable和相關的雲端運算平臺,後來就出現了另外一套參考Google雲端運算架構的Hadoop平臺,
並且發展出 HBase分散式資料庫。HBase是Hadoop平臺使用的資料庫,用來儲存Hadoop進行MapReduce平行運算的資料。
類似Google的 BigTable,也是在一張大資料表中儲存很多行資料,每一行的結構同樣有一個主要Key值和任意數量的列欄位。

Amazon開發的Dynamo分散式資料庫則是用在Amazon的網路服務,例如S3儲存服務,
也是採取Key-Value的儲存方式來建立分散式的高 可用性環境。Amazon的購物車就是使用Dynamo資料庫,
Dynamo會將一份資料複製到很多伺服器上建立副本,彼此定期同步。不過,由於 Dynamo無法確保每一個副本的資料即時同步,
為了解決資料衝突和遺失的問題,Amazon另外開發了衝突解決技術來確保資料的一致性。

在Key-Value資料庫類型中,還有一個最近很熱門的NoSQL資料庫,也就是力可科技使用的Cassandra。
這是Facebook在2008年 釋出的分散式資料庫,支援Java平臺。Facebook用Cassandra來儲存高達120TB的站內信箱(inbox)資料,
2009年3月由 Apache基金會接手維護,現在是Apache重點發展的頂級計畫之一。

和HBase這種主從式架構的分散式資料庫不同,Cassandra每一個在資料庫叢集中的節點都是相同的,沒有主從關係,
所以,建置分散式資料庫 時,Cassandra最少只要建立2個伺服器節點就能執行,這兩個節點的功能和角色幾乎一模一樣,
只需要在設定檔中指定好彼此溝通的IP網址即可。啟動 資料庫以後,這兩個節點會自行複製資料、分散儲存、平衡資料庫存取的負載。

類型 2 記憶體資料庫是知名網站慣用快取工具
記憶體資料庫(In-memory Database)就是將資料儲存在記憶體的NoSQL資料庫,
包括了Memcached、Redis、Velocity、Tuple space等。其實像Memcached、Redis都是一種Key-Value資料架構的資料庫,
只是這類資料庫改將資料儲存在記憶體中來提高讀取效 率,大多用來快取常用網頁,
加快傳遞網頁的速度,減少讀取硬碟的次數,不過系統關機後就無法保存。

2003年就出現的Memcached更是許多知名網站改善網站瀏覽效率的重要工具,
例如YouTube、Facebook、Zynga、Twitter等都有使用Memcached。
Google應用代管服務App Engine也提供了Memcached的服務。

在Facebook上最熱門的Farm Ville農場遊戲就是利用Memcached來改善遊戲流暢性。
Farm Ville每天登入的使用者人數高達1千萬人,為了讓使用者操作過程不需要等待資料讀寫的延遲,
Farm Ville採取2層式的架構,使用Memcached來傳遞站上使用者的資料,稍後再整批將資料寫入後端MySQL資料庫,
儲存在硬碟上。不過,這個架構 的風險就是,系統當機時,會遺失一整批儲存在記憶體中的資料。

除了老牌的Memcached以外,2009年出現了一個新的開源記憶體資料庫Redis。
除了提供分散式的快取以外,Redis和Memcached最大的不同點是,Redis提供了一個資料架構,
可以自動排序那些儲存在Redis中的資料,讓開發者取得排序後的資料。

Redis在今年3月時獲得VMware贊助。9月剛釋出了2.0新版,新增加了如虛擬記憶體的設計,
讓開發者可以放入記憶體容量更多的資料量。美國分類廣告網站Craigslist和程式碼代管網站Github都是使用Redis來加快存取速度。

類型 3 文件資料庫適合儲存非結構化資料
文件資料庫主要是用來儲存非結構性的文件,例如最常見的非結構化資料就是HTML網頁。
一個HTML網頁結構不像一般表格那樣有固定的欄位,每個欄位有特 定資料類型和大小。
例如網頁裡有Head和Body結構,Body元素中可能會有10個段落,
段落中會有文字、連結、圖片等。文件資料庫的資料結構往往是 鬆散的樹狀結構。

很多文件資料庫都是商用資料庫系統,文件資料庫的概念源自IBM的Lotus Notes儲存文件的方式,
XML資料庫也是一種文件資料庫。常見的開源文件資料庫像是CouchDB、MongoDB以及Riak等。

隨著網頁儲存和搜尋索引的需求大增,CouchDB和MongoDB這2款文件資料庫越來越受到關注。
2005年就出現的CouchDB剛釋出了1.0 版,它也是Apache基金會維護的頂級計畫之一。
CouchDB提供了一套RESTful的API,讓應用程式透過HTTP協定就能存取資料庫,也可以 用JavaScript作為查詢語言。

2009年才出現的MongoDB很快就已經釋出穩定的1.6.1版,可以用來儲存UTF-8和非UTF-8的文件資料。
不像CouchDB只能儲存 UTF-8格式的文件。MongoDB同樣可以在查詢指令中使用JavaScript。
採取Master-Slave架構,1臺Master伺服器搭配多 臺資料伺服器,資料伺服器間互相備援、容錯。

類型 4 圖學資料庫可用於記錄社交關係
最後一類是圖學資料庫,這不是專門用來處理圖片的資料庫,而是指運用圖學架構來儲存節點間關係資料架構,
例如用樹狀結構來組織從屬關係或網狀結構來儲存朋 友關係,地理圖資系統通常也會用圖學資料庫來儲存地圖上每一點和鄰近點的關係,
或用圖學資料庫來計算點與點之間最短的距離,也可以用同樣的概念來計算出人 與人之間最短的交友距離。
圖學資料庫最大的特性是對複雜性的擴充力,關係越複雜的資料越適合使用圖學資料庫。

這類資料的資料結構沒有標準的作法,基本的圖學資料包括了節點(Node)、關係(Relation)和屬性(Property)三種結構。
例如用節點來 記錄Facebook上的帳號、用關係來記錄朋友關係、用屬性來描述這個帳號的個人資料等。
最後可以用網絡圖來呈現出Facebook用戶之間的交友狀 況。常見的圖學資料庫如Neo4j、InfoGrid、AllegroGrph等。

這四大類NoSQL資料庫是比較精簡的區分方式,可以用來快速了解不同NoSQL資料庫的特性和差異,
另外像維基百科則是從應用角度將NoSQL分成10 類,那個分類方法特別將Key-Value資料庫區分出更多不同應用類型的子分類,
也可以更進一步了解更多NoSQL資料庫的特性。