Cassandra 初學者指南
Apache Cassandra 是一種分布式非關系型數據庫,具有高性能、可擴展、無中心化等特征。Cassandra 是適用于社交網絡業務場景的數據庫,適合實時事務處理和提供交互型數據。以 Amazon 完全分布式的 Dynamo 數據庫作為基礎,結合 Google BigTable 基于列族(Column Family)的數據模型,實現 P2P 去中心化的存儲。
行列概念:一組包含名稱值對的數據叫做行(Row),而每一組名稱值對(Name/Value Pair)被稱之為列(Column)。數據是以松散結構的多維哈希表存儲在數據庫中,所謂松散結構,是指每行數據可以有不同的列結構,如圖所示:
Super Column:可在列之間建立關聯的超級列,支持往超級列中添加子列。
Keyspaces:鍵空間是 Cassandra 的數據容器,可以理解為關系型數據庫中的數據庫(Database)。對于一個 Keyspace 來說,包括定義每行數據的復制節點數目、定義在一致性哈希環中某個節點的替換策略、列族(Column Families)等多個概念。
列族:列的容器,它的結構像是一個四維哈希表,[Keyspace][ColumnFamily][Key][Column]。
列:一組鍵值對。
在 CAP 原則(又稱 CAP 定理,指的是在一個分布式系統中,Consistency 一致性、Availability 可用性、Partition Tolerance 分區容錯性,三者不可得兼)上,HBase 選擇了 CP,Cassandra 則更傾向于 AP,但是其實 Cassandra 的一致性是可以調節的,并不是固定就是最終一致性。具體數據庫對應的 CAP“站隊”情況,大家可以看下面這張圖:
V0.6:2010 年 4 月,成為 Apache 頂級項目之后的第一次發布版本。包含特性:
與 Hadoop 集成,允許通過 MapReduce 方式從 Cassandra 讀取數據
集成行緩存,減輕 Cassandra 對于其他緩存技術的依賴
V0.7:2011 年 1 月,包含特性及優化點:
二級索引,允許在非主鍵字段上構建索引
支持規模較大的行設計,可以包含最多 20 億個列
支持在線模式改變,包括在線集群環境下增加、重命名、移除 KeySpaces 和列家族
通過每一列的 TTL(time-to-live)特性可以設置列的過期時間
引入 NetworkTopologyStrategy,支持多數據中心部署,允許 KeySpace 跨數據中心的副本配置
配置文件從 XML 轉為更可讀的 YAML 格式
V0.8:2011 年 6 月,這是一次較大的升級發布,包含特性:
加入了一個新的數據類型 -Distributed counters,用于計數器的自增 引入 sstableloader 工具,支持批量導入數據
引入堆外行緩存,允許 JVM 堆內存以外的本地內存可供使用
允許多線程執行并行壓縮,對 SSTable 的壓縮能力進行限流
改進內存配置參數,允許更靈活地控制 memtables 的大小
V1.0:2012 年 10 月,該版本后很多廠商開始在生產環境使用 Cassandra。包含特性:
CQL 改進了幾處,包括更改表和行的能力、支持計數和 TTL、獲取計數等
壓縮策略開始支持多種,提供了更快地讀寫速度支持
壓縮 SSTable 文件,基于表級別進行配置
V1.1:2011 年 4 月,包含特性:
CQL3 增加 timeuuid 類型,支持采用組合主鍵方式創建表
支持“order by”進行數據排序
支持通過 cqlsh 工具導入和導出 CSV 文件
允許數據以表的形式存儲在 SSD 或者磁盤上
Schema 以表的形式存儲在 system
keyspace 允許配置緩存大小
引入基于行級別的隔離,防止在多個列被更新或寫入的時候出現臟讀現象
V1.2:2013 年 1 月,包含特性:
CQL3 新增集合類型(sets、lists、maps),新增二進制協議用于替換 Thrift
虛擬節點支持集群內跨節點分布數據,提升新增或替換節點時的性能
增加追蹤方式,允許客戶端查看節點之間的讀和寫交互過程
所有數據結構都被從 JVM 堆內存轉移到了本地內存
V2.0:2015 年 6 月,這個版本具有里程碑意義,它不僅大規模提升了性能,而且解決了很多長達 5 年的技術債。包含特性:
新增支持 Paxos 協議的輕量級交易
CQL3 的改變包括針對 ALTER 命令的 DROP 語義支持,新增條件模式(IF EXISTS、IF NOTEXISTS),允許在主鍵字段上創建二級索引
運行時需要采用 Java7
引入針對寫操作的觸發機器,觸發可以在任何 JVM 語言中實現
V3.0:2015 年 11 月,這個版本開始采用 Intel 發明的“tick-tock 發布模型”,即在短時間內對系統架構進行變更,所以 V3.0 版本對于 Cassandra 來說,做了一定程度上的架構變更,修復了之前的很多缺陷,更加適用于現代高性能、高可用性數據庫需求。包含特性:
重寫存儲引擎代碼,更加貼合 CQL 結構
新增物理視圖(也叫全局索引)
正式基于 Java8 編譯和運行
移除基于 Thrift 的命令行接口(CLI)
Cassandra 是無中心化的,每一個節點都可能擔任臨時協調者角色,也可能擔任數據備份角色,這也意味著所有節點沒有差異,也不會存在差異,因為所有行為都是按照規則約束的隨機行為。
為了支持無中心化和分區容錯,Cassandra 使用 gossip 協議允許每個節點追蹤集群里其他節點的狀態信息。
Gossip 協議(也叫八卦協議)通常假設在大型、無中心化的網絡系統中容易出現網絡故障,也被用于分布式數據庫內的自動備份機制。本身它的名稱就來源于人類的八卦行為,你可以和任何人交換互相感興趣的信息。Gossip 比較適合在沒有很高一致性要求的場景中用作信息的同步。信息達到同步的時間大概是 log(N),這個 N 表示節點的數量。Gossip 中的每個節點維護一組狀態,狀態可以用一個 key/value 對表示,還附帶了一個版本號,版本號大的為更新的狀態。
以下是 Gossip 的工作流程:
每一秒鐘,gossiper 會隨機選擇集群中的一個節點并初始化 gossiper session。每一輪 gossip 需要三條信息。
gossip 初始器向它自己選擇的朋友(其他節點)發送 GossipDigestSynMessage。
當這個朋友收到這條信息,返回一條 GossipDigestAckMessage。
當初始器從這個朋友收到 ack 信息,它會向這個朋友發送 GossipDigestAck2Messae 去完成一輪 gossip。
如果我們從代碼層面來理解,Cassandra 源代碼里通過 Gossiper 類實現 gossip 協議,Gossip 每秒都會自動運行,以下代碼會定時啟動 GossipTask 類,GossipTask 是位于 org.apche.cassandra.gms.Gossip 類下的一個內部類,這個類負責管理本地節點的 gossip。當一個服務節點啟動后,這個類把自己注冊到 Gossiper,用以接收終端狀態信息。
GossipTask 在 Gossip 啟動后并不會立即運行,阻塞在 listenGate 這個變量上,當 Gossip 服務調用 listen 時才開始運行,如下代碼所示:
接下來,首先更新本節點的心跳版本號,如代碼所示:
然后構造需要發送給其他節點的消息 gDigests,如代碼所示:
接著,從存活節點中隨機選擇一個節點發送、從失效節點中隨機選取一個發送。如果當前存活節點數小于種子數,向其中一個種子節點發送消息,如代碼所示:
最后一步是檢查節點狀態,如果節點剛收到消息,還沒有來得及處理(收到時間小于 1 秒內),那線程會睡眠 100ms,用于處理消息。
Cassandra 中,Token 是用來分區數據的關鍵。每個節點都有一個唯一的 Token,表明該節點分配的數據范圍。節點的 Token 形成一個 Token 環。例如使用一致性 Hash 進行分區時,鍵值對將 genuine 一致性 Hash 值來判斷數據應當屬于哪個 Token。
根據分區策略的不同,Token 的類型和設置原則也有所不同。Cassandra(V3.10 版本)本身支持四種分區策略:
Murmur3Partitioner:這個是默認的分區器,它是根據 Row
Key 字段的 HashCode 來均勻分布的,這種策略提供了一種更快的哈希函數。
RandomPartitioner:這個分區器也是隨機分區器,基本特性和 Murmur3Partitioner 類似,只是通過 MD5 計算哈希值,可用于安全性更高的場合。
ByteOrderedPartitioner:采用的是按照 Row Key 的字節數據來排序,這個分區器支持 Row Key 的范圍查詢。
OrderPreservingPartioner:這個分區器也是支持 Row Key 范圍查詢的。它采用的是 Row Key 的 UTF-8 編碼方式來排序。
Cassandra 采用一個叫做 snitches(告密者)的辦法決定集群內部每個節點的相對主機距離,用來決定哪一個節點被用來讀和寫。Snitches 收集整個網絡拓撲信息,這樣 cassandra 可以有效地路由請求。
當 Cassandra 發起一個讀請求,它需要通過設定的一致性級別與幾個備份交互。為了提供讀請求的最大速度,Cassandra 選擇一個單一的副本用于整個對象的查詢,并且要求額外的副本執行 hash 值,用于確保拿到請求數據的最新版本。Snitch 的角色是去幫助確認哪個副本會最快地返回,并且這個副本需要包含查詢的所有數據。
Cassandra 當前針對不同的網絡架構方案已經提供了多種 Snitch 算法,每一個 snitch 實現了 IEndpointSnitch 接口。當前 Snitches 按實現分為三種:
SimpleSnitch:這種策略不能識別數據中心和機架信息,適合在單數據中心使用;
NetworkTopologySnitch:這種策略提供了網絡拓撲結構,以便更高效地消息路由;
DynamicEndPointSnitch:這種策略可以記錄節點之間通信時間間隔,記錄節點之間的通信速度,從而達到動態選擇最合適節點的目的。
這篇文章主要是針對 Cassandra 初學者,首先介紹了基本概念、關鍵定義,并對 Cassandra 直到 V3.0 版本的整個發布過程做了簡短總結,接著重點針對無中心化實現機制,特別是通信消息機制、節點數據存儲信息統計機制等做了一些討論。受限于篇幅,后續會專門寫一篇文章針對 Tombstones、Bloom Filters、SEDA 這三個概念進行深入解釋。
掃描二維碼推送至手機訪問。
版權聲明:本文由短鏈接發布,如需轉載請注明出處。
本文鏈接:http://www.virginiabusinesslawupdate.com/article_425.html