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