ClickHouse(14)ClickHouse合併樹MergeTree家族表引擎之VersionedCollapsingMergeTree詳細解析

来源:https://www.cnblogs.com/the-pig-of-zf/archive/2023/06/21/17495702.html
-Advertisement-
Play Games

[toc] >VersionedCollapsingMergeTree引擎繼承自MergeTree並將摺疊行的邏輯添加到合併數據部分的演算法中。VersionedCollapsingMergeTree用於相同的目的摺疊樹但使用不同的摺疊演算法,允許以多個線程的任何順序插入數據。特別是,Version列有 ...


目錄

VersionedCollapsingMergeTree引擎繼承自MergeTree並將摺疊行的邏輯添加到合併數據部分的演算法中。VersionedCollapsingMergeTree用於相同的目的摺疊樹但使用不同的摺疊演算法,允許以多個線程的任何順序插入數據。特別是,Version列有助於正確摺疊行,即使它們以錯誤的順序插入。相比之下,CollapsingMergeTree只允許嚴格連續插入。

VersionedCollapsingMergeTree引擎的作用如下:

  • 允許快速寫入不斷變化的對象狀態。
  • 刪除後臺中的舊對象狀態。 這顯著降低了存儲體積。

建表語法

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = VersionedCollapsingMergeTree(sign, version)
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

針對於VersionedCollapsingMergeTree(sign, version)兩個特殊的參數。

sign — 指定行類型的列名:1是一個“state”行,-1是一個“cancel”行列數據類型應為Int8.
version — 指定對象狀態版本的列名。列數據類型應為UInt*.

使用場景

考慮一種情況,您需要為某個對象保存不斷變化的數據。對於一個對象有一行,併在發生更改時更新該行是合理的。但是,對於資料庫管理系統來說,更新操作非常昂貴且速度很慢,因為它需要重寫存儲中的數據。如果需要快速寫入數據,則不能接受更新,但可以按如下順序將更改寫入對象。使用 Sign 列寫入行時。如果Sign=1這意味著該行是一個對象的狀態(讓我們把它稱為“state”行)。如果Sign=-1它指示具有相同屬性的對象的狀態的取消(讓我們稱之為“cancel”行)。 還可以使用 Version 列,它應該用單獨的數字標識對象的每個狀態。

例如,我們要計算用戶在某個網站上訪問了多少頁面以及他們在那裡的時間。在某個時間點,我們用用戶活動的狀態寫下麵的行:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │         5 │      146 │    1 │
└─────────────────────┴───────────┴──────────┴──────┘

在稍後的某個時候,我們註冊用戶活動的變化,並用以下兩行寫入它。

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │         5 │      146 │   -1 │
│ 4324182021466249494 │         6 │      185 │    1 │
└─────────────────────┴───────────┴──────────┴──────┘

第一行取消對象(用戶)的先前狀態。它應該複製已取消狀態的所有欄位,除了Sign。

第二行包含當前狀態。

因為我們只需要用戶活動的最後一個狀態,所以需要刪除,摺疊對象的無效(舊)狀態。VersionedCollapsingMergeTree會在在合併數據部分時執行此操作。

最終摺疊之後的結果如下。

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │         5 │      146 │    1 │       1 |
│ 4324182021466249494 │         5 │      146 │   -1 │       1 |
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

對於使用VersionedCollapsingMergeTree有下麵三個需要註意的點。

  1. 寫入數據的程式應該記住對象的狀態以取消它。該“cancel”字元串應該是“state”與相反的字元串Sign。這增加了存儲的初始大小,但允許快速寫入數據。
  2. 列中長時間增長的數組由於寫入負載而降低了引擎的效率。數據越簡單,效率就越高。
  3. SELECT結果很大程度上取決於對象變化歷史的一致性。準備插入數據時要準確。不一致的數據將導致不可預測的結果,例如會話深度等非負指標的負值。

合併演算法

合併演算法主要是下麵兩個。

  • 當ClickHouse合併數據部分時,它會刪除具有相同主鍵和版本但Sign值不同的一對行.行的順序並不重要。
  • 當ClickHouse插入數據時,它會按主鍵對行進行排序。如果Version列不在主鍵中,ClickHouse將其隱式添加到主鍵作為最後一個欄位並使用它進行排序。

ClickHouse不保證具有相同主鍵的所有行都將位於相同的結果數據部分中,甚至位於相同的物理伺服器上。對於寫入數據和隨後合併數據部分都是如此。此外,ClickHouse流程SELECT具有多個線程的查詢,並且無法預測結果中的行順序。這意味著,如果有必要從VersionedCollapsingMergeTree表中得到完全“collapsed”的數據,聚合是必需的。

也就是說ClickHouse並不保證查詢出來的數據一定是經過合併摺疊的。如果要保證一定經過摺疊合併,需要查詢的時候使用GROUP BY和聚合函數。

要計算數量,使用sum(Sign)而不是count()。要計算的東西的總和,使用sum(Sign * x)而不是sum(x),並添加HAVING sum(Sign) > 0。可以在一定程度上避免數據未摺疊導致的數據問題。

如果您需要手動摺疊合併,但是,如果沒有聚合(例如,要檢查是否存在其最新值與某些條件匹配的行),則可以使用FINAL修飾FROM條件這種方法效率低下,不應與大型表一起使用。

使用例子、

示例數據:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │         5 │      146 │    1 │       1 |
│ 4324182021466249494 │         5 │      146 │   -1 │       1 |
│ 4324182021466249494 │         6 │      185 │    1 │       2 |
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

創建表:

CREATE TABLE UAct
(
    UserID UInt64,
    PageViews UInt8,
    Duration UInt8,
    Sign Int8,
    Version UInt8
)
ENGINE = VersionedCollapsingMergeTree(Sign, Version)
ORDER BY UserID

插入數據:


INSERT INTO UAct VALUES (4324182021466249494, 5, 146, 1, 1)

INSERT INTO UAct VALUES (4324182021466249494, 5, 146, -1, 1),(4324182021466249494, 6, 185, 1, 2)

我們用兩個INSERT查詢以創建兩個不同的數據部分。
如果我們使用單個查詢插入數據,ClickHouse將創建一個數據部分,並且永遠不會執行任何合併。

獲取數據:

SELECT * FROM UAct

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │         5 │      146 │    1 │       1 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │         5 │      146 │   -1 │       1 │
│ 4324182021466249494 │         6 │      185 │    1 │       2 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

我們在這裡看到了什麼,摺疊的合併部分在哪裡?我們使用兩個創建了兩個數據部分INSERT查詢。該SELECT查詢是在兩個線程中執行的,結果是行的隨機順序。由於數據部分尚未合併,因此未發生摺疊合併。 ClickHouse在我們無法預測的未知時間點合併數據部分。

這就是為什麼我們需要聚合:

SELECT
    UserID,
    sum(PageViews * Sign) AS PageViews,
    sum(Duration * Sign) AS Duration,
    Version
FROM UAct
GROUP BY UserID, Version
HAVING sum(Sign) > 0

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Version─┐
│ 4324182021466249494 │         6 │      185 │       2 │
└─────────────────────┴───────────┴──────────┴─────────┘

如果我們不需要聚合,並希望強制摺疊,我們可以使用 FINAL 修飾符 FROM 條款

SELECT * FROM UAct FINAL

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │         6 │      185 │    1 │       2 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

資料分享

ClickHouse經典中文文檔分享

參考文章

本文來自博客園,作者:張飛的豬,轉載請註明原文鏈接:https://www.cnblogs.com/the-pig-of-zf/p/17495702.html

公眾號:張飛的豬大數據分享,不定期分享大數據學習的總結和相關資料,歡迎關註。

個人網站"張飛的豬編程工作室"鏈接: https://zhangfeidezhu.com


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...