Cassandra
Apache Cassandra(社區內一般簡稱為C*)是一套開源分散式NoSQL資料庫系統。它最初由Meta開發,用於改善電子郵件系統的搜尋效能的簡單格式資料,集Google BigTable的資料模型與Amazon Dynamo的完全分散式架構於一身。Facebook於2008將 Cassandra 開源,此後,由於Cassandra良好的可延伸性和效能,被 Apple[2], Comcast[3],Instagram[4], Spotify[5], eBay[6], Rackspace[7], Netflix[8]等知名網站所採用,成為了一種流行的分散式結構化資料儲存方案。
原作者 | Avinash Lakshman、Prashant Malik |
---|---|
開發者 | Apache軟件基金會 |
首次發佈 | 2008年7月 |
目前版本 |
|
原始碼庫 | |
程式語言 | Java |
作業系統 | 跨平台 |
語言 | 英文 |
類型 | NoSQL資料庫 |
許可協定 | Apache許可證2.0 |
網站 | cassandra |
在資料庫排行榜「DB-Engines Ranking」中,Cassandra排在第十位,是非關聯型資料庫中排名第四高[9]。
歷史
Cassandra 的名稱來源於希臘神話,是特洛伊的一位悲劇性的女先知的名字,因此專案的Logo是一隻放光的眼睛。
這個專案由就職於Facebook的Avinash Lakshman(也是Amazon Dynamo的作者之一)和Prashant Malik在為Facebook的Inbox編寫。2008年,Facebook將專案開源,Cassandra在2009年成為了Apache軟件基金會的Incubator專案,並在2010年2月走出孵化器,成為正式的基金會專案。目前這個專案主要由專門進行Cassandra商業化運作的DataStax(頁面存檔備份,存於互聯網檔案館)公司來開發,也有一些來自其他公司或獨立的開發者[10]。
主要版本和主要改進[11]
- 0.6,2010年4月發佈,支援內建的快取。
- 0.7,2011年1月發佈,支援按欄建二級索引(secondary indexes)及線上修改表的結構定義
- 0.8,2011年6月發佈,支援CQL語言和零停機的線上升級
- 1.0,2011年10月發佈,支援資料壓縮,level compaction和提高讀取效能
- 1.1,2012年4月發佈,支援ssd和機械硬碟混合使用
- 1.2,2013年1月發佈,支援虛擬節點(一個機器在一致性雜湊環中擁有多個節點)、原子性的批次處理
- 2.0,2013年9月發佈,支援輕量級事務、觸發器、改進compaction效能,強制使用Java7
- 2.1,2014年9月10日發佈
- 2.2 , 2015年7月20日發佈
- 3.0 , 2015年11月11日發佈
- 3.1 , 同樣 3.10版本,使用類tick-tock發佈模式,每月發佈一次 , 偶數編號版本提供新功能和錯誤修正,而奇數編號版本只包括錯誤修正。
- 3.11 ,2017年6月23日發佈,作為穩定的3.11版本系欄,修復了上一個tick-tock功能版本的錯誤。
資料模型
Cassandra使用了Google 設計的 BigTable的資料模型,與面向列(row)的傳統的關聯型資料庫或鍵值儲存的key-value資料庫不同,Cassandra使用的是寬欄儲存模型(Wide Column Stores)[9],每列資料由row key唯一標識之後,可以有最多20億個欄[12],每個欄有一個column key標識,每個column key下對應若干value。這種模型可以理解為是一個二維的key-value儲存,即整個資料模型被定義成一個類似map<key1, map<key2,value>>的類型。
舊版的Cassandra與客戶端互動的方法是通過thrift,而目前新版本的Cassandra採用與SQL語言類似的CQL語言[13]來實現資料模型的定義和資料的讀寫。其中BigTable中的欄族(Column Family)在Cassandra中被稱作類似關聯型資料庫中的稱呼——表(table),而Cassandra/BigTable中的row key和column key並稱為主鍵(primary key)。[14]
Cassandra的row key決定了該列資料儲存在哪些節點中,因此row key需要按雜湊來儲存,不能順序的掃描或讀取,而一個row內的column key是順序儲存的,可以進行有序的掃描或範圍尋找[14]。
儲存模型
與BigTable和其模仿者HBase不同,Cassandra的資料並不儲存在分散式檔案系統如GFS或HDFS中,而是直接存於本地。與BigTable一樣,Cassandra也是紀錄檔型資料庫,即把新寫入的資料儲存在主記憶體的Memtable中並通過磁碟中的CommitLog來做持久化,主記憶體填滿後將資料按照key的順序寫進一個唯讀檔案SSTable中,每次讀取資料時將所有SSTable和主記憶體中的資料進行尋找和合併[15][16]。這種系統的特點是寫入比讀取更快[17],因為寫入一條資料是順序計入commit log中,不需要隨機讀取磁碟以及搜尋。
分散式架構
Cassandra的系統架構與Dynamo類似,是基於一致性雜湊的完全P2P架構,每列資料通過雜湊來決定應該存在哪個或哪些節點中[18]。叢集沒有master的概念,所有節點都是同樣的角色,徹底避免了整個系統的單點問題導致的不穩定性,叢集間的狀態同步通過Gossip協定來進行P2P的通訊。每個節點都把資料儲存在本地,每個節點都接受來自客戶端的請求。每次客戶端隨機選擇叢集中的一個節點來請求資料,對應接受請求的節點將對應的key在一致性雜湊的環上定位是哪些節點應該儲存這個資料,將請求轉發到對應的節點上,並將對應若干節點的查詢反饋返回給客戶端。
在一致性、可用性和分區耐受能力(CAP)的折衷問題上,Cassandra和Dynamo一樣比較靈活。Cassandra的每個keyspace可組態一列資料會寫入多少個節點(設這個數為N),來保證資料不因為機器宕機或磁碟損壞而遺失資料,即保證了CAP中的P。用戶在讀寫資料時可以指定要求成功寫到多少個節點才算寫入成功(設為W),以及成功從多少個節點讀取到了資料才算成功(設為R)。可推理得出,當W+R>N時,讀到的資料一定是上一次寫入的,即維護了強一致性,確保了CAP中的C。當W+R<=N時,資料是最終一致性因為存在一段時間可能讀到的並不是最新版的資料。當W=N或R=N時,意味着系統只要有一個節點無響應或宕機,就有一部分資料無法成功寫或者讀,即失去了CAP中的可用性A。因此,大多數系統中,都將N設為3,W和R設為QUORUM,即「過半數」——在N為3時QUORUM是2。
支援的操作
Cassandra支援對一欄資料進行insert、update、或delete操作。其中insert和update雖然語法略有區別,但語意上等價,即可以針對已經存在的列進行update或insert一個不存在的列。
輕量級事務
從2.0版開始,Cassandra支援輕量級事務。這種事務被稱為「compare-and-set」,簡稱CAS。通過paxos演算法實現在滿足某條件後才修改資料否則不修改。目前支援"insert if not exist"、"update if col=value"、"delete if exist"等幾種操作。
資料類型
Cassandra在CQL語言層面支援多種資料類型[19]。
CQL類型 | 對應Java類型 | 描述 |
---|---|---|
ascii | String | ascii字串 |
bigint | long | 64位元整數 |
blob | ByteBuffer/byte[] | 二進制陣列 |
boolean | boolean | 布林 |
counter | long | 計數器,支援原子性的增減,不支援直接賦值 |
decimal | BigDecimal | 高精度小數 |
double | double | 64位元浮點數 |
float | float | 32位元浮點數 |
inet | InetAddress | ipv4或ipv6協定的ip地址 |
int | int | 32位元整數 |
list | List | 有序的列表 |
map | Map | 鍵值對 |
set | Set | 集合 |
text | String | utf-8編碼的字串 |
timestamp | Date | 日期 |
uuid | UUID | UUID類型 |
timeuuid | UUID | 時間相關的UUID |
varchar | string | text的別名 |
varint | BigInteger | 高精度整型 |
與類似開源系統的比較
Apache HBase
HBase是Apache Hadoop專案的一個子專案,是Google BigTable的一個克隆,與Cassandra一樣,它們都使用了BigTable的欄族式的資料模型,但是:
- Cassandra只有一種節點,而HBase有多種不同角色,除了處理讀寫請求的region server之外,其架構在一套完整的HDFS分散式檔案系統之上,並需要ZooKeeper來同步叢集狀態,部署上Cassandra更簡單。
- Cassandra的資料一致性策略是可組態的,可選擇是強一致性還是效能更高的最終一致性;而HBase總是強一致性的。
- Cassandra通過一致性雜湊來決定一列資料儲存在哪些節點,靠概率上的平均來實現負載均衡;而HBase每段資料(region)只有一個節點負責處理,由master來動態分配一個region是否大到需要拆分成兩個,同時會將過熱的節點上的一些region動態的分配給負載較低的節點,因此實現動態的負載均衡。
- 因為每個region同時只能有一個節點處理,一旦這個節點無響應,在系統將這個節點的所有region轉移到其他節點之前這些資料便無法讀寫,加上master也只有一個節點,備用master的恢復也需要時間,因此HBase在一定程度上有單點問題;而Cassandra無單點問題。
- Cassandra的讀寫效能優於HBase[17]。
參考文獻
- ^ https://github.com/apache/cassandra/releases/tag/cassandra-5.0.2.
- ^ PlanetCassandra, Apple Inc.: Cassandra at Apple for Massive Scale, 2015-03-03 [2016-06-27], (原始內容存檔於2016-03-24)
- ^ Comcast messaging infrastructure chooses linearly scaling Apache Cassandra as NoSQL solution. www.planetcassandra.org. [2016-06-27]. (原始內容存檔於2016-06-26).
- ^ Facebook’s Instagram: Making the Switch to Cassandra from Redis, a 75% ‘Insta’ Savings. planetcassandra.org. [2016-06-27]. (原始內容存檔於2016-07-02).
- ^ Spotify scales to the top of the charts with Apache Cassandra at 40k requests/second. planetcassandra.org. [2016-06-27]. (原始內容存檔於2016-07-18).
- ^ PlanetCassandra, eBay: Apache Cassandra Best Practices at Ebay, 2014-10-10 [2016-06-27], (原始內容存檔於2017-03-29)
- ^ Rackspace Monitors the Cloud with Cassandra: 35 Million Writes, 180 Million Samples per Hour. 2013-10-08 [2016-06-27]. (原始內容存檔於2014-04-03).
- ^ Case Study: Netflix. DataStax. [2016-06-27]. (原始內容存檔於2016-06-18).
- ^ 9.0 9.1 DB-Engines Ranking. 2016-06-27 [2014-08-17]. (原始內容存檔於2020-02-21).
- ^ Cassandra Committers. [2014-08-17]. (原始內容存檔於2014-08-19).
- ^ Cassandra Changes. [2014-08-17]. (原始內容存檔於2010-05-27).
- ^ CassandraLimitations. [2014-08-17]. (原始內容存檔於2014-08-18).
- ^ Cassandra Query Language (CQL) v2.0. 2014-08-18 [2014-08-17]. (原始內容存檔於2014-08-15).
- ^ 14.0 14.1 cql document. [2014-08-17]. (原始內容存檔於2014-08-19).
- ^ Bigtable: A Distributed Storage System for Structured Data (PDF). [2014-08-17]. (原始內容存檔 (PDF)於2014-07-23).
- ^ MemtableSSTable. [2014-08-17]. (原始內容存檔於2014-08-19).
- ^ 17.0 17.1 nosql-performance-benchmarks. [2014-08-17]. (原始內容存檔於2014-09-07).
- ^ Amazon. Dynamo: Amazon’s Highly Available Key-value Store (PDF). [2014-08-17]. (原始內容 (PDF)存檔於2011-03-04).
- ^ cql data types. [2014-08-18]. (原始內容存檔於2014-09-29).