<code>Cassandra是一個分佈式、高可擴展的數據庫,用戶可以創建線上應用程序,實時處理大量數據。 Apache Spark是應用於Hadoop集群的處理引擎,在內存條件下可以為Hadoop加速100倍,在磁盤上運行時也能實現十倍的加速。Spark還提供SQL、流數據處理、機器學習和圖型計算等功能。 Cassandra與Spark的結合,讓端到端的分析工作流的實現更為容易。另外,交易型數據庫的分析性能也能得到很大的提升,企業可以更快地響應客戶需求。 對於需要向客戶提供實時推薦和個性化的在線體驗的公司,Cassandra與Spark的結合堪稱福音。/<code>
<code>Hadoop擴展性有餘,實時性不足。Storm這樣的實時流處理框架,但它只有處理固定的流程時才具有優勢,彈性查詢能力欠佳。 現在Ooyala正在運行的就是Spark/Cassandra架構/<code>
1. Cassandra
NoSQL數據庫的選擇之痛,目前市面上有近150多種NoSQL數據庫,如何在這麼龐雜的隊伍中選中適合業務場景的佼佼者,實非易事。
好的是經過大量的篩選,大家比較肯定的幾款NoSQL數據庫分別是HBase、MongoDB和Cassandra。
Cassandra在哪些方面吸引住了大量的開發人員呢?下面僅做一個粗略的分析。
1.1 高可靠性
Cassandra採用gossip作為集群中結點的通信協議,該協議整個集群中的節點都處於同等地位,沒有主從之分,這就使得任一節點的退出都不會導致整個集群失效。
Cassandra和HBase都是借鑑了Google BigTable的思想來構建自己的系統,但Cassandra另一重要的創新就是將原本存在於文件共享架構的p2p(peer to peer)引入了NoSQL。
P2P的一大特點就是去中心化,集群中的所有節點享有同等地位,這極大避免了單個節點退出而使整個集群不能工作的可能。
與之形成對比的是HBase採用了Master/Slave的方式,這就存在單點失效的可能。
1.2 高可擴性
隨著時間的推移,集群中原有的規模不足以存儲新增加的數據,此時進行系統擴容。Cassandra級聯可擴,非常容易實現添加新的節點到已有集群,操作簡單。
1.3 最終一致性
分佈式存儲系統都要面臨CAP定律問題,任何一個分佈式存儲系統不可能同時滿足一致性(consistency),可用性(availability)和分區容錯性(partition tolerance)。
Cassandra是優先保證AP,即可用性和分區容錯性。
Cassandra為寫操作和讀操作提供了不同級別的一致性選擇,用戶可以根據具體的應用場景來選擇不同的一致性級別。
1.4 高效寫操作
寫入操作非常高效,這對於實時數據非常大的應用場景,Cassandra的這一特性無疑極具優勢。
數據讀取方面則要視情況而定:
- 如果是單個讀取即指定了鍵值,會很快的返回查詢結果。
- 如果是範圍查詢,由於查詢的目標可能存儲在多個節點上,這就需要對多個節點進行查詢,所以返回速度會很慢
- 讀取全表數據,非常低效。
1.5 結構化存儲
Cassandra是一個面向列的數據庫,對那些從RDBMS方面轉過來的開發人員來說,其學習曲線相對平緩。
Cassandra同時提供了較為友好CQL語言,與SQL語句相似度很高。
1.6 維護簡單
從系統維護的角度來說,由於Cassandra的對等系統架構,使其維護操作簡單易行。如添加節點,刪除節點,甚至於添加新的數據中心,操作步驟都非常的簡單明瞭。
參考資料
- 1.http://cassandra.apache.org
- 2.http://www.datastax.com/doc
- 3.http://planetcassandra.org/documentation/
2. Cassandra數據模型
2.1 單表查詢
2.1.1 單表主鍵查詢
在建立個人信息數據庫的時候,以個人身份證id為主鍵,查詢的時候也只以身份證為關鍵字進行查詢,則表可以設計成為:
<code>create table person ( userid text primary key, fname text, lname text, age int, gender int);/<code>
Primary key中的第一個列名是作為Partition key。也就是說根據針對partition key的hash結果決定將記錄存儲在哪一個partition中,如果不湊巧的情況下單一主鍵導致所有的hash結果全部落在同一分區,則會導致該分區數據被撐滿。
解決這一問題的辦法是通過組合分區鍵(compsoite key)來使得數據儘可能的均勻分佈到各個節點上。
舉例來說,可能將(userid,fname)設置為複合主鍵。那麼相應的表創建語句可以寫成
<code>create table person ( userid text, fname text, lname text, gender int, age int, primary key((userid,fname),lname); ) with clustering order by (lname desc);/<code>
稍微解釋一下primary key((userid, fname),lname)的含義:
- 其中(userid,fname)稱為組合分區鍵(composite partition key)
- lname是聚集列(clustering column)
- ((userid,fname),lname)一起稱為複合主鍵(composite primary key)
2.1.2 單表非主鍵查詢
如果要查詢表person中具有相同的first name的人員,那麼就必須針對fname創建相應的索引,否則查詢速度會非常緩慢。
Create index on person(fname);
Cassandra目前只能對錶中的某一列建立索引,不允許對多列建立聯合索引。
2.2 多表關聯查詢
Cassandra並不支持關聯查詢,也不支持分組和聚合操作。
那是不是就說明Cassandra只是看上去很美其實根本無法解決實際問題呢?答案顯然是No,只要你不堅持用RDBMS的思路來解決問題就是了。
比如我們有兩張表,一張表(Departmentt)記錄了公司部門信息,另一張表(employee)記錄了公司員工信息。顯然每一個員工必定有歸屬的部門,如果想知道每一個部門擁有的所有員工。如果是用RDBMS的話,SQL語句可以寫成:
<code>select * from employee e , department d where e.depId = d.depId;/<code>
要用Cassandra來達到同樣的效果,就必須在employee表和department表之外,再創建一張額外的表(dept_empl)來記錄每一個部門擁有的員工信息。
<code>Create table dept_empl ( deptId text,/<code>
看到這裡想必你已經明白了,在Cassandra中通過數據冗餘來實現高效的查詢效果。將關聯查詢轉換為單一的表操作。
2.3 分組和聚合
在RDBMS中常見的group by和max、min在Cassandra中是不存在的。
如果想將所有人員信息按照姓進行分組操作的話,那該如何創建數據模型呢?
<code>Create table fname_person ( fname text, userId text, primary key(fname) );/<code>
2.4 子查詢
Cassandra不支持子查詢,下圖展示了一個在MySQL中的子查詢例子:
要用Cassandra來實現,必須通過添加額外的表來存儲冗餘信息。
<code>Create table office_empl ( officeCode text, country text, lastname text, firstname, primary key(officeCode,country)); create index on office_empl(country);/<code>
2.5 小結
總的來說,在建立Cassandra數據模型的時候,要求對數據的讀取需求進可能的清晰,然後利用反範式的設計方式來實現快速的讀取,原則就是以空間來換取時間。