Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

評估和調整資料模型

建立實體模型後,您需要採取一些步驟來評估和改善表格設計,以確保最佳效能。

計算分割區大小

您首先要找出表格的分割區是否過大,換句話說,是否太寬。分割區大小以儲存在分割區中的儲存格 (值) 數量來衡量。Cassandra 的硬性限制為每個分割區 20 億個儲存格,但您在達到此限制之前可能會遇到效能問題。

若要計算分割區大小,請使用下列公式

\[N_v = N_r (N_c - N_{pk} - N_s) + N_s\]

分割區中的值 (或儲存格) 數量 (Nv) 等於靜態欄位數 (Ns) 加上列數 (Nr) 與每列值數量的乘積。每列值數量定義為欄位數 (Nc) 減去主鍵欄位數 (Npk) 和靜態欄位數 (Ns)。

欄位的數量傾向於相對靜態,儘管可以在執行階段變更表格。因此,分割區大小的主要驅動力是分割區中的列數。這是決定分割區是否有可能過大的關鍵因素,您必須考慮到這一點。二十億個值聽起來很多,但在每毫秒測量數十或數百個值的感測器系統中,值的數量開始快速增加。

讓我們來看看其中一個表格,以分析分割區大小。由於它採用每間飯店一個分割區的廣泛分割區設計,請查看 available_rooms_by_hotel_date 表格。該表格總共有四個欄位 (Nc = 4),包括三個主鍵欄位 (Npk = 3) 和沒有靜態欄位 (Ns = 0)。將這些值代入公式,結果為

\[N_v = N_r (4 - 3 - 0) + 0 = 1N_r\]

因此,此表格的值數等於列數。您仍需要確定列數。為此,請根據應用程式設計進行估計。該表格儲存每間飯店中每個房間的記錄,每晚一個記錄。假設系統將用於一次儲存兩年的庫存,系統中有 5,000 間飯店,每間飯店平均有 100 間房間。

由於每間飯店都有分割區,因此每個分割區的估計列數如下

\[N_r = 100 間房間/飯店 \times 730 天 = 73,000 列\]

每個分割區的列數相對較少,不會造成太大問題,但如果您開始儲存更多日期的庫存,或無法使用 TTL 妥善管理庫存大小,您可能會開始遇到問題。您可能仍想考慮分割這個大分割區,您很快就會看到如何執行此操作。

在執行調整大小計算時,很容易假設變數的標稱或平均情況,例如列數。考慮也計算最壞情況,因為這類預測在成功的系統中往往會成真。

計算磁碟大小

除了計算分區大小之外,估計群集中每個您計畫儲存的資料表所需的磁碟空間量也是個好主意。為了確定大小,請使用下列公式來確定分區 St 的大小

\[S_t = \displaystyle\sum_i sizeOf\big (c_{k_i}\big) + \displaystyle\sum_j sizeOf\big(c_{s_j}\big) + N_r\times \bigg(\displaystyle\sum_k sizeOf\big(c_{r_k}\big) + \displaystyle\sum_l sizeOf\big(c_{c_l}\big)\bigg) +\]
\[N_v\times sizeOf\big(t_{avg}\big)\]

這比前一個公式複雜一些,但讓我們一次分解一點。讓我們先看看符號

  • 在此公式中,ck 指的是分區金鑰欄,cs 指的是靜態欄,cr 指的是一般欄,而 cc 指的是分群欄。

  • tavg 這個詞是指每個儲存在儲存格中的平均位元組數,例如時間戳記。一般會使用 8 位元組來估計這個值。

  • 您會從先前的計算中辨識出列數 Nr 和值數 Nv

  • sizeOf() 函數是指每個參考欄的 CQL 資料類型的位元組大小。

第一個詞項要求您將分區金鑰欄的大小加總起來。對於此範例,available_rooms_by_hotel_date 資料表有一個單一分區金鑰欄,也就是 hotel_id,其類型為 text。假設飯店識別碼是簡單的 5 個字元代碼,您會有一個 5 位元組值,因此分區金鑰欄大小的總和為 5 位元組。

第二個詞項要求您將靜態欄的大小加總起來。此資料表沒有靜態欄,因此大小為 0 位元組。

第三個詞項最為複雜,而且有充分的理由—它正在計算分區中儲存格的大小。將分群欄和一般欄的大小加總起來。兩個分群欄是 date(4 位元組)和 room_number(2 位元組短整數),總和為 6 位元組。只有一個一般欄,也就是布林值 is_available,大小為 1 位元組。將一般欄大小(1 位元組)加上分群欄大小(6 位元組)加總起來,總共為 7 位元組。要完成這個詞項,將此值乘以列數(73,000),結果為 511,000 位元組(0.51 MB)。

第四個項目只是計算 Cassandra 為每個儲存格儲存的元資料。在 Cassandra 3.0 及更新版本所使用的儲存格式中,特定儲存格的元資料量會根據儲存的資料類型而有所不同,以及是否為個別儲存格指定自訂時間戳記或 TTL 值。對於此表格,重複使用前一個計算值 (73,000) 的值,並乘以 8,得到 0.58 MB。

將這些項目加總,您會得到最後的估計值

\[區段大小 = 16 位元組 + 0 位元組 + 0.51 MB + 0.58 MB = 1.1 MB\]

此公式是區段在磁碟上實際大小的近似值,但準確度足以相當有用。記得區段必須能夠放入單一節點,看起來表格設計不會對磁碟儲存造成太多負擔。

Cassandra 的儲存引擎已在 3.0 版本中重新實作,包括 SSTable 檔案的新格式。先前的格式將群集欄位的個別副本儲存在每個儲存格的記錄中。較新的格式消除了此重複,這會縮小儲存資料的大小,並簡化計算該大小的公式。

請記住,此估計值只計算資料的單一複本。您需要將在此取得的值乘以區段數目和鍵空間複製策略所指定的複本數目,才能決定每個表格所需的總容量。當您規劃叢集時,這會派上用場。

分割大型區段

如前所述,目標是設計表格,這些表格可以使用觸及單一區段的查詢提供您需要的資料,或如果無法做到,則使用最少可能的區段數目。然而,如範例所示,設計接近 Cassandra 內建限制的寬區段樣式表格非常有可能。對表格執行調整大小分析可能會顯示區段可能太大,不論是在值數目、磁碟大小或兩者。

分割大型區段的技術很簡單:在區段金鑰中新增一個額外欄位。在大部分情況下,將其中一個現有欄位移至區段金鑰中就足夠了。另一個選項是在表格中引入一個額外欄位,作為分片金鑰,但這需要額外的應用程式邏輯。

繼續檢視可用的房間範例,如果您將 date 欄位新增至 available_rooms_by_hotel_date 表格的分區金鑰,每個分區便會表示特定飯店在特定日期的房間可用性。這肯定會產生明顯更小的分區,甚至可能太小,因為連續幾天的資料可能會在不同的節點上。

另一種稱為分桶的技術通常用於將資料切分為中型分區。例如,您可以透過將 month 欄位新增至分區金鑰,將 available_rooms_by_hotel_date 表格分桶,可能表示為整數。與原始設計的比較顯示在下圖中。雖然 month 欄位與 date 部分重複,但它提供了一種將相關資料分組在不會過大的分區中的好方法。

image

如果您真的強烈希望保留廣泛的分區設計,您可以將 room_id 新增至分區金鑰,以便每個分區表示房間在所有日期的可用性。由於沒有識別出涉及搜尋特定房間可用性的查詢,因此第一或第二種設計方法最適合應用程式的需求。

改編自 Cassandra, The Definitive Guide。由 O’Reilly Media, Inc. 出版。版權所有 © 2020 Jeff Carpenter、Eben Hewitt。保留所有權利。經許可使用。