Apache Cassandra 資料儲存模型

2021-09-22 02:35:07 字數 3284 閱讀 7108

我們在《apache cassandra 簡介》文章中介紹了 cassandra 的資料模型類似於 google 的 bigtable,對應的開源實現為 apache hbase,而且我們在 《hbase基本知識介紹及典型案例分析》 文章中簡單介紹了 apache hbase 的資料模型。按照這個思路,apache cassandra 的資料模型應該和 apache hbase 的資料模型很類似,那麼這兩者的資料儲存模型是不是一樣的呢?本文將為大家解答這些問題。我們從 keyspace -> table -> partition -> row -> cell 順序介紹。本文基於 apache cassandra 3.11.4 原始碼進行介紹的,不同版本可能有些不一樣。

cassandra 中的 keyspace 概念和 rdbms 裡面的 database 概念很類似,乙個 keyspace 包含多張表,一般將有關聯的資料表放到同乙個 keyspace 下面。keyspace 建立的時候可以指定副本策略,副本因子以及是否啟用 commitlog 機制(類似 hbase 中的 wal)。

cassandra 中表的概念和 rdbms 很類似。不同的是在 cassandra 中屬於同一張表的資料在物理上是分布在不同節點上儲存的,同一張表由多個 partition 組成。

cassandra 一般是由多台節點組成的,每台節點負責一定範圍的,如果使用 murmur3hash 的時候,每個節點負責的 token 類似於下面那樣:

所以 token 範圍為 -9223372036854775808 ~ -4611686018427387904 的資料儲存在 a 節點;同理,token 範圍為 -4611686018427387903 ~ -1 之間的資料儲存在 b節點,其他類似;每個 token 範圍由多個 partition 構成,每個 partition 由一行或多行資料組成,partition 類似下面的:

其中,username 為 partition key;type 為 clustering key。那麼在這種情況下,username = iteblog 的兩條資料構成乙個 partition;另外兩條構成分別構成兩個 partitions。在底層儲存每個 partition 格式如下:

從上圖可以看出,乙個 partition 是由 partitionheader、零個或多個 row (格式在後面介紹)以及 endpartition 三部分組成的。endpartition 這個用於標記 partition 結束,只占用乙個位元組,並使用 0x00000001 標記。partitionheader 的格式如下:

在底層儲存中,多個 partition 組成乙個 sstable(sorted-string table)檔案。那麼同乙個 sstable 檔案中的資料資料是如何組織的呢?答案是按照 partition key 計算得到的 token 公升序排序的。

上面看出,partition 裡面包含了零個或多個 row,這些 row 對應的 partition key 是一樣的。非 static 的 row 在磁碟儲存的格式如下:

上面除了 flags 、row body size 、 previous row body size 以及 primary key liveness timestamp 這四個字段一定會存在,其他字段需要滿足條件才會儲存。下面對上面字段進行介紹:

如果存在的列沒有佔總列數的一半,則按照全部列的順序儲存存在的列在排序後列的索引位置;

如果存在的列佔總列數超過一半,則按照全部列的順序儲存不存在的列在排序後列的索引位置。

可見,cassandra 通過將列的資訊(包括列的名稱、型別、表名、keyspace等資訊)儲存到對應 sstable 的 md-x-big-statistics.db 檔案中,相應的行只儲存列是否存在的標記資訊,這個可以節省儲存空間的占用。注意,hbase 儲存資料的時候每個 cell 都需要儲存列名稱和列族名稱的。

非 static row 的底層儲存格式已經在前面描述過,對於 static row 除了沒有上圖的 clustering info 資訊,其餘都一樣,所以這裡就不介紹了。

上圖中最後有 n 個 cell,那多個 cell 之間的順序是如何保證的呢?答案是按照列的名稱字典順序公升序排序的。比如我們表的定義如下:

create table iteblog (

user_id text,

type text,

action text,

username text,

age text,

email text,

primary key(user_id)

);

那麼 cell 的順序排列如下:

action -> age -> email -> type -> username
這個排序是通過 btree 實現的,row 的實現類為 btreerow。

cell 就是每列資料的底層實現,cell 裡面包含了列的定義資訊,比如是否被刪除、是否過期、是否設定了時間戳等。在 cassandra 裡面,column 有 ****** 和 complex(cassandra-8099引入的) 之分。non-frozen collection 或 udt(使用者自定義型別)的列是 complexcolumn(complex cell)。

我們正常使用的列就是屬於這種型別的,它的底層儲存格式如下:

如果列屬於 non-frozen collection 或 udt(使用者自定義型別),那麼這個屬於 complex cell,它的底層儲存格式如下:

可以看出,complex cell 和 ****** cell 大部分很類似,下面只介紹不一樣的地方:

在 cassandra 中, complex cell 的實現類是 complexcolumndata。

設計海量key value資料的儲存查詢模組

設計海量key value資料的儲存查詢模組 單機儲存100億大資料量的key value資料,要求能夠支援插入和查詢操作,單條資料長度不定,平均約1024位元組,假設可用記憶體10g,磁碟空間不限,請設計乙個儲存查詢模組,支援按照key來獲取對應的value,設計目標以查詢效能為先,盡量節約資源,...

mysql資料儲存 mysql資料儲存

頁 從磁碟讀取或者寫入資料時,我們通常會指定乙個緩衝區大小,達到緩衝區域大小才會寫入一次資料,較少io操作次數。同樣的從磁碟讀取資料時候,就作業系統而言,讀取一條較小的資料時,並不是只會返回我們需要的資料,而是會將這個資料前後的部分資料一併讀取到記憶體中,以備之後使用。這個從磁碟讀取的最小量的資料被...

mysql 取模遷移資料 mysql 取模分表

取模分表,根據時間維度進行分表自定義的hash 分表後的資料複製,一般採用insert select語句將原有表的資料匯入新的分表,或者直接copy原表的資料到分表中。比如根據id取模分四張表,分表後把原有資料複製示例如下。insert into user1 id,name,extdo,hobbys...