Cassandra NoSQL資料庫簡介
Cassandra整體架構
Cassandra主要有下面這些元件組成:
- Node
Node用於存放資料,是Cassandra的基礎單元; - Data Center
多個Node集合組成一個Data Center; - Cluster
多個Data Center形成一個Cluster; - Commit Log
每次寫操作都會記錄到Commit Log中,用於資料恢復 - Mem-table
Commit Log記錄完之後,會將資料寫到Mem-table中,Mem-table是一個記憶體緩衝區。 - SSTables
當Mem-table中的資料到達一定量之後會將資料寫入到磁碟中的SSTables檔案集合中。
Cassandra的資料模型
Keyspace是Cassandra中最外層的數容器,一個Keyspace包含多個 Column families
,一個 Column families
中包含多個 row
,一個 row
中包含多個 column
, column
是Cassandra最基本的資料結構,一個 column
中包含三個值:鍵、值和時間戳。
Cassandra資料備份
Cassandra有兩種備份策略:
- SimpleStrategy
用於只部署了一個資料中心的場景,首先由一致性雜湊演算法計算得到資料塊的存放位置,然後根據配置的備份數量,順時針查詢Node,將剩餘的備份依次存入查詢到的Node中。 - NetworkTopologyStrategy
用於部署了多個數據中心的場景,可以單獨設定每個資料中心的備份數量,資料中心內採用順時針查詢機架,將剩餘的備份依次存入查詢到的機架中(一個機架中可以有多個Node,此策略可以保證資料備份不在同一個機架中)。
Cassandra寫操作
因為Cassandra是無主結構,所以客戶端可以連線到任何一個Node上,被連線的這個Node稱為 coordinator
, coordinator
負責處理此客戶端的所有請求。
Consistency level
用於指定多少個Node返回寫成功之後, coordinator
給客戶端返回成功。例如:當備份數量設定為3, Consistency level
設定為1時,寫請求會分發到三個Node上, 只要有一個Node返回寫成,則 coordinator
給客戶端返回成功。
寫請求在Node內部的實現步驟:首先會提交Commit Log記錄,然後將資料寫到Mem-table快取中。Mem-table中的資料重新整理到磁碟SSTable的時機:
- Mem-table分配的記憶體空間被寫滿
- Mem-table在記憶體中的存放時間超過了限制
- 使用者手動重新整理
SSTables儲存格式
Mem-table中的資料每次重新整理都會建立一個新的SSTables,並且對同一份資料的修改也是通過增加一份資料,而不是修改原有資料來實現的。 所以一份資料可能存在多個SSTables中,並且需要其他工具來輔助讀操作(這也是為什麼cassandra適用於寫多讀少的場景)。 Cassandra會定期合併SSTables並刪除舊的資料,這種操作叫做壓縮:首先收集同一個row key所有版本的資料,然後對比column資料中的版本號(時間戳),使用最新的版本號合併為一個最新的資料集, 這樣可以增加讀效能,避免在讀操作時掃描所有SSTable表。
對於每個SSTable有下面這些結構與之對應:
- Data(Data.db)
實際存放資料的表 - Primary Index(Index.db)
raw key的索引,儲存著對應資料在Data.db檔案中的位置 - Bloom filter (Filter.db)
此表存放在記憶體中,用於檢查資料是否在對應的SSTable中,這樣可以減少對SSTable的磁碟訪問。 - Compression Information (CompressionInfo.db)
包含未壓縮資料的長度,塊偏移和其他有關壓縮資訊的資料。 - Statistics (Statistics.db)
有關於SSTable內容的統計資料 - Digest (Digest.crc32, Digest.adler32, Digest.sha1)
A file holding adler32 checksum of the data file - CRC (CRC.db)
A file holding the CRC32 for chunks in an a uncompressed file. - SSTable Index Summary (SUMMARY.db)
A sample of the partition index stored in memory - SSTable Table of Contents (TOC.txt)
A file that stores the list of all components for the SSTable TOC - Secondary Index (SI_.*.db)
Built-in secondary index. Multiple SIs may exist per SSTable
Cassandra讀操作
讀操作和寫操作類似,也是其中一個Node當作 coordinator
,根據備份數量和 Consistency level
來確定多少個備份返回成功,就視為請求成功。 如果不同備份返回的資料版本號不一致, coordinator
會返回最新的版本給客戶端,然後傳送一個讀修復命令給儲存有舊資料的Node,觸發他們同步更新資料。
讀請求在Node內部的實現步驟,查詢所有SSTable,將該row key的資料全部找出來,然後做合併操作:
- 在memtable中查詢
- 如果開啟了row cache功能,在row cache中查詢
- 在Bloom filter中查詢
- 如果開啟了partition key cache功能,在partition key cache中查詢
- 如果在partition key cache找到則直接訪問compression offset map,如果沒有找到則到partition summary中查詢
- 使用compression offset map載入磁碟資料
- 獲取SSTable中的指定資料
Node之間的通訊協議Gossip
Gossip是用來在Cassandra叢集中的各個結點之間傳輸結點狀態的協議。它每秒都將執行一次,並將當前Cassandra結點的狀態以及其所知的其它結點的狀態與至多三個其它結點交換。通過這種方法,Cassandra的有效結點能很快地瞭解當前叢集中其它結點的狀態。同時這些狀態資訊還包含一個時間戳,以允許Gossip判斷到底哪個狀態是更新的狀態。
除了在叢集中的各個結點之間交換各結點的狀態之外,Gossip還需要能夠應對對叢集進行操作的一系列動作。這些操作包括結點的新增,移除,重新加入等。為了能夠更好地處理這些情況,Gossip提出了一個叫做Seed Node的概念。其用來為各個新加入的結點提供一個啟動Gossip交換的入口。在加入到Cassandra叢集之後,新結點就可以首先嚐試著跟其所記錄的一系列Seed Node交換狀態。這一方面可以得到Cassandra叢集中其它結點的資訊,進而允許其與這些結點進行通訊,又可以將自己加入的資訊通過這些Seed Node傳遞出去。由於一個結點所得到的結點狀態資訊常常被記錄在磁碟等持久化組成中,因此在重新啟動之後,其仍然可以通過這些持久化後的結點資訊進行通訊,以重新加入Gossip交換。而在一個結點失效的情況下,其它結點將會定時地向該結點發送探測訊息,以嘗試與其恢復連線。但是這會為我們永久地移除一個結點帶來麻煩:其它Cassandra結點總覺得該結點將在某一時刻重新加入叢集,因此一直向該結點發送探測資訊。此時我們就需要使用Cassandra所提供的結點工具了。
參考:
ofollow,noindex" target="_blank">Cassandra Architecture Apache Cassandra Architecture Data replication How is data read? How is data maintained? How is data written? Cassandra - Data Model Cassandra簡介