Cassandra

Apache Cassandra（社群內一般簡稱為 C*）是一套開源分散式 NoSQL 資料庫系統。它最初由 Meta 開發，用於改善電子郵件系統的搜尋效能的簡單格式資料，集 Google BigTable 的資料模型與 Amazon Dynamo 的完全分散式架構於一身。Facebook 於 2008 將 Cassandra 開源，此後，由於 Cassandra 良好的可擴充套件性和效能，被Apple,Comcast,Instagram,Spotify,eBay,Rackspace,Netflix 等知名網站所採用，成為了一種流行的分散式結構化資料儲存方案。

在資料庫排行榜 “DB-Engines Ranking” 中，Cassandra 排在第十位，是非關係型資料庫中排名第四高。

歷史

Cassandra 的名稱來源於希臘神話，是特洛伊的一位悲劇性的女先知的名字，因此專案的 Logo 是一隻放光的眼睛。

這個專案由就職於 Facebook 的 Avinash Lakshman（也是 Amazon Dynamo 的作者之一）和 Prashant Malik 在為 Facebook 的 Inbox 編寫。2008 年，Facebook 將專案開源，Cassandra 在 2009 年成為了 Apache 軟體基金會的 Incubator 專案，並在 2010 年 2 月走出孵化器，成為正式的基金會專案。目前這個專案主要由專門進行 Cassandra 商業化運作的 DataStax 公司來開發，也有一些來自其他公司或獨立的開發者。

1.1 主要版本和主要改進

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)，每行資料由 row key 唯一標識之後，可以有最多 20 億個列，每個列有一個 column key 標識，每個 column key 下對應若干 value。這種模型可以理解為是一個二維的 key-value 儲存，即整個資料模型被定義成一個類似 map > 的型別。

舊版的 Cassandra 與客戶端互動的方法是透過 thrift，而目前新版本的 Cassandra 採用與 SQL 語言類似的 CQL 語言來實現資料模型的定義和資料的讀寫。其中 BigTable 中的列族 (Column Family) 在 Cassandra 中被稱作類似關係型資料庫中的稱呼 —— 表 (table)，而 Cassandra/BigTable 中的 row key 和 column key 並稱為主鍵 (primary key)。

Cassandra 的 row key 決定了該行資料儲存在哪些節點中，因此 row key 需要按雜湊來儲存，不能順序的掃描或讀取，而一個 row 內的 column key 是順序儲存的，可以進行有序的掃描或範圍查詢。

儲存模型

與 BigTable 和其模仿者 HBase 不同，Cassandra 的資料並不儲存在分散式檔案系統如 GFS 或 HDFS 中，而是直接存於本地。與 BigTable 一樣，Cassandra 也是日誌型資料庫，即把新寫入的資料儲存在記憶體的 Memtable 中並透過磁碟中的 CommitLog 來做持久化，記憶體填滿後將資料按照 key 的順序寫進一個只讀檔案 SSTable 中，每次讀取資料時將所有 SSTable 和記憶體中的資料進行查詢和合並。這種系統的特點是寫入比讀取更快，因為寫入一條資料是順序計入 commit log 中，不需要隨機讀取磁碟以及搜尋。

分散式架構

Cassandra 的系統架構與 Dynamo 類似，是基於一致性雜湊的完全 P2P 架構，每行資料透過雜湊來決定應該存在哪個或哪些節點中。叢集沒有 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 一個不存在的行。

5.1 輕量級事務

從 2.0 版開始，Cassandra 支援輕量級事務。這種事務被稱為 “compare-and-set”，簡稱 CAS。透過 paxos 演算法實現在滿足某條件後才修改資料否則不修改。目前支援 "insert if not exist"、"update if col=value"、"delete if exist" 等幾種操作。

資料型別

Cassandra 在 CQL 語言層面支援多種資料型別。

與類似開源系統的比較

7.1 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。

相關閱讀