數倉選型必列入考慮的OLAP列式資料庫ClickHouse(上)

概述

定義

ClickHouse官網地址 //clickhouse.com/ 最新版本22.4.5.9

ClickHouse官網文檔地址 //clickhouse.com/docs/zh

ClickHouseGitHub源碼地址 //github.com/ClickHouse/ClickHouse

ClickHouse是俄羅斯的 Yandex 於 2016 年開源的用於在線分析處理查詢(OLAP :Online Analytical Processing)MPP架構列式存儲資料庫(DBMS:Database Management System),能夠使用 SQL 查詢實時生成分析數據報告。ClickHouse的全稱是Click Stream,Data WareHouse。ClickHouse可以做用戶行為分析,流批一體,其線性擴展和可靠性保障能夠原生支援 分片和副本,shard + replication,ClickHouse沒有走hadoop生態自己實現分散式存儲。

  • OLAP場景的關鍵特徵
    • 絕大多數是讀請求
    • 數據以相當大的批次(> 1000行)更新,而不是單行更新;或者根本沒有更新。
    • 已添加到資料庫的數據不能修改。
    • 對於讀取,從資料庫中提取相當多的行,但只提取列的一小部分。
    • 寬表,即每個表包含著大量的列
    • 查詢相對較少(通常每台伺服器每秒查詢數百次或更少)
    • 對於簡單查詢,允許延遲大約50毫秒
    • 列中的數據相對較小:數字和短字元串(例如,每個URL 60個位元組)
    • 處理單個查詢時需要高吞吐量(每台伺服器每秒可達數十億行)
    • 事務不是必須的
    • 對數據一致性要求低
    • 每個查詢有一個大表。除了他以外,其他的都很小。
    • 查詢結果明顯小於源數據。換句話說,數據經過過濾或聚合,因此結果適合於單個伺服器的RAM中
  • 很容易可以看出,OLAP場景與其他通常業務場景(例如,OLTP或K/V)有很大的不同, 因此想要使用OLTP或Key-Value資料庫去高效的處理分析查詢場景,並不是非常完美的適用方案。例如,使用OLAP資料庫去處理分析請求通常要優於使用MongoDB或Redis去處理分析請求。
  • 列式資料庫更適合OLAP場景的原因
    • 針對分析類查詢,通常只需要讀取表的一小部分列。在列式資料庫中你可以只讀取你需要的數據。例如,如果只需要讀取100列中的5列,這將幫助你最少減少20倍的I/O消耗。
    • 由於數據總是打包成批量讀取的,所以壓縮是非常容易的。同時數據按列分別存儲這也更容易壓縮。這進一步降低了I/O的體積。
    • 由於I/O的降低,這將幫助更多的數據被系統快取。
  • CPU
    • 向量引擎:所有的操作都是為向量而不是為單個值編寫的。這意味著多個操作之間的不再需要頻繁的調用,並且調用的成本基本可以忽略不計。操作程式碼包含一個優化的內部循環。
    • 程式碼生成:生成一段程式碼,包含查詢中的所有操作。

特性

  • 真正的列式資料庫管理系統:ClickHouse不單單是一個資料庫, 它是一個資料庫管理系統。因為它允許在運行時創建表和資料庫、載入數據和運行查詢,而無需重新配置或重啟服務.
  • 數據壓縮:支援通用壓縮編解碼器之外,ClickHouse還提供針對特定類型數據的專用編解碼器。
  • 數據的磁碟存儲:ClickHouse被設計用於工作在傳統磁碟上的系統,它提供每GB更低的存儲成本,但如果可以使用SSD和記憶體,它也會合理的利用這些資源。
  • 多核心並行處理
  • 多伺服器分散式處理
  • 支援SQL
  • 向量引擎
  • 實時的數據更新
  • 索引
  • 適合在線查詢
  • 支援近似計算
  • 自適應連接演算法
  • 支援數據複製和數據完整性
  • 角色的訪問控制
  • 限制
    • 沒有完整的事務支援。
    • 缺少高頻率,低延遲的修改或刪除已存在數據的能力。僅能用於批量刪除或修改數據,但這符合 GDPR
    • 稀疏索引使得ClickHouse不適合通過其鍵檢索單行的點查詢。

性能

  • 單個大查詢吞吐量:如果數據被放置在page cache中,則一個不太複雜的查詢在單個伺服器上大約能夠以2-10GB/s(未壓縮)的速度進行處理。
  • 處理短查詢的延遲時間:如果一個查詢使用主鍵並且沒有太多行(幾十萬)進行處理,並且沒有查詢太多的列,那麼在數據被page cache快取的情況下,它的延遲應該小於50毫秒。
  • 處理大量短查詢的吞吐量:在相同的情況下,ClickHouse可以在單個伺服器上每秒處理數百個查詢。
  • 寫入速度大約為50到200MB/s。如果您寫入的數據每行為1Kb,那麼寫入的速度為50,000到200,000行每秒。

為什麼ClickHouse這麼快?

  • 面向列的存儲:源數據通常包含數百甚至數千列,而報表可以只使用其中的少數列。系統需要避免讀取不必要的列,否則最昂貴的磁碟讀取操作將被浪費。
  • 索引:ClickHouse將數據結構保存在記憶體中,不僅允許讀取已使用的列,還允許讀取這些列的必要行範圍。
  • 數據壓縮:將同一列的不同值存儲在一起通常會帶來更好的壓縮比(與面向行的系統相比),因為在實際數據中,列的相鄰行通常具有相同或不那麼多的不同值。除了通用壓縮,ClickHouse還支援專門的編解碼器,可以使數據更加緊湊。
  • 向量化查詢執行:ClickHouse不僅在列中存儲數據,還在列中處理數據。它可以提高CPU快取利用率,並允許使用SIMD CPU指令。
  • 可伸縮性:ClickHouse可以利用所有可用的CPU核和磁碟執行單個查詢。不僅在單個伺服器上,而且在集群的所有CPU核和磁碟上也是如此。

安裝部署

系統要求

ClickHouse可以在任何具有x86_64,AArch64或PowerPC64LE CPU架構的Linux,FreeBSD或Mac OS X上運行。

官方預構建的二進位文件通常針對x86_64進行編譯,並利用SSE 4.2指令集,因此,除非另有說明,支援它的CPU使用將成為額外的系統需求。下面是檢查當前CPU是否支援SSE 4.2的命令:

$ grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"

要在不支援SSE 4.2AArch64PowerPC64LE架構的處理器上運行ClickHouse,您應該通過適當的配置調整從源程式碼構建ClickHouse

可用安裝包

  • DEB安裝包
  • RPM安裝包
  • Tgz安裝包
  • Docker安裝包
  • 其他環境安裝包
  • 使用源碼安裝

安裝包列表:

  • clickhouse-common-static — ClickHouse編譯的二進位文件。
  • clickhouse-server — 創建clickhouse-server軟連接,並安裝默認配置服務
  • clickhouse-client — 創建clickhouse-client客戶端工具軟連接,並安裝客戶端配置文件。
  • clickhouse-common-static-dbg — 帶有調試資訊的ClickHouse二進位文件。

單機RPM包安裝

單機部署比較簡單,執行完下面四條命令就可以通過clickhouse-client來操作了

yum install -y yum-utils
yum-config-manager --add-repo //packages.clickhouse.com/rpm/clickhouse.repo
yum install -y clickhouse-server clickhouse-client
/etc/init.d/clickhouse-server start

image-20220516110212533

集群部署

ClickHouse集群是一個同質集群,操作步驟如下

  • 分別在ckserver1(192.168.5.52)、ckserver2(192.168.5.53)、huawei27(192.168.12.27)這三台上按照上面的單機部署前面3行命令安裝ClickHouse服務端。需提前準備Zookeeper,這樣使用的是提前建好的3台Zookeeper集群(Zookeeper部署可以查看之前的文章)。
  • 在配置文件中設置集群配置。主要配置zookeeper、remote_servers和macros節點數據,而macros數據在每個節點分別配置,ckserver1配置為01,ckserver2配置02,huawei27配置為03,在下面示例為配置一個3個分片和3個副本的集群。
    <zookeeper>
        <node>
            <host>huawei27</host>
            <port>2181</port>
        </node>
        <node>
            <host>huawei28</host>
            <port>2181</port>
        </node>
        <node>
            <host>huawei29</host>
            <port>2181</port>
        </node>
    </zookeeper>


    <remote_servers>
        <perftest_3shards_3replicas>
            <shard>
                <replica>
                    <host>ckserver1</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>ckserver2</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>huawei27</host>
                    <port>9000</port>
                 </replica>
            </shard>
            <shard>
                <replica>
                    <host>ckserver1</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>ckserver2</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>huawei27</host>
                    <port>9000</port>
                 </replica>
            </shard>
            <shard>
                <replica>
                    <host>ckserver1</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>ckserver2</host>
                    <port>9000</port>
                 </replica>
                 <replica>
                    <host>huawei27</host>
                    <port>9000</port>
                 </replica>
            </shard>
        </perftest_3shards_3replicas>
    </remote_servers>

    <macros>
        <shard>01</shard>
        <replica>01</replica>
    </macros>

修改完配置後分別在三台上執行/etc/init.d/clickhouse-server start,查詢集群資訊如下

image-20220516161932927

介面

  • ClickHouse提供了一個原生命令行客戶端clickhouse-client客戶端支援命令行
    • --host, -h -– 服務端的host名稱, 默認是localhost。您可以選擇使用host名稱或者IPv4或IPv6地址。
    • --port – 連接的埠,默認值:9000。注意HTTP介面以及TCP原生介面使用的是不同埠。
    • --user, -u – 用戶名。 默認值:default
    • --password – 密碼。 默認值:空字元串。
    • --query, -q – 使用非交互模式查詢。
    • --database, -d – 默認當前操作的資料庫. 默認值:服務端默認的配置(默認是default)。
    • --multiline, -m – 如果指定,允許多行語句查詢(Enter僅代表換行,不代表查詢語句完結)。
    • --multiquery, -n – 如果指定, 允許處理用;號分隔的多個查詢,只在非交互模式下生效。
    • --format, -f – 使用指定的默認格式輸出結果。
    • --vertical, -E – 如果指定,默認情況下使用垂直格式輸出結果。這與–format=Vertical相同。在這種格式中,每個值都在單獨的行上列印,這種方式對顯示寬表很有幫助。
    • --time, -t – 如果指定,非交互模式下會列印查詢執行的時間到stderr中。
    • --stacktrace – 如果指定,如果出現異常,會列印堆棧跟蹤資訊。
    • --config-file – 配置文件的名稱。
    • --secure – 如果指定,將通過安全連接連接到伺服器。
    • --history_file — 存放命令歷史的文件的路徑。
    • --param_<name> — 查詢參數配置。
  • HTTP客戶端:HTTP介面允許您在任何程式語言的任何平台上使用ClickHouse,HTTP介面比原生介面受到更多的限制,但它具有更好的兼容性。默認情況下,clickhouse-server會在8123埠上監控HTTP請求(這可以在配置中修改)。如果你發送了一個未攜帶任何參數的GET /請求,它會返回一個字元串 «Ok.»
  • MySQL介面:ClickHouse支援MySQL wire通訊協議。
  • JDBC驅動
    • 官網驅動
    • 第三方驅動:
      • ClickHouse-Native-JDBC
      • clickhouse4j
  • ODBC驅動
  • C++客戶端庫
  • 第三方工具
    • 客戶端開發庫,支援多種語言如Python、Java、Go、Php、NodeJs、Swift、Ruby、R、Scala、C#、Kotlin等等
    • 第三方集成庫
      • 關係資料庫:MySQL、MSSQL、PostgreSQL
      • 消息隊列:Kafka
      • 流處理:Flink
      • 對象存儲:S3
      • 容器編排:Kubernetes
      • 監控:Grafana、Prometheus、Zabbix
    • 第三方代理
      • chproxy
      • KittenHouse
      • ClickHouse-Bulk
    • 第三方開發的可視化介面
      • 開源
        • Tabix
        • HouseOps
        • 燈塔
        • DBeaver
        • clickhouse-cli
        • clickhouse-flamegraph
        • DBM
      • 商業
        • Holistics
        • DataGrip

創建資料庫

默認情況下,ClickHouse使用Atomic資料庫引擎。它提供了可配置的table engines和SQL dialect。創建一個測試資料庫

CREATE DATABASE test ENGINE = Atomic;
use test;

image-20220521003209445

創建數據表

# -m支援多行輸入
clickhouse-client -m

使用最常見的MergeTree表引擎創建一張用戶資訊表user_info

CREATE TABLE user_info
(
    id INT,
    name String,
    age Int8,
    sex Int8,
    career INT,
    birthday Date
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(birthday)
ORDER BY (career, birthday);

image-20220521005636216

# user_info插入兩行數據
insert into user_info values(100,'張三',27,1,1000,'1998-05-21'),(101,'李婷',28,2,1001,'2000-07-25');
# 查詢user_info數據
select * from user_info;

image-20220521005709412

至此,ClickHouse的環境已經完全準備就緒,下一篇我們先通過一個案例需求學習ClickHouse使用,然後再層層深入。