Cassandra是雲原生和微服務化場景中最好的NoSQL資料庫。我信了~ 1. Cassandra是什麼 高可用性和可擴展的分散式資料庫 Apache Cassandra™是一個開源分散式數據,可提供當今最苛刻的應用程式所需的高可用性、高性能和線性可伸縮性。它提供了跨雲服務提供商、數據中心和地理位 ...
Cassandra是雲原生和微服務化場景中最好的NoSQL資料庫。我信了~
1. Cassandra是什麼
高可用性和可擴展的分散式資料庫
Apache Cassandra™是一個開源分散式數據,可提供當今最苛刻的應用程式所需的高可用性、高性能和線性可伸縮性。它提供了跨雲服務提供商、數據中心和地理位置的操作簡便性和輕鬆的複製,並且可以在混合雲環境中每秒處理PB級信息和數千個併發操作。
在Hadoop關聯的項目中對Cassandra的解釋是:A scalable multi-master database with no single points of failure.
可以看出,高可用性和高可伸縮性是Cassandra最閃亮的特點。沒有單點故障。
2. Cassandra vs. MongoDB vs. Couchbase vs. HBase
Apache Cassandra™在高負載下提供了更高的性能,在許多用場景中都超過了它的NoSQL資料庫競爭對手。
Apache Cassandra: 高度可伸縮、高性能的分散式資料庫,設計用於處理許多商用伺服器上的大量數據,提供高可用性,沒有單點故障。
Apache HBase: 基於谷歌的BigTable的開源、非關係型、分散式資料庫,是用Java編寫的。它是Apache Hadoop項目的一部分,在HDFS上運行,為Hadoop提供類似於BigTable的功能。
MongoDB: 跨平臺的面向文檔的資料庫系統,避開了傳統的基於表的關係資料庫結構,轉而使用具有動態模式的類JSON文檔,從而使數據在某些類型的應用程式中的集成更加容易和快捷。
Couchbase: 為互動式應用程式優化的分散式NoSQL面向文檔的資料庫。
3. 架構簡介
Cassandra被設計用來處理跨多個節點的大數據工作負載,沒有單點故障。Cassandra通過採用跨同構節點的對等分散式系統來解決故障問題,其中數據分佈在集群中的所有節點中。每個節點使用點對點gossip通信協議頻繁地交換自己和集群中其他節點的狀態信息。每個節點上按順序寫入的提交日誌被捕獲寫入活動,以確保數據的持久性。然後,數據被編入索引並寫入記憶體結構,稱為memtable,它類似於回寫緩存。每次記憶體結構滿了,數據就被寫到一個SSTables數據文件的磁碟上。所有寫操作都會自動分區併在整個集群中複製。Cassandra定期使用一個稱為壓縮的進程合併SSTables,丟棄用tombstone標記為要刪除的過時數據。為了確保集群中的所有數據保持一致,需要使用各種修複機制。
Cassandra是一個分區的行存儲資料庫,其中行被組織成具有所需主鍵的表。Cassandra的體繫結構允許任何授權用戶連接到任何數據中心中的任何節點,並使用CQL語言訪問數據。為了易於使用,CQL使用與SQL類似的語法並處理表數據。通常,集群中的每個應用程式都有一個鍵空間,由許多不同的表組成。
客戶端讀或寫請求可以發送到集群中的任何節點。當客戶端使用請求連接到某個節點時,該節點充當該特定客戶端操作的協調器。協調器充當客戶端應用程式和擁有所請求數據的節點之間的代理。協調器根據集群的配置方式確定環形中的哪些節點應該獲得請求。
3.1. 核心結構
• Node
存儲數據的地方。它是Cassandra的基礎設施組件
• datacenter
相關節點的集合。數據中心可以是物理數據中心,也可以是虛擬數據中心。不同的工作負載應該使用單獨的數據中心,無論是物理的還是虛擬的。複製由數據中心設置。使用單獨的數據中心可以防止Cassandra事務受到其他工作負載的影響,並使請求彼此接近以降低延遲。根據複製因數,可以將數據寫入多個數據中心。數據中心絕不能跨越物理位置。
• Cluster
一個集群包含一個或多個數據中心。它可以跨越物理位置。
• Commit log
為了持久性,所有數據寫入之前都要首先寫入提交日誌(日誌寫入優先)。所有數據都刷新到SSTables之後,就可以對其進行歸檔、刪除或回收。
• SSTable(Sorted String Table)
一個SSTable是一個不可變的數據文件,Cassandra定期將memtables寫入其中。僅追加SSTables並按順序存儲在磁碟上,併為每個Cassandra表維護SSTables。
• CQL Table
按表行獲取的有序列的集合。一張表由多列組成,並且有一個主鍵。
3.2. 核心組件
• Gossip
一種對等通信協議,用於發現和共用Cassandra集群中其他節點的位置和狀態信息。Gossip息也由每個節點本地保存,以便在節點重新啟動時立即使用。
• Partitioner
分區程式確定哪個節點將接收一段數據的第一個副本,以及如何跨集群中的其他節點分發其他副本。每一行數據都由一個主鍵唯一地標識,主鍵可能與其分區鍵相同,但也可能包含其他集群列。Partitioner是一個哈希函數,它從一行的主鍵派生標記。分區程式使用令牌值來確定集群中的哪些節點接收該行的副本。Murmur3Partitioner是新Cassandra集群的預設分區策略,幾乎在所有情況下都是新集群的正確選擇。
• Replication factor
整個集群中的副本總數。副本因數1表示在一個節點上每一行只有一個副本。副本因數2表示每一行有兩個副本,其中每個副本位於不同的節點上。所有的副本都同樣重要,沒有主副本。你可以為每個數據中心定義副本因數。通常,應該將副本策略設置為大於1,但不超過集群中的節點數。
• Replica placement strategy
Cassandra將數據的副本存儲在多個節點上,以確保可靠性和容錯能力。副本策略決定將副本放在哪個節點上。數據的第一個副本就是第一個副本,它在任何意義上都不是唯一的。強烈建議使用NetworkTopologyStrategy策略,因為在將來需要擴展時,可以輕鬆擴展到多個數據中心。創建keyspace時,必須定義副本放置策略和所需的副本數。
• Snitch
snitch將一組機器定義為數據中心和機架(拓撲),副本策略使用這些數據中心和機架放置副本。
在創建集群時,必須配置一個snitch。所有的snitch都使用一個動態的snitch層,該層監視性能並選擇最佳副本進行讀取。它是預設啟用的,建議在大多數部署中使用。在cassandra.yaml配置文件中為每個節點配置動態snitch閾值。
• cassandra.yaml
用於設置集群的初始化屬性、表的緩存參數、調優和資源利用率的屬性、超時設置、客戶端連接、備份和安全性的主要配置文件。
4. 安裝
將Cassandra倉庫添加到yum源中
新建文件/etc/yum.repos.d/cassandra.repo 並粘貼以下內容:
[cassandra] name=Apache Cassandra baseurl=https://downloads.apache.org/cassandra/redhat/311x/ gpgcheck=1 repo_gpgcheck=1 gpgkey=https://downloads.apache.org/cassandra/KEYS
執行yum install命令:
yum install cassandra
安裝完以後就是cassandra服務了
# 啟動服務
service cassandra start|status|stop
systemctl start|status|stop cassandra
# 開機啟動
chkconfig cassandra on
命令行直接輸入cqlsh即可連接到本地cassandra資料庫,就像直接輸入mysql回車一樣
5. 數據分區
Apache Cassandra是一個開源的分散式NoSQL資料庫。它提供了具有最終一致語義的分區寬列存儲模型。
Cassandra的設計目標:
- 完全多主資料庫副本
- 低延遲的全局可用性
- 擴展到商用硬體
- 每增加一個處理器,線性吞吐量就會增加
- 線上負載平衡和集群增長
- 分區key-oriented查詢
- 靈活的schema
Apache Cassandra依賴於Amazon Dynamo分散式存儲鍵值系統的多種技術。Dynamo系統的每個節點有三個主要組成部分:
- 在分區數據集上請求協調
- 環的成員和故障檢測
- 一個本地存儲引擎
Cassandra主要使用前兩個集群組件,同時使用基於日誌結構合併樹(LSM)的存儲引擎。特別地,Cassandra使用Dynamo風格:
- 使用一致哈希的數據集分區
- 使用版本化數據和可調一致性的多主(multi-master)複製
- 通過gossip協議進行分散式集群成員和故障檢測
- 商用硬體的增量橫向擴展
Cassandra以這種方式設計,可以滿足大規模(PB級數據)關鍵業務存儲要求。
Cassandra不僅吸收了Dynamo論文中的如何做分散式,如何做副本複製,故障容錯等方面成功的經驗,又吸取了Google Bigtable中的LSM單機引擎層面精華。理論扎實,工程實現靠譜,所以面世以來,不斷受到人們的追捧。
5.1. 數據集分區:一致性哈希
Cassandra通過使用哈希函數對存儲在系統中的所有數據進行分區來實現水平可伸縮性。每個分區被覆制到多個物理節點,通常跨機架甚至數據中心。
使用一個令牌環的一致性哈希
Cassandra將每個節點映射到連續哈希環上的一個或多個token(令牌),並通過將key哈希到環上然後沿一個方向“遍歷”環來決定key應該放在什麼位置,類似於Chord演算法。一致性哈希與原始數據哈希的主要區別在於,當要哈希到的節點(桶)數量發生變化時,一致哈希只需移動一小部分key。
例如,如果我們有一個8個節點的集群,每個節點都有均勻間隔的token(令牌),並且副本因數(RF)為3,那麼要找到一個key的所屬節點,我們首先對該key進行哈希以生成一個token(即key的hash),然後沿順時針方向“walk”(走,遍歷),直到遇到三個不同的節點,這時我們找到了該key的所有副本。這個過程可以用下圖表示:
每個物理節點有多個令牌
如果你許多物理節點來分散數據,則簡單的單令牌一致哈希可以很好地工作。但是如果令牌間隔均勻而物理節點數量很少,此時如果新增一個節點的話就沒有令牌可選,以使環保持平衡。Cassandra試圖避免令牌不平衡,因為令牌範圍不均衡會導致請求負載不均衡。 例如,在前面的示例中,無法在不引起不平衡的情況下添加第九個令牌。
Dynamo論文中提倡使用“虛擬節點”來解決這種不平衡問題。虛擬節點通過將令牌環中的多個令牌分配給每個物理節點來解決該問題。通過允許單個物理節點在環中占據多個位置,我們可以使小型集群看起來更大,因此即使添加單個物理節點,我們也可以使其看起來像我們添加了更多節點。
Cassandra引入了一些術語來處理這些概念:
- Token:dynamo風格的哈希環上的單個位置
- Endpoint:網路上的單個物理IP和埠
- Host ID:單個“物理”節點的唯一標識符,通常存在於一個端點並包含一個或多個令牌
- Virtual Node:哈希環上的一個令牌,由具有相同的主機ID的相同的物理節點擁有
從Tokens到Endpoints的映射形成了Token Map,Cassandra以此來會跟蹤哪些環位置映射到哪些物理端點。
例如,在下圖中,通過為每個節點分配兩個令牌,我們可以僅使用4個物理節點來表示8個節點的集群:
說了這麼多,什麼意思呢?簡單的回顧一下:
token代表哈希環(hash ring)上的一個位置,這這個環上,兩個token之間有一個區間範圍,這也是key的範圍或者理解為哈希值的區間範圍。從token到node的映射被稱之為Token Map。
上面第一幅圖中,描述的是假設你有足夠的物理機,再假設副本因數是3,那麼1節點對應1個token,這樣就是8個節點8個token,形成瞭如下區間範圍:
(t1,t2] -> {n2,n3,n4}
(t2,t3] -> {n3,n4,n5}
(t3,t4] -> {n4,n5,n6}
(t4,t5] -> {n5,n6,n7}
(t5,t6] -> {n6,n7,n8}
(t6,t7] -> {n7,n8,n1}
(t7,t8] -> {n8,n1,n2}
(t8,t1] -> {n1,n2,n3}
假設hash("foo")落在了(t1,t2]區間,那麼該key的3個副本放置的位置應該是n2,n3,n4
此時,如果我要新加一個節點n9,就沒有token可選了
如果物理機不夠怎麼辦呢?
假設物理機只有4台,但是token的範圍區間是固定的,那麼4個節點8個token,為了保持平衡,必須1個節點對應2個token
為了保持平衡,只能將虛擬節點均勻分佈在物理節點之間,因為是按順時針方嚮往前走的,數據最終還是要放到物理節點上的
於是形成瞭如下區間範圍:
(t1,t2] -> {n1,n2,n3}
(t2,t3] -> {n2,n3,n4}
(t3,t4] -> {n3,n4,n1}
(t4,t5] -> {n4,n1,n2}
(t5,t6] -> {n1,n2,n3}
(t6,t7] -> {n2,n3,n4}
(t7,t8] -> {n3,n4,n1}
(t8,t1] -> {n4,n1,n2}
每個物理節點對應兩個token的好處:
- 當添加一個新節點時,它從環中的其他節點接收大約相同數量的數據,從而使數據在集群中均勻分佈。
- 當刪除一個節點時,它丟失的數據與環中的其他成員丟失的數據大致相同,這再次保持了數據在集群中的均勻分佈。
- 如果某個節點變得不可用,查詢負載(特別是支持令牌的查詢負載)將均勻地分佈在許多其他節點上。
壞處:
- 每個令牌在令牌環上引入最多2 * (RF - 1)的其他鄰居,這意味著在令牌環的一部分失去可用性時,會出現更多的節點故障組合
- 集群範圍的維護操作通常會變慢。 例如,隨著每個節點令牌數量的增加,集群必須執行的離散修複操作的數量也會增加。
- 跨令牌範圍的操作性能可能會受到影響。
6. CAP
根據CAP定理,分散式數據存儲不可能同時提供兩個以上的以下保證:
- Consistency(一致性): 一致性意味著每次讀取都會收到最新的寫入或錯誤輸出
- Availability(可用性): 可用性意味著每個請求都會收到響應。不能保證響應中包含最新的寫入或數據。
- Partition tolerance(分區容錯性): 分區容錯是指存儲系統對網路分區故障的容錯。即使某些消息丟失或延遲,系統仍將繼續運行。
CAP定理表明,當使用網路分區時,由於存在分區故障的固有風險,因此必須在一致性和可用性之間進行選擇,並且不能同時保證兩者。
在基於web的應用程式中,高可用性是的優先順序比較高的需求,為此,Cassandra從CAP保證中選擇可用性和分區容錯性,在一定程度上犧牲數據一致性。
(PS:根據CAP定理,只能同時滿足兩個,而由網路分區帶來的分區錯誤風險是必然存在的,因此只能在CA中間選一個,Cassandra選擇了AP)
Cassandra提供以下保證:
- 高擴展性
- 高可用性
- 持久性
- 寫入單個表的最終一致性
- 具有可線性化一致性的輕量級事務
- 保證跨多個表的批量寫入完全成功或根本不成功
- 二級索引保證與其本地副本數據一致
高可擴展性
Cassandra是一個高度可擴展的存儲系統,可以根據需要添加/刪除節點。使用基於gossip的協議,每個節點都保留一個統一且一致的成員列表。
高可用性
Cassandra通過實現容錯存儲系統來保證數據的高可用性。使用基於gossip的協議進行節點中的故障檢測。
持久性
Cassandra通過使用副本來保證數據的持久性。副本是存儲在集群中不同節點上的數據的多個拷貝。在多數據中心環境中,副本可以存儲在不同的數據中心。如果一個副本由於不可恢復的節點/數據中心故障而丟失,數據不會完全丟失,因為副本仍然可用。
最終一致性
在生產中,Cassandra滿足了性能、可靠性、可伸縮性和高可用性的要求,是一個最終一致的存儲系統。最終一致性意味著所有更新最終會到達所有副本。相同數據的不同版本可能暫時存在,但最終會協調成一致的狀態。最終的一致性是實現高可用性的折衷方案,它涉及一些讀寫延遲。
輕量級事務
數據必須按順序讀寫。Paxos協議實現了輕量級事務,能夠使用線性一致性處理併發操作。線性化一致性是與實時約束的順序一致性,它保證了比較和設置(CAS)事務的事務隔離。使用CAS副本比較數據,並將發現過期的數據設置為最一致的值。使用線性一致性讀取允許讀取數據的當前狀態(可能是未提交的),而不需要進行新的添加或更新。
批量寫入
跨多個表進行批處理寫操作的保證是,它們最終會成功,或者沒有成功。批處理數據首先寫入到批處理日誌系統數據,當批處理數據成功地存儲在集群中時,批處理日誌數據將被刪除。批處理被覆制到另一個節點,以確保在協調節點失敗的情況下完成完整的批處理。
二級索引
二級索引是列上的索引,用於查詢通常不可查詢的表。二級索引在構建時保證與它們的本地副本一致。
7. Docs
https://cassandra.apache.org/download/
https://cassandra.apache.org/doc/latest/architecture/index.html
https://www.datastax.com/products/compare/nosql-performance-benchmarks
https://docs.datastax.com/en/cassandra-oss/3.x/
https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/architecture/archDataDistributeHashing.html
https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/dml/dmlIntro.html
補充:寬表
寬表從字面意義上講就是欄位比較多的資料庫表。通常是指業務主題相關的指標、維度、屬性關聯在一起的一張資料庫表。由於把不同的內容都放在同一張表存儲,寬表已經不符合三範式的模型設計規範,隨之帶來的主要壞處就是數據的大量冗餘,與之相對應的好處就是查詢性能的提高與便捷。(空間換時間)