Cassandra 初學者指南
作者|周明耀
編輯|小智
本文是一篇科普文,適合 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 原則(又稱 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。
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 這三個概念進行深入解釋。
作者介紹
周明耀,2004 年畢業於浙江大學,工學碩士。13 年軟體研發經驗,近 10 年技術團隊管理經驗,4 年分散式計算、大數據技術經驗。著有《大話 Java 性能優化》、《深入理解 JVM&G1 GC》、《技術領導力 - 碼農如何才能帶團隊》。個人微信號 michael_tec,個人公眾號「麥克叔叔每晚 10 點說」。
今日薦文
點擊展開全文
※最後 7 天!距離你入職矽谷名企
※極簡大法,化繁為簡的雲實戰分享
※技術團隊,如何更高效地開會?
※一份數據支持多種應用場景 CarbonData融合數據存儲方案技術揭秘
※抵擋黑產,他們是最具男友力的研發團隊
TAG:InfoQ |
※I left my heart in San Francisco 舊金山旅行指南
※Dream Fitness健身指南
※收藏者指南:Van Cleef&Arpels
※Electrical Engineering Master 選課指南
※周三鑒定科|Chanel Costume Jewelry鑒定指南
※Mozilla發布Firefox Reality WebVR開發者指南
※簡版科幻入坑指南/Instruction of Falling for SF-Abridged Edition
※英式傳統下午茶指南‖Food and Tea Service
※職場指南之三:Working with a bully boss
※始於Jupyter Notebooks:一份全面的初學者實用指南
※Python 機器學習 Scikit-learn 完全入門指南
※狗狗飲水指南 How Much Water Should Your Dog Be Drinking?
※中國Sneakerhead歧視指南
※IOS 11 Human Interface Guidelines-視覺設計指南
※舊裝勞力士簡易中文買家指南 Part1.9 Service Case&Fake Case
※白色版Virgil Abloh x Nike VaporMax發售之際,雙手奉上Fake Or Real辨別指南!
※21世紀孤獨生活指南×Kovanen&Vivian Maier&Amélie
※入門|始於Jupyter Notebooks:一份全面的初學者實用指南
※Tensorflow入坑指南
※Find Chitchat 手帳入坑指南