共計 10794 個字符,預計需要花費 27 分鐘才能閱讀完成。
這篇文章給大家介紹如何了解 Cassandra 數據庫,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Cassandra 數據庫,值得介紹的技術細節其實挺多的。因為它很多實現思路和關系型數據庫或者其他的 NoSQL 數據庫,是有一些不同的。這種不同是在數據庫設計實現思路上也是根源上的。所以衍生開來的諸多特點,在介紹起來就不太容易和其他數據庫去類比。
我把這幾大特性分為四類:
第一類開源,這個不需要討論。其余的三類 7 個特性,就是選講的核心提綱。
第二類是高可用、容錯性、可配置的一致性,這是圍繞著多節點冗余數據的特性,換句話說,如果 Cassandra 的數據,每一行數據只有一份而沒有副本,那么第二類特點就是不存在的。
第三類是分布式、去中心化、可擴展性,這三個特點圍繞的是數據庫的可拆分性,且各節點可以獨立運行的能力。若只裝一個單機的 Cassandra,那這一類特點就不存在。
第四類是行存儲,是描述數據庫底層存放數據的最基本的存儲結構特征,也是我切入的第一個特征。
行存儲結構
任何數據庫設計和優化始終圍繞一個核心事情 mdash; mdash; 查詢優化。查詢永遠是使用數據的核心需求。為什么要 INSERT? 為了以后這個數據要查詢。為什么要 DELETE? 因為不再查詢,并且讓其他的數據更快的查詢。為什么要 UPDATE,因為要實時的查詢使用。無論是數據庫的存儲結構,像 ORACLE 的段、區、塊的設計,還是輔助的存儲結構,像索引這種,歸根結底,為了更快速的查詢出需要數據。Cassandra 也不例外,了解它的存儲結構,就更加能夠理解它是如何在這個存儲體系下提高查詢性能的,即便它是一個號稱更擅長于 INSERT 的數據庫。
在早期的 Cassandra 中,數據庫表一直被稱之為 ColumnFamily(列族),我也有很長的時間將其理解為列的集合的意思。所以,我有一段時間認為 Cassandra 是一個列存儲的數據庫。那為什么 Cassandra 的數據模型,可以認為是行存儲 (ROW-ORIENTED) 的,但又會在早期表被稱之 ColumnFamily 呢? 因為從根本上來講,Cassandra 不能算一個嚴格的行存儲,當然它更不是列存儲,它的數據是存儲在一個稀疏矩陣中的。可能這個解釋略微抽象。那么我先來說下它為什么不是行存儲。
任何傳統的行存儲數據庫,一旦 DDL 定義了數據表有多少個列。那么這一行數據一定存儲了所有的列值。即使出現了這一列沒有值的情況,那么也一定存儲了一個 NULL 值,或者是由應用程序存儲一個空格或 0 來表示沒有值。這一列對應的存儲空間一定是存在的,當然數據庫中的 varchar 或者壓縮算法會使得這個存儲空間盡可能小。
但是,Cassandra 允許對于任何給定的行,你可以只包含其中幾列,而并非一行數據要有所有的列,當然 KEY 列是要有的。這種在列值存儲上的動態性,是傳統的行存儲數據庫根本不具備的。我猜這也可能早期為何有 ColumnFamily 概念的根源。
前文提到了,我有一段時間認為 Cassandra 是一個列存儲的數據庫。但是,我從來都認為它是一個不徹底的列存儲數據庫,而是一個受限的列存儲數據庫。不徹底在哪里? 大部分的列存儲數據庫,都是為了 OLAP 而生的,它的優勢在于,在某一列上做聚合的性能無語倫比。
比如我一個表有 100 列,我要對某一列求個 SUM。列存儲數據庫可以完美繞過多余的 99 列,只把需要的這一列一個不差的拿出來做 SUM。但是,用過 Cassandra 數據庫的人都知道,在任何一列上做全列級的聚合,那簡直是災難性的。就憑 Cassandra 會將不同的 KEY 部署在不同的數據庫節點 / 分區 PARTITION(注意這里和傳統數據庫分區不同),任何列級的操作,都會需要在多個數據庫上打轉。更何況,CQL 語句到來的時候,還要搞清楚,這個聚合列在這行數據上有沒有。所以,Cassandra 是不具備列存儲數據庫的特質的。
為什么,最后 Cassandra 還是被描述為是一個 ROW-ORIENTED 呢?
首先,它的存儲是緊緊圍繞著 Key 的。Key,它是一行數據的唯一標識符號。一行數據圍繞著 Partition Key 存在一起, 并且圍繞著 Clusterting Key 局部有序。可見它 ROW-ORIENTED 的特點還是很鮮明的。什么樣的存儲結構,就決定一個數據庫擅長做什么。按主鍵排序的行存儲 DB2 數據庫最擅長的是什么? 是在 OLTP 系統里,通過主鍵做單條記錄的快速查詢(Select by Key),這也正是 Cassandra 最為常見的 CQL 形態。什么樣的存儲結構,也決定了什么樣的操作會有限制。
在理解了 Cassandra 數據庫的 ROW-ORIENTED 的稀疏矩陣存儲之后,再來看看 CQL 語句的語法限制,那么這些限制就很容易理解。例如:Select 語句,Where 條件里,一定要送 Partition Key(沒有次索引的情況)。如果不送,則語法上必須要添加 ALLOW FILTERING。
為什么是這樣,剛才提到了,Partition Key 決定了數據存在哪里,它像是一個指針,直接指向了這一行數據的物理位置。ALLOW FILTERING 表示什么,表示的是 Cassandra 數據庫獲得這條記錄是通過篩選得來的,而不是通過直接定位得來的。
類比一下傳統數據庫,Where 條件送 Partition Key 就好比通過 HASH 索引定位記錄,ALLOW FILTERING 就如同先做一次 TABLE SCAN,讀出大量記錄再從記錄里過濾出符合 WHERE 條件的。再看看關于 Clusterting Key 的,CQL 語法要求,范圍查找、Order by 一類的語法都需要使用 Clusterting Key,這就十分好理解。在定位的 Partition Key 確定了位置之后,同一 Partition Key 的數據,都是 Clusterting Key 有序存放的,那么通過在這個有序的 Key 列上,無論范圍也好、排序也好,都不會需要數據庫引擎真正去排序,這就好像在傳統數據庫里,ORDER BY 的列,和某一個索引一致的情況下,執行計劃里不會真的排序是一個道理。
搞清楚了 Cassandra 的存儲結構之后,我們來看 Cassandra 在某一個節點上怎么做增刪改查。無論 Cassandra 的多節點特點多么鮮明,在單一節點上面,數據的讀寫,永遠才是數據庫性能的根基。節點再多,如果單節點上讀寫性能不行,那數據庫終究是快不起來的。所以這里我們來看一下,Cassandra 是怎么樣讀寫數據的。
先翻譯《Cassandra The Definitive Guide》一段話。“在 Cassandra 中,寫入數據非常快,因為它的 memtables 和 SSTables 設計,使它插入時,不需要執行磁盤讀取或搜索,這些減慢數據庫速度的操作。Cassandra 中的所有寫入都是追加形態的。”
我們看一下 Cassandra 的寫入步驟,來解讀它的寫入優勢。
第一步,寫 Commit Logs。這個步驟完全不是什么新發明。我覺得它和傳統數據庫的 REDO Log 幾乎是一樣的。無論是什么數據庫,這個 Log 的寫入,都是追加形態的。但是,注意看這個圖,Commit Logs 直接寫在硬盤上,我認為這個描述并不準確。無論時傳統數據庫的 REDO LOG 還是 Cassandra 的 Commit Logs,它都是先到內存,再 FLUSH 到磁盤上的。而 FLUSH 的策略是由一些參數決定的,比如 commitlog_sync。這和傳統數據庫非常相似,這里不展開來討論,只需要認識到一點,FLUSH 的動作頻率越高,系統奔潰時丟失的數據越少,同時損失部分數據插入性能。就像 Mysql 數據庫的參數 Innodb_flush_log_at_trx_commit= 1 時,Mysql 是最安全,但是也是最慢的。
第二步,Add to memtable,這是關鍵的一步,Cassandra 的這一步是完完全全的內存動作。而若是傳統的數據庫,則大約需要做這么幾個動作:
逐層搜索索引,若這個索引塊不在 DATA BUFFER 里,觸發磁盤 IO。
通過索引定位數據塊,若數據塊不在 DATA BUFFER 里,觸發磁盤 IO。
修改索引塊,修改數據塊,如果修改并發量大時,可能產生鎖等。
當然,若是像 Oracle 數據庫那樣的堆表設計,純粹的 INSERT 動作在 b 的 IO 觸發可能性要少一點,但是在 UPDATE(Cassandra 中也是 Insert)場景下,這些開銷都是不可少的。Cassandra 為什么可以在 Memtable 上純粹的做追加寫入,這個 Cassandra 記錄的 Timestamp 概念是分不開的,即無論你寫入多少次,數據庫只會以最新 Timestamp 的記錄為準。這樣就不需要去對記錄資源上鎖。這樣的設計,不要說沒有鎖沖突了,就連去把需要上鎖的記錄找出來的開銷都省了,快就快在這個地方。
但是,這個快是有代價的,那就是數據的一致性。比如一個簡單的需求,在數據寫入之前,需要看看這條數據是不是存在,如果存在了就不能插入(CQL 的 IF NOT EXIST 語法),或者 UPDATE 需要看數據條件(WHERE IF Column = lsquo;* rsquo;) 。一旦這種帶條件 CQL 使用,那可以推斷,上面的這些優勢,也就不存在了。
看第三步,如果這行數據在 Row Caches 里,使它失效。注意這個地方,Row Caches 里的記錄是不改的。那么 Row Caches 的使用場景,只有特別熱點的數據讀取的時候使用,它并不適合高并發熱點數據修改的場景。
常規交易,做完這三步就返回成功了,不需要等待 Memtable 的內容落盤。換句話說,直接影響交易性能的步驟,結束了。這和傳統數據庫也沒有太大的差別。那么接下來的步驟,就不直接影響數據庫的寫入能力。
第四步,數據的落盤,這個動作通常是異步的,在后面會詳細展開將 SSTable 的存儲。第五步,這個就是多節點特性了,是一個節點異常的處理過程。
總結一下,傳統的數據庫的寫入(包括 INSERT、UPDATE、Delete),通常是一個讀后寫的過程。而 Cassandra 的寫入,是沒有先讀這個動作的,這也是它快的根本原因。一旦使用了 IF NOT EXIST 之類的語法,那么它的寫入性能也就會要受損。
接下來看一下 Cassandra 的讀取,它的讀取是多節點、多副本的讀取。此處,我們先關注一個節點上的情況。
第一步,如果這一行數據在 Row Caches 中,直接返回數據,這個好理解。
第二步,檢查檢查 KeyCaches 里的索引,這里可以理解為,這是一個主鍵索引,它存儲的是未來在 Memtables 或者 SSTables 用來定位的信息(書上原文是 offset location)。需要注意的是,這里面的值,在第三步、和第四步的時候,都可能用得上,而不是僅僅用于第三步。看到這個地方,可以發現,其實這個圖有個問題,就是沒有指出 KeyCaches 的維護。Cache 是可以在建表時配置的一個參數。可以推測,假如我們建表的時候,keys 的 Cache 采用了 ALL 的設置,那么應該是在有新的 KEY 值寫入 Memtables 時,維護到了 Key Caches 中。
第三步,這一步需要關注是,對于一個指定的表(或列族),是只會使用唯一的一個 Memtable 的,那么這個搜索就是線性的。Memtable 中的內容,是還沒有 FLUSH 到 SSTables 里的數據,在查詢是,它里面的內容和 SSTables 中的內容,都是要同步讀取的,但對單節點而言,它的內容通常更新。
與寫入場景大有不同的地方是,讀數據的關鍵步驟,是第 4 步,讀 SSTables。這里在后面的內容展開,看一下第五步,如果 Row Caches 還可用,把這條記錄加入的 Row Caches。Row Caches 放的是一整行的數據,如前面提到了,適合于存放熱點讀取的數據。
所有的數據庫,通常都是有四大常規操作,謂之“增刪改查”。介紹了寫入、查詢之后,這里簡單的介紹一下 Cassandra 的刪和改。一句話簡述之,Cassandra 的刪除都是修改,Cassandra 的修改都是寫入,所以 Cassandra 只有寫入和查詢。Cassandra 一直寫入數據,豈不是會存儲爆炸不成。在這里,我們介紹三個新概念(相對傳統數據庫)-Tombstones,Timestamps,Compaction。
Cassandra 的刪除都是修改,這個好理解,在很多業務數據庫表里面,經常會為了保留痕跡,而做一個邏輯刪除動作。也就是修改某個標識,表示這條記錄以及刪除或作廢,而并沒有在數據庫里真正的刪除。Cassandra 在收到 Delete 命令時,并不會立刻去刪除這行記錄。而是會給這行記錄一個 Tombstones,表示它被刪除了。
Cassandra 的修改都是寫入。前面提到 Cassandra 速度快,快在不需要定位數據。任何 Update 命令,在傳統數據庫上,都需要把這條記錄讀到內存里,并上鎖。而在 Cassandra 上,Update 命令會變成一條 INSERT 語句,那豈不是在系統里重 KEY 了嗎? 這里便要依靠記錄上的 Timestamps。
Cassandra 的每次查詢,都會把所有重的 KEY 讀出來,但是永遠會以最新的 Timestamps 為準。這就解決了把所有的修改,都變成寫入的問題。但是,這么干有兩大顯而易見問題。第一,數據會無限的膨脹,吃掉磁盤。第二,數據膨脹會帶來查詢需要讀出的重復數據增加,無限的膨脹則會無限的增加,讀取性能就會受損。
所以這里,就要介紹壓縮 (Compaction) 的概念。這里要特別的注意,這不是我們通常說的數據庫壓縮技術,那個通常用的 Compress。只是由于多個官方文檔都把 Compaction 翻譯成了壓縮,我個人覺得它更應該翻譯成數據的整理。Compaction 是在數據庫后臺異步做的,接著前面的內容,它的內容至少有比如把墓碑數據真實移除,把時間戳比較老的數據移除,重新整理 SSTable 的存儲文件等。這樣來解決前面那兩個問題。這個動作在某種意義上來講甚至有一點像 DB2 數據庫的 REORG 動作。不同的數據庫表,可以在 Keyspace 級別選擇不一樣的 CompactionStrategy。它常翻譯為壓縮算法,我覺得翻譯成整理策略更加合適。我覺壓縮算法,應該和 Compress 的那個概念一致。畢竟,這個 Compaction 沒有給數據文件里連續的值,用個 RLE 算法,或者建個字典什么的對吧。介紹完了這些之后,讓我們來直面數據庫最大的瓶頸。
只要一個數據庫不是內存數據庫,那它永遠都要面對它最大的性能瓶頸,磁盤 IO。我們前面提到的諸多概念,比如 Cache、列存儲、索引等等,他們優化性能的本質都指向一處,減少磁盤 IO。前面講讀寫部分時,都跳過了第 4 步。而對于 SSTable 的讀取,其實才是影響性能的關鍵步驟。
我們來看一下,SSTable 到底是什么,它的讀取是什么樣子的。我們根據 SSTable 的訪問順序來看,在 3.0 版本中,SSTable 包含以下這么幾個文件:
Filter.db 這是 SSTable 的 Bloom 過濾器,簡單的講,它告訴你,你要的 Key,在我這里有沒有。Bloom 過濾器的工作方式是將數據集中的值映射到位數組,并使用散列函數將較大的數據集壓縮為摘要字符串。根據定義,摘要使用的內存量比原始數據少得多。它速度快,可能誤報,但不會漏。簡言之,有可能告訴你有,但是沒有。但絕不會告訴沒有,卻有。注意! 這里劃一個重點,Cassandra 會維護一個 Bloom filter 的副本在內存里面。所以,這一步不一定會有實際 IO。在書上也提到,如果加大內存,是可以減少 Bloom 過濾器誤報的情況。
Summary.db,這里是索引的抽樣,用來加速讀取的。
Index.db,提供 Data.db 里的行列偏移量。
CompressionInfo.db 提供有關 Data.db 文件壓縮的元數據。這里值得關注的是,它用了 Compression 這個詞,我猜測,如果 Data.db 里面采用了壓縮算法,比如說字典壓縮之類的,那么這個文件里面應該就會存儲字典數據,或者類似的 Compress 相關的元素據。這也就是為什么這個文件,在訪問流程中是不可繞過的。因為一旦 Data.db 的數據進行了壓縮,那就必須依靠相關的元數據來解壓縮數據。從圖上可以看出,這個元數據在內存中,相對性能會比較快。
Data.db 是存儲實際數據的文件,是 Cassandra 備份機制保留的唯一文件。它是唯一的真實數據,其他的都是輔助數據。比如索引可以重建,字典可以重建等等。
Digest.adler32 是 Data.db 校驗用的。
Statistics.db 存儲 nodetool tablehistograms 命令使用的有關 SSTable 的統計信息。
TOC.txt 列出此 SSTable 的文件組件。
其中 1 - 5 是跟 SSTable 訪問數據性能相關的文件。如果 Cache 是 ALL 的情況下,Cassandra 在通常都可以在內存訪問之后,直接定位到 SSTable 的具體文件和數據所在偏移量中去。相對于傳統數據庫,B 樹索引層層向下,遇到沒有的索引塊就要 IO。這個性能應該還是非常可觀的。
講到這里,不知道你有沒有感受到,Cassandra 的一個重要精華所在,那就是沒有鎖,或者叫沒有資源上的沖突和爭搶。通過 Timestamps 概念,解決數據可相同 Key 數據不要上鎖的問題。盡管我們前面的內容,全部都還只是在圍繞單節點數據庫介紹。但是 Timestamps 的使用,是為 Cassandra 分布式、去中心、可擴展、高可用、容錯性、可配置一致性提供了更多靈活方便的地方。
分布式、去中心、可擴展性
前面我們把這六條分成了兩類,分布式、去中心、可擴展,這三個圍繞的是 KEY 的獨立性。尤其是 Partition Key,它是具有極強的獨立性的。由于它的極度獨立,理論上任何不同 Partition Key 的數據,就都可以放在不同機器上,去獨立的提供服務,也就成就它的分布式、去中心和可擴展。對照這幾條特性看一下。
分布式,百度詞條上解釋為,建立在網絡上的軟件系統。有四大特性:
分布性。分布式系統由多臺計算機組成,它們在地域上是分散的,可以散布在一個單位、一個城市、一個國家,甚至全球范圍內。整個系統的功能是分散在各個節點上實現的,因而分布式系統具有數據處理的分布性。一個邏輯上的數據庫表,他是分散存儲來多個 Node 中的。不同的 Key 值的記錄會由 Cassandra 的不能節點提供分散的的服務。
自治性。分布式系統中的各個節點都包含自己的處理機和內存,各自具有獨立的處理數據的功能。通常,彼此在地位上是平等的,無主次之分,既能自治地進行工作,又能利用共享的通信線路來傳送信息,協調任務處理。Cassandra 只有在 Partition Key 劃分數據所屬 Node 的存儲位置時,有主次副本之分。比如說,我的 Node1 要存放的 Key 值是多少到多少,其他的勉強稱之為副本。其實 Cassandra 存的是多個地位平等主本,且都具備獨立處理數據等能力,它們協同處理任務,并非傳統意義上的主備數據概念。
并行性。一個大的任務可以劃分為若干個子任務,分別在不同的主機上執行。每個 Node 自然是自己提供涉及的 Key 的服務,相互之間獨立、并行。對于不同的 CQL 而言,可能會由不同 Node 來完成查詢。也可以是一個 CQL 里面涉及的多個 Node,它們也基本上是并行來完成這個 CQL 的。
全局性。分布式系統中必須存在一個單一的、全局的進程通信機制,使得任何一個進程都能與其他進程通信,并且不區分本地通信與遠程通信。同時,還應當有全局的保護機制。系統中所有機器上有統一的系統調用集合,它們必須適應分布式的環境。在所有 CPU 上運行同樣的內核,使協調工作更加容易。Cassandra 是完全符合這個定義的,Coordinator 節點并不是固定的。每個節點都可以接受任何的 CQL,并且來充當協調者的角色。重要的是,對于一個應用程序或者客戶端而且,可以不關心 Cassandra 后來是怎么樣存儲和查詢數據的。它從外面看到的,始終只有一張完整的邏輯數據表。
有了分布式的基礎,Cassandra 可以運行在多個 Node 下,并且多個 Node 可以部署在真實的不同的數據中心機房里,不同機架上,也就能做到去中心 Decentralized。有了這個基礎,就可以配合 Cassandra 的多中心的復制策略 NetworkTopologyStrategy,在每一個數據中心定義數據復制了。
可擴展這個詞其實,并不是特別準確,它的重點其實是可水平擴展。簡而言之,就是在圖中環上加 Node,就可以提高 Cassandra 的處理能力。這其實和它的分布式特點是密不可分的。Cassandra 的拆分粒度最細,理論上幾乎可以到一個 Partition KEY。或者說,每一個 Partition KEY,都可以被看作可以拆分的,獨立處理的最小的單位。增加數據的同時只要增加 Node 就可以了,這就使得它的水平擴展性是很好的。
做一個偏激的假設,如果 Cassandra 只有一份數據存儲,就憑 Key 獨立的特點,把不同的 Key 分到不同的機器上提供服務,也可以算得上是分布式、去中心和可擴展的。但是它這個特點是不完美,不徹底的。因為機器分得越多,任何一臺機器故障,它提供的服務就是不完整的。
高可用、容錯性、可配置一致性
接下來,我們繼續看另外三個特點,高可用、容錯性、可配置的一致性,這些特點圍繞的核心就數據冗余。
任何的高可用背后,一定是有數據冗余的。傳統數據庫通常偏愛的是主備模式,就是當提供服務的數據庫節點 DOWN 掉之后,備節點開始提供服務。這時候往往故障檢測、主備切換,應用切換的時間就會成為關注的焦點,做得好一點的數據庫可以在 1 分鐘或者幾十秒內完成切換。不過在如今 7 *24*365 的環境下,1 分鐘的故障恢復時間通常并不能讓用戶十分滿意,當切換時間壓縮到一定程度,還會出現一個矛盾點,就是數據庫異常時間監測閾值。如果設得太長,主備切換就慢,設太短了,一個網絡抖動,就可能觸發不必要的主備切換誤判。
Cassandra 的數據復制 (replicas) 并不像傳統的備份數據,它更像是多份主數據,這些數據都是時時刻刻對外提供服務的,換句話說,有一個數據庫節點 DOWN 掉,完全不需要主備切換時間。在資源充足的情況下,甚至是幾乎無感的(比如 7 個 replicas 壞了 1 個)。
在 Cassandra 里面,數據復制 (replicas) 多少份,怎么存儲,這個策略是可以根據不同的 Keyspace 來設置的,相當于提供一個靈活的選擇,可以根據數據庫表的實際使用場景和形態,來決定數據復制的策略。
數據冗余可以說是分布式系統中的常規操作,像參數數據之類的,經常會采用數據冗余的方法來處理。然而,有冗余的地方就有同步。數據一致性問題,永遠和數據冗余相伴而生。好在 Cassandra 有 Timestamps 來解決一致性問題,容錯性只是一致性的一個衍生產品,簡單的說,只是 Cassandra 發現了一個老 Timestamps 的錯誤數據,后臺修復一下而已。
而可配置一致性,就是 Cassandra 的一個特別重要的特性了。因為它的影響但不僅僅是對于高可用,它還直接影響數據庫性能。就傳統數據庫而言,開不開備庫,對 OLTP 交易性能也是有直接影響的(包括 Redis 也是)。從理論上來說,Cassandra 要等更多的 Node 寫入數據,那響應時間就會越慢。這個響應時間取決與最慢的那個 Node。若要交易響應更快,就需要通過異步的方式。所以 Cassandra 通常都不會等所有的 Node 都響應,等多少 Node,等哪些 Node,就是可配置一致性。
在數據寫入讀取方面 Cassandra 的一直性級別有:
ANY(僅寫入),ONE,TWO,THREE ,QUORUM,ALL
LOCAL_ONE, LOCAL_QUORUM,EACH_QUORUM
以上這些級別很好理解,不需要逐個解釋。關于高可用和強一致性,永遠都是魚和熊掌。假如我們的系統使用了最快的方式寫入,比如寫 ANY,讀 ONE。那么讀到的數據并不是最實時的準確數據的可能性就會大幅增加。如上面的圖,有 6 個節點在寫入數據,任意一個寫成功,程序就成功返回。那么假定其余 5 個節點還沒有完成寫入。那這時候,有一個讀 ONE 的程序,恰好讀到了這 5 節點中的一個,并成功返回,這就產生了數據的不一致。要做到數據的強一致,讀寫策略就必須配合設置,滿足這樣的條件。
W+R RF W mdash; 寫一致性級別 R mdash; 讀一致性級別 RF mdash; 副本數
Cassandra 的這個設計非常的巧妙,它提供極好的調優靈活性。數據庫調優的本質無非是個損有余而補不足的過程,這個有余并非指損性能好的地方去補性能不好的地方。
數據庫或數據,有些地方有些功能,我們不用或者少用,性能不需要那么好,稱之為有余; 有些地方有些功能我們常用,主要用,性能要越快越好,我們稱之為不足。比如很多系統的某個數據庫表,它的訪問形態是有局限性的。有可能一張表,100 次插入,只有 1 次讀取,像流水數據。有可能一張表,1 次插入,100 次讀取,像參數數據。這里面就有了極大的靈活性,我們可以損失冷門操作的性能,來保障我們的主要操作。例如,以讀取為主的表,我們可以設置寫入的一致性為 ALL , 讀取的一致性為 ONE。從而獲得一個非常高效的系統性能。
需要注意的是,數據的復制因子,是定義在 Keyspace,也就是在存儲方面決定。而讀取的一致性,是由客戶端決定的。同樣的數據,也可以根據不同使用場景來使用不同的一致性級別。比如說,對數據實時性要求高時,可以設置成讀 QUORUM 或者 ALL,實時性要求低時,選擇讀 ONE。
總結
至此,我已經完整的講解了 Cassandra 的分布式、去中心化、可擴展性、高可用、容錯性、可配置的一致性、行存儲的特性。
回顧一下,我們先講了 Cassandra 單節點上的行存儲結構,然后圍繞 Cassandra 數據 Key 的獨立性介紹了分布式、去中心化、可擴展性。繼而討論了關于 Cassandra 多副本數據帶來的高可用、容錯性、和可配置一致性。
當然 Cassandra 數據庫還有很多值得探討和介紹的內容和概念,如 Secondary Index、Tokens、Hinted 等等。此外在 Cassandra 數據庫的使用過程中,也還有監控、備份恢復、性能調優、安全等等內容值得關注學習,這里就不一一介紹了,未來有機會,再做續集吧。
關于如何了解 Cassandra 數據庫就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。