考慮 Apache Cassandra 數據庫

簡介

在數據庫歷史文章 「What Goes Around Comes Around」(參閱 參考資料)中,Michal Stonebraker 詳細描述了存儲技術是如何隨着時間的推移而發展的。實現關係模型以前,開發人員曾嘗試過其餘模型,好比層次圖和有向圖。值得注意的是,基於 SQL 的關係模型(即便到如今也仍然是事實上的標準)已經盛行了大約 30 年。鑑於計算機科學的短暫歷史及其快速發展的步伐,這是一項非凡的成就。關係模型創建已久,以致於許多年來,解決方案架構師很容易爲應用程序選擇數據存儲。他們的選擇老是關係數據庫。 程序員

諸如增長系統、移動設備、擴展的用戶在線狀態、雲計算和多核系統的用戶羣之類的開發已經致使產生愈來愈多的大型系統。Google 和 Amazon 之類的高科技公司都是首批觸及規模問題的公司。他們很快就發現關係數據庫並不足以支持大型系統。 算法

爲了不這些挑戰,Google 和 Amazon 提出了兩個可供選擇的解決方案:Big Table 和 Dynamo(參閱 參考資料),他們能夠由此放鬆關係數據模型提供的保證,從而實現更高的可擴展性。Eric Brewer 的 「CAP Theorem」(參閱 參考資料)後來官方化了這些觀察結果。它宣稱,對於可擴展性系統,一致性、可用性和分區容錯性都是權衡因素,由於根本不可能構建包含全部這些屬性的系統。不久以後,根據 Google 和 Amazon 早期的工做,以及所得到的對可擴展性系統的理解,計劃建立一種新的存儲系統。這些系統被命名爲 「NoSQL」 系統。該名稱最初的意思是 「若是想縮放就不要使用 SQL」,後來被從新定義爲 「不僅是 SQL」,意思是說,除了基於 SQL 的解決方案外,還有其餘的解決方案。 數據庫

有許多 NoSQL 系統,並且每個系統都緩和或改變了關係模型的某些方面。值得注意的是,沒有一個 NoSQL 解決方案適用於全部的場景。每個解決方案都優於關係模型,且針對一些用例子集進行了縮放。個人早期文章 「在 Data Storage Haystack 中爲您的應用程序尋找正確的數據解決方案」 討論瞭如何使應用程序需求和 NoSQL 解決方案相匹配(參閱 參考資料)。 apache

Apache Cassandra(參閱 參考資料)是其中一個最先也是最普遍使用的 NoSQL 解決方案。本文詳細介紹了 Cassandra,並指出了一些首次使用 Cassandra 時不容易發現的細節和複雜之處。 編程

回頁首 架構

Apache Cassandra

Cassandra 是一個 NoSQL 列族 (column family) 實現,使用由 Amazon Dynamo 引入的架構方面的特性來支持 Big Table 數據模型。Cassandra 的一些優點以下所示: 數據庫設計

  • 高度可擴展性和高度可用性,沒有單點故障
  • NoSQL 列族實現
  • 很是高的寫入吞吐量和良好的讀取吞吐量
  • 相似 SQL 的查詢語言(從 0.8 起),並經過二級索引支持搜索
  • 可調節的一致性和對複製的支持
  • 靈活的模式

這些優勢很容易讓人們推薦使用 Cassandra,可是,對於開發人員來講,相當重要的一點是要深刻探究 Cassandra 的細節和複雜之處,從而掌握該程序的複雜性。 分佈式

Cassandra 根據列族數據模型存儲數據,如 圖 1 所示。 工具

圖 1. Cassandra 數據模型
該圖顯示了密鑰空間中列和行之間的關係

什麼是列?

 有點用詞不當,使用名稱單元格 極可能更容易理解一些。我會堅持使用,由於這是一種習慣用法。 性能

Cassandra 數據模型包括列、行、列族和密鑰空間 (keyspace)。讓咱們逐一進行詳細介紹它們。

  • 列:Cassandra 數據模型中最基本的單元,每個列包括一個名稱、一個值和一個時間戳。在本文的討論中,咱們忽略了時間戳,您能夠將一個列表示爲一個名稱值對(例如 author="Asimov")。
  • 行:用一個名稱標記的列的集合。例如,清單 1 顯示瞭如何表示一個行:
    清單 1. 行的示例
    "Second Foundation"-> {
        author="Asimov", 
        publishedDate="..",
        tag1="sci-fi", tag2="Asimov"
        }

    Cassandra 包括許多存儲節點,而且在單個存儲節點內存儲每個行。在每一行內,Cassandra 老是存儲按照列名稱排序的列。使用這種排序順序,Cassandra 支持切片查詢,在該查詢中,給定了一個行,用戶能夠檢索屬於給定的列名稱範圍內的列的子集。例如,範圍 tag0 到 tag9999 內的切片查詢會得到全部名稱範圍在 tag0 和 tag9999 內的列。

  • 列族:用一個名稱標記的行的集合。清單 2 顯示了樣例數據的可能形式:
    清單 2. 列族示例
    Books->{
        "Foundation"->{author="Asimov", publishedDate=".."},
        "Second Foundation"->{author="Asimov", publishedDate=".."},
        …
        }

    人們常說列族就像是關係模型中的一個表格。以下例所示,類似點將不復存在。

  • 密鑰空間:許多列族共同造成的一個組。它只是列族的一個邏輯組合,併爲名稱提供獨立的範圍。

最後,超級列位於一個列族中,該列族對一個密鑰下的多個列進行分組。正如開發人員不同意使用超級列同樣,在此,我對此也不做任何討論。

回頁首

Cassandra 與 RDBMS 數據模型

根據以上對 Cassandra 數據模型的描述,數據被放入每個列族的二維 (2D) 空間中。要想在列族中檢索數據,用戶須要兩個密鑰:行名稱和列名稱。從這個意義上來講,儘管還存在多處相當重要的差別,關係模型和 Cassandra 仍然很是類似。

  • 關係列均勻分佈在表中的全部行之間。數據項之間一般有明顯的縱向關係,但這種狀況並不適用於 Cassandra 列。這就是 Cassandra 使用各個數據項(列)來存儲列名稱的緣由。
  • 有了關係模型,2D 數據空間就完整了。2D 空間內的每個點至少應當擁有存儲在此處的 null 值。另外,這種狀況不適用於 Cassandra,Cassandra 能夠擁有隻包括少數項的行,而其餘行能夠擁有數百萬個項。
  • 有了關係模型,就能夠對模式進行預約義,並且在運行時不能夠更改模式,而 Cassandra 容許用戶在運行時更改模式。
  • Cassandra 始終存儲數據,這樣就能夠根據其名稱對列進行排序。這使得使用切片查詢在列中搜索數據變得很容易,但在行中搜索數據變得很困難,除非您使用的是保序分區程序。
  • 另外一個重要差別是,RDMBS 中的列名稱表示與數據有關的元數據,但毫不是數據。而在 Cassandra 中,列名稱能夠包括數據。所以,Cassandra 行能夠擁有數百萬個列,而關係模型一般只有數十個列。
  • 關係模型使用定義良好的不可變模式來支持複雜的查詢,這些查詢中包括 JOIN 和聚合等。使用關係模型,用戶無需擔憂查詢就可定義數據模式。Cassandra 不支持 JOIN 和大多數 SQL 搜索方法。所以,模式必須知足應用程序的查詢要求。

爲了探討上述差別,能夠考慮一個書籍評分站點,用戶能夠在該站點添加書籍(做者、等級、價格和連接)、評論(文本、時間和名稱),對這些添加的內容進行標記。應用程序須要支持用戶的如下操做:

  • 添加書籍
  • 添加書籍評論
  • 添加書籍標記
  • 列出按等級排序的書籍
  • 列出給定一個標記的書籍
  • 列出給定一個書籍 ID 的評論

使用關係模型實現以上應用程序幾乎微不足道。圖 2 展現了數據庫設計的實體關係 (ER) 圖。

圖 2. 書籍評分站點的 ER 模型
書籍站點數據模型的流程圖

讓咱們看看使用 Cassandra 數據模型如何實現此項操做。清單 3 展現了 Cassandra 的可能模式,其中第一行表示 「Book" 列族(擁有多個行),每一行擁有和列相同的書籍屬性。<TS1> 和 <TS2> 表示時間戳。

清單 3. 用於書籍評分的 Cassandra 模式樣例
Books[BookID->(author, rank, price, link, tag<TS1>, tag<TS2> .., 
    cmt+<TS1>= text + "-" + author) …] 
Tags2BooksIndex[TagID->(<TS1>=bookID1, <TS2>=bookID2, ..) ] 
Tags2AuthorsIndex[TagID->(<TS1>=bookID1, <TS2>=bookID2, ..) ]
RanksIndex["RANK" -> (rank<TS1>=bookID)]

表 1 是按照模式表示的樣例數據集。

表 1. 書籍評分站點的樣例數據
列族名稱 樣例數據集
Books


"Foundation" -> ("author"="Asimov", "rank"=9, "price"=14, "tag1"="sci-fi", "tag2"="future", "cmt1311031405922"="best book-sanjiva", "cmt1311031405923"="well I disagree-srinath")
"I Robot" -> ("author"="Asimov", "rank"=7, "price"=14, "tag1"="sci-fi" "tag2"="robots", "cmt1311031405924"="Asimov's best-srinath", "cmt1311031405928"="I like foundation better-sanjiva")
RanksIndex "Rank" -> (9="Foundation", 7="I Robot")
Tags2BooksIndex
"sci-fi" -> ("1311031405918"="Foundation", "1311031405919"="I Robot"
"future" -> …
Tags2AuthorsIndex "sci-fi" -> (1311031405920="Asimov")
"future" -> …

本示例展現了關係模型和 Cassandra 模型之間的幾個設計差別。Cassandra 模型在一個名爲 「Book" 的單個列族內存儲書籍數據,而其餘三個列族是構建用來支持查詢的索引。

請仔細看一下 「Books」 列族,該模型使用了一個行來表示書籍名稱是行 ID 的每本書。有關書籍的細節被表示爲存儲在行中的列。

再仔細看看,您可能會發現,已存儲的數據項(好比評論、與書籍關係爲 1:M 的標記)也位於單個行中。爲了實現這一點,能夠將時間戳附加在列名稱上,以便進行標記和評論。這種方法在同一列中存儲全部的數據。這樣的操做避免了必須執行 JOIN 纔可檢索數據的問題。Cassandra 彌補了經過此方法支持 JOIN 的不足。

這也提供了一些優點。

  • 經過使用單個查詢讀取完整行的方法,您能夠讀取書籍的全部數據。
  • 您能夠經過使用切片查詢來檢索評論和標記,無需執行 JOIN,該切片查詢的起始範圍和終止範圍分別爲 cmt0-cmt9999 和 tag0-tag9999。

因爲 Cassandra 存儲按照其列名稱排序的列,這就使得切片查詢很是快就能完成。值得注意的是,在單個行中存儲全部的數據細節並使用排序順序是 Cassandra 數據設計時最重要的理念。大多數 Cassandra 數據模型根據這些理念的某些形式進行設計。用戶在存儲數據和構建索引時可使用排序順序。例如,給列名稱附加時間戳的另外一個反作用是:就像列名稱按照排序順序進行存儲同樣,評論也有使用時間戳後綴的列名稱,並按照建立它們的順序進行存儲,且搜索結果也具備相同的順序。

Cassandra 不支持基礎設計的任何搜索方法。儘管其支持二級索引,這些方法仍是經過使用後來構建的索引來提供支持,並且二級索引有一些侷限性,不支持範圍查詢。

所以,要實現 Cassandra 數據設計最好的結果,須要用戶經過構建定製索引並使用列和行排序順序來實現搜索。其餘三個列族(Tags2BooksIndex、Tags2AuthorsIndex 和 RankIndex)也這樣作。因爲用戶須要搜索具備給定標記的書籍,經過將標記名稱存儲爲行 ID,並將使用該標記進行標記的全部書籍存儲爲該行下的列,「Tags2BooksIndex」 列族構建了一個索引。如該例所示,時間戳被添加爲列密鑰,可是也是將要提供的唯一的列 ID。經過按照標記名稱查找行並經過讀取存儲在該 rowID 內的全部列來找到匹配項,搜索實現僅讀取索引。

表 2 討論了應用程序要求的每一個查詢是如何使用上述 Cassandra 索引來實現的。

表 2. 查詢實現的比較
查詢描述 SQL 查詢 Cassandra 實現
列出根據等級存儲的書籍

運行查詢
"Select * from Books order by rank",而後在每一個結果上執行 "Select tag from Tags where bookid=?" and "Select comment from Comments where bookid=?"
在 「RankIndex」 列族上進行切片查詢,接收已排序的書籍列表,並在 「Books」 對每個書籍執行切片查詢,以便讀取書籍的詳細信息。
給定一個標記,查找具備給定標記的書籍的做者。 Select distinct author from Tags, Books where Tags.bookid=Books.bookid and tag=? 使用切片查詢在 Tags2Authors 中讀取給定標記的全部列。
給定一個標記,列出具備給定標記的書籍。 Select bookid from Tags where tag=? 使用切片查詢在 Tags2BooksIndex 中讀取具備給定標記的全部列。
給定一個書籍,建立評論時,按時間的排序對列出該書籍的評論進行排序。 Select text, time, user from Comments where bookid=? Order by time 在 「Books」 列族中,在與給定書籍對應的行中執行切片查詢。它們是按排序順序的,這是由於將時間戳用做了列名稱。

儘管上述設計能夠高效支持由書籍評分站點要求的查詢,但它只能支持爲專用查詢設計但不支持專用查詢的查詢。例如,若是沒有構建新的索引,它就不能支持如下查詢。

  • Select * from Books where price > 50;
  • Select * from Books where author="Asimov"

將設計更改成支持這些和其餘查詢是有可能的,經過構建適當的索引或編寫代碼來遍歷全部數據便可實現此操做。可是,須要定製代碼來支持新的查詢,與關係模型相比,這是一種侷限性,由於在關係模型中添加新查詢一般不須要更改模式。

在 0.8 發行版中,Cassandra 支持次級索引,用戶能夠在此根據給定屬性指定搜索,並且 Cassandra 能夠自動構建索引來根據該屬性進行搜索。可是,該模型的靈活性不大。例如,次級索引不支持範圍查詢,也沒有爲結果的排序順序提供保證。

回頁首

在 Java 環境中使用 Cassandra

Cassandra 具備許多用不一樣語言編寫的客戶端。本文將重點介紹 Hector 客戶端(參閱 參考資料),這是最普遍用於 Cassandra 的 Java 客戶端。用戶能夠經過嚮應用程序類路徑添加 Hector JAR 嚮應用程序添加 Hector 客戶端節點。清單 4 展現了一個樣例 Hector 客戶端。

首先,鏈接到 Cassandra 集羣。而後使用 Cassandra Getting Started Page(參閱 參考資料)中的指令來創建一個 Cassandra 節點。除非更改了配置,不然一般在端口 9160 之上運行該指令。其次,要定義一個密鑰空間,這能夠經過客戶端或 conf/cassandra.yaml 配置文件來完成。

清單 4. Cassandra 的樣例 Hector 客戶端節點
Cluster cluster = HFactory.createCluster('TestCluster', 
        new CassandraHostConfigurator("localhost:9160"));

//define a keyspace
Keyspace keyspace = HFactory.createKeyspace("BooksRating", cluster);

//Now let's add a new column. 
String rowID = "Foundation"; 
String columnFamily = "Books";

Mutator<String>
 mutator = HFactory.createMutator(keyspace, user);
mutator.insert(rowID, columnFamily, 
        HFactory.createStringColumn("author", "Asimov"));

//Now let's read the column back 
ColumnQuery<String, String, String>
        columnQuery = HFactory.createStringColumnQuery(keyspace);
columnQuery.setColumnFamily(columnFamily).setKey(」wso2」).setName("address");
QueryResult<HColumn<String, String>
 result = columnQuery.execute();
System.out.println("received "+ result.get().getName() + "= " 
        + result.get().getValue() + " ts = "+ result.get().getClock());

在 Download 中查找書籍評分示例的完整節點。包括切片查詢的樣例和其餘複雜的操做。

回頁首

Cassandra 架構

查看過 Cassandra 的數據模型以後,讓咱們返回到 Cassandra 的架構,從分佈式系統的角度瞭解它的優缺點。

圖 3 展現了 Cassandra 集羣的架構。首先觀察到得是 Cassandra 是一個分佈式系統。Cassandra 包括多個節點,並跨這些節點來分發數據(用數據庫的術語來講就是,將數據分紅不少份)。

圖 3. Cassandra 集羣
該圖顯示了 cassandra 集羣中每個節點在一個迴路中的鏈接方式

Cassandra 使用一致的散列算法給節點分配數據項。簡言之,Cassandra 使用一個散列算法來計算存儲在 Cassandra (例如,列名稱和行 ID)中的每一個數據項的密鑰散列。散列範圍或全部可能的散列值(又稱爲密鑰空間)是在 Cassandra 集羣中的節點之間進行分配的。而後,Cassandra 向該節點分配每個數據項,而該節點負責存儲或管理數據項。論文 「Cassandra - A Decentralized Structured Storage System」(參閱 參考資料)提供了有關 Cassandra 架構的詳細討論。

由此產生的架構提供瞭如下屬性:

  • Cassandra 在其節點之間分發數據,這對用戶是透明的。任何節點能夠接收任何請求(讀取、寫入或刪除)並將請求路由至正確的節點,即便數據沒有存儲在該節點中。
  • 用戶能夠定義所需的副本的數量,並且 Cassandra 會透明地處理副本的建立和管理。
  • 可調節的一致性:在存儲和讀取數據時,用戶能夠選擇所指望的每項操做的一致性級別。例如,若是 「quorum」 一致性級別是在執行寫入或讀取操做時使用,那麼能夠對來自集羣中一半以上的節點的數據進行寫入和讀取操做。支持可調節的一致性使用戶可以選擇最適合其用例的一致性級別。
  • Cassandra 提供很是快速的寫入速度,比每一個節點以每秒 80-360MB 的速度傳輸數據時的讀取速度還要快。它經過使用兩項技術實現這一目的。
    • Cassandra 在其負責的節點上保留內存中的大多數數據,並且全部更新都在內存中完成,並以一種懶惰的方式寫入永久存儲(文件系統)。可是,爲了不丟失數據,Cassandra 將全部的事務寫入磁盤中的提交日誌。與在磁盤中更新數據不一樣,向提交日誌寫入數據是追加數據,所以在向磁盤寫入輸入時能夠避免旋轉延遲。有關磁盤驅動性能特徵的更多信息,請參閱 參考資料
    • 除非要求寫入操做是徹底一致的,不然 Cassandra 無需解決任何數據不一致性(只在首次讀取時解決不一致性)問題便可將數據寫入足夠多的節點。這個過程稱做 「讀取修復」。

由此產生的架構具備高可縮放性。您能夠構建一個具備數十至數百個節點的 Cassandra 集羣,可以處理數 TB 到數 PB 字節的數據。分佈式系統有一個權衡,並且縮放幾乎歷來不會免費提供。如前所述,用戶在從關係數據庫遷移到 Cassandra 時會遇到許多驚喜。下一部分將討論這些問題。

回頁首

Cassandra 可能帶來的驚喜

從關係數據庫遷移到 Cassandra 時要意識到這些差別。

不支持事務,就不支持 JOIN

衆所周知,Cassandra 不支持 ACID 事務。儘管其有一個批處理操做,但仍是不能保證批處理操做內的子操做是以原子的方式進行的。在 失敗操做可能產生變動 中會對此進行詳細討論。

此外,Cassandra 不支持 JOIN。若是用戶須要鏈接兩個列族,就必須以編程方式檢索和鏈接數據。對於大型數據集來講,這一般代價高昂且很是耗時。Cassandra 經過在同一行中存儲盡更多的數據來巧妙地避免這種侷限性,如示例中所述。

沒有任何外鍵和鍵是不可變的

Cassandra 不支持外鍵,因此 Cassandra 不可能表明用戶來管理數據的一致性。所以,應用程序應當處理數據一致性。此外,用戶不能更改鍵。推薦使用具備須要對多個鍵進行更改的用例的代理鍵(生成多個鍵而非一個鍵,並將鍵做爲屬性進行管理)。

鍵必須是唯一的

每一個鍵(例如行鍵和列鍵)在此範圍內都必須是唯一的,並且若是同一個鍵使用過兩次,則須要重寫數據。

對於這個問題有兩種解決方案。第一個是,您可使用一個組合鍵。也就是說,經過組合多個字段來建立鍵,並且這個解決方案一般和行鍵一塊兒使用。第二個解決方案是,當出現同一個鍵被使用兩次的危險時,使用任意值或時間戳做爲該鍵的後綴。在索引將某個值存儲爲列名稱而且使用這些索引時,一般會發生這種狀況。例如,在書籍評分應用程序中,等級用做列名稱。爲了不有兩個條目因具備相同的等級而具備相同的列名稱,時間戳做爲後綴添加到等級中。

失敗的操做可能致使發生更改

正如前面已經解釋過的,Cassandra 不支持原子操做。相反,它支持冪等操做。不論執行多少次操做,冪等操做都將系統保持爲相同的狀態。全部的 Cassandra 操做都是冪等的。若是操做失敗,您能夠果斷進行重試。這就提供了一種從暫時性故障中恢復的機制。

Cassandra 還支持批處理操做,但也不提供任何原子性保證。由於操做是冪等的,因此客戶端能夠一直重試,直到全部批處理操做成功完成爲止。

冪等操做並不等同於原子操做。若是一個操做成功了,一切都很順利,結果與原子操做是相同的;若是某個操做失敗,客戶端能夠進行重試,若是重試成功了,那麼再次一切順利。可是,若是在重試後操做仍然失敗(與原子操做不一樣),則會產生反作用。不幸的是,在使用 Cassandra 的時候,這是程序員必須親自處理的一項復瑣事物。

搜索變得複雜

搜索並無構建爲 Cassandra 架構的核心,並且如前所述,搜索機制使用了排序順序,劃分在分層結構的頂部。Cassandra 支持次級索引,系統能夠利用一些受限的功能在此自動構建次級索引。當次級索引不工做時,用戶必須瞭解數據模型,並使用排序順序和切片來構建索引。

與構建搜索方法相關的三種類型的複雜領域:

  1. 在必定程度上,構建定製搜索方法須要程序員瞭解索引和存儲的細節。所以,Cassandra 須要的是更高水平的技能熟練的開發人員,而不是關係模型。
  2. 定製索引很大程度上取決於排序順序,並且被複雜化。有兩種類型的排序順序:第一,列始終根據名稱進行排序,第二,行排序順序只在使用保序分區程序(參閱 參考資料)時起做用。
  3. 添加一個新查詢一般須要新的索引以及與關係模型不一樣的代碼更改。這就要求開發人員先分析查詢,而後再存儲數據。

不同意使用超級列和保序分區程序

Cassandra 超級列在建模多層數據時很是有用,它能夠向層次結構再添加一個級別。然而,能夠與超級列一塊兒建模的任何事物也經過列進行支持。所以,超級列不提供附加能力,也不支持次級索引。所以,Cassandra 開發人員不同意使用超級列。儘管沒有固定的中斷支持的日期,但這種狀況會發生在未來的版本中。

Cassandra 中的分區程序決定了以何種方式在 Cassandra 節點之間分發(分開)數據,並且有多種實現方式。若是使用保序分區程序,那麼 rowID 會根據排序順序進行存儲,並且 Cassandra 也能夠跨各個 rowID 進行切片(搜索)。然而,該分區程序並非在其節點之間均勻地分發數據,若是使用大數據庫,一些節點可能負擔很重,而其餘節點則是空載的。所以,開發人員也不同意使用保序分區程序。

手動執行故障修復

若是 Cassandra 集羣中的一個節點已經失敗,若是您有副本的話,則該集羣將繼續工做。完整恢復,用來從新分發數據並彌補缺乏的副本,是一項經過名爲節點工具(參閱 參考資料)執行的手動操做。並且,執行手動操做時,系統是不可用的。

記得刪除

Cassandra 被設計爲:即便節點發生故障(或斷開鏈接)但隨後又恢復,節點仍會繼續工做,不會出現任何問題。其中一個結果就是這使得數據刪除複雜化。例如,假設一個節點出現故障。出現故障時,數據項已經從副本中刪除。當不可用的節點恢復的時候,若是 Cassandra 記得該數據項已經刪除,它會在同步流程中再次引入已刪除的數據項。

所以,Cassandra 必須記得該數據項已經刪除。在 0.8 發行版中,Cassandra 記得全部數據(即便已經刪除)。這就使得進行集中更新操做時磁盤使用率持續增加。Cassandra 不須要記得全部已刪除的數據,但事實剛好已經刪除了一個數據項。在之後的 Cassandra 發行版中會執行此項修復。

回頁首

結束語

本文深刻研究了在考慮 Cassandra 時不太明顯的一些細節。我描述了 Cassandra 數據模型,將它與關係數據模型進行了比較,並演示了一個使用 Cassandra 設計的典型模式。其中一個重要的觀察結果是,與關係模型有所不一樣,Cassandra 將數據分解成許多表格,並試圖在同一行內保留儘量多的數據,從而避免鏈接該數據進行檢索。

您還能夠看看基於 Cassandra 的方法的一些侷限性。可是,這些侷限性對於大多數 NoSQL 解決方案來講很常見,並且經常是支持高可擴展性時須要留意的一些設計權衡。

相關文章
相關標籤/搜索