1. 程式人生 > 實用技巧 >基於騰訊雲端儲存COS的ClickHouse資料冷熱分層方案

基於騰訊雲端儲存COS的ClickHouse資料冷熱分層方案

一、ClickHouse簡介

ClickHouse是一個用於聯機分析(OLAP)的列式資料庫管理系統(DBMS),支援PB級資料量的互動式分析,ClickHouse最初是為YandexMetrica 世界第二大Web分析平臺而開發的。多年來一直作為該系統的核心元件被該系統持續使用著。目前為止,該系統在ClickHouse中有超過13萬億條記錄,並且每天超過200多億個事件被處理。它允許直接從原始資料中動態查詢並生成報告。自2016 年開源以來,ClickHouse 憑藉其數倍於業界頂尖分析型資料庫的極致效能,成為互動式分析領域的後起之秀,發展速度非常快。

二、ClickHouse的架構簡述

ClickHouse是一種分散式的資料庫管理系統,不同於其他主流的大資料元件,它並沒有採用Hadoop生態的HDFS檔案系統,而是將資料存放於伺服器的本地盤,同時使用資料副本的方式來保障資料的高可用性。

ClickHouse使用分散式表實現資料的分散式儲存和查詢。下圖演示了一個分散式表是如何儲存的:

分片(Shard):包含資料的不同部分的伺服器,要讀取所有資料必須訪問所有的分片。通過將分散式表的資料存放到多個Shard實現計算和儲存的橫向擴充套件。

副本(Replica):每個切片的資料都包含多個副本,要讀取資料時訪問任一副本上的資料即可。通過副本機制保證儲存資料的單節點失效時資料的可用性。只有MergeTree型別的表引擎可以支援多副本。ClickHouse是在表的引擎而不是資料庫引擎實現資料的副本功能的,所以副本是表級別的而不是伺服器級別的。資料在插入ReplicatedMergeTree引擎的表的時候會做資料的主備同步以實現資料的多副本,在同步的過程中使用ZooKeeper做分散式協調。

分散式表(Distributed table):使用分散式引擎建立的分散式表並不儲存資料,但是能夠將查詢任務分佈到多臺伺服器上處理。在建立分散式表的過程中,ClickHouse會先在每個Shard上建立本地表,本地表只在對應的節點內可見,然後再將建立的本地表對映給分散式表。這樣使用者在訪問分散式表的時候,ClickHouse會自動根據叢集的架構資訊,將請求轉發給對應的本地表。

綜上所述,一個ClickHouse叢集由分片組成,而每個分片又由多個數據副本組成。一個副本對應了組成ClickHouse叢集中的一個伺服器節點,並使用該伺服器節點上的本地盤儲存資料。通過分散式表、資料分片以及資料副本,ClickHouse實現了叢集的橫向擴充套件能力並提供資料的高可用保護。

三、資料的分層儲存

1. 資料的分層儲存

從19.15這個版本開始,ClickHouse開始支援multi-volume storage這個功能,它允許將ClickHouse表儲存在包含多個裝置的卷當中,利用這個特性,我們可以在volume中定義不同型別的磁碟,根據資料的“冷”、“熱”程度將資料存放在不同型別的磁碟上(我們可以稱之為Tier Storage),以實現效能與成本的平衡。

以下是Altinity網站上關於multi-volume storage的架構圖。

ClickHouse的配置檔案中和磁碟相關的術語:

磁碟(Disk):已經格式化成檔案系統的塊裝置。
預設磁碟(Default Disk):在伺服器設定中通過path引數指定的資料儲存,預設路徑為/var/lib/clickhouse/。
卷(Volume):有序的磁碟的集合。
儲存策略(Storage Policy):卷的集合以及卷之間資料移動的規則。

ClickHouse儲存及儲存相關的策略是寫在配置檔案中的,你可以在/etc/clickhouse-server/config.xml檔案中新增關於卷、磁碟以及儲存策略的定義,也可以在/etc/clickhouse-server/config.d目錄中新建xml型別的配置檔案,新增相關的儲存的定義。

2. ClickHouse支援的磁碟型別

ClickHouse主要支援DiskLocal和DiskS3兩種常用的磁碟型別。

2.1 DiskLocal型別磁碟

DiskLocal型別磁碟使用伺服器本地磁碟,並指明資料儲存的路徑。ClickHouse有一個名為default的DiskLocal型別的磁碟,路徑為/var/lib/clickhouse/。

同樣我可以自定義新增DiskLocal型別的磁碟,在ClickHouse中新增一個DiskLocal型別的磁碟,使用路徑問/data,步驟如下:

a. 伺服器新掛載一塊硬碟,並格式化檔案系統並掛載在/data目錄下。

b. 在/etc/clickhouse-server/config.d目錄下新建一個名為storage.xml的檔案,並新增如下內容:

<yandex>
    <storage_configuration>
        <disks>
            <localdisk> <!-- disk name -->
                <path>/data/</path>
            </localdisk>
        </disks>
        <policies>
            <local>
                <volumes>
                    <main>
                        <disk>localdisk</disk>  
                    </main>
                </volumes>
            </local>
        </policies>
    </storage_configuration>
</yandex>

c. 重啟clickhouse-server服務之後,檢視新加的磁碟:

2.2 DiskS3型別磁碟

ClickHouse支援DiskS3型別磁碟,使用S3介面訪問儲存於物件儲存上的資料,原生支援AWS物件儲存S3以及騰訊雲物件儲存COS。

下面我們在ClickHouse中再新增一個DiskS3型別的磁碟,這裡我們使用騰訊雲端儲存COS的一個儲存桶作為例子,編輯/etc/clickhouse-server/config.d/storage.xml檔案,內容如下:

<yandex>
    <storage_configuration>
        <disks>
            <localdisk> <!-- disk name -->
                <path>/data/</path>
            </localdisk>
            <cos>
                <type>s3</type>
                <endpoint>http://example-1250000000.cos.ap-shanghai.myqcloud.com/ck/</endpoint>
                <access_key_id>AKIDxxxxxxxx</access_key_id>
                <secret_access_key>xxxxxxxxxxx</secret_access_key>
            </cos>
        </disks>
        <policies>
            <local>
                <volumes>
                    <main>
                        <disk>localdisk</disk>  
                    </main>
                </volumes>
            </local>
            <cos>
                <volumes>
                    <main>
                        <disk>cos</disk>
                    </main>
                </volumes>
            </cos>
        </policies>
    </storage_configuration>
</yandex>    

在上面的配置檔案中,我們定義了兩個磁碟,一個名為localdisk的Disklocal型別的磁碟,使用本地/data路徑儲存資料,另外一個是名為cos的DiskS3型別的磁碟,使用騰訊雲物件儲存的example-1250000000儲存桶儲存資料,並需要在配置檔案中配置可以訪問該儲存桶賬號的SecretId和SecretKey,上面的例子中access_key_id和secret_access_key分別對應訪問COS儲存桶賬號的SecretId和SecretKey。接下來在策略中我們定義了兩個策略用於將資料儲存至本地磁碟或者物件儲存COS。

在ClickHouse中重新載入配置後,能查詢到剛才我們定義的磁碟及儲存策略:

在後面的章節我們會詳細演示如何將ClickHouse表中的資料儲存在本地儲存或者物件儲存COS上。

3. 資料移動策略

通過在配置檔案中配置多個不同型別的磁碟以及儲存策略,ClickHouse能夠將資料儲存在不同的儲存介質中,同時ClickHouse還支援配置移動策略以實現資料在不同儲存介質之間自動的移動。

3.1 基於move factor的資料移動策略
這是一種基於檔案大小以及卷(volume)中各個磁碟(Disk)容量使用情況來移動資料的策略。

下面的例子中,我們建立了一個名為“moving_from_local_to_cos”的策略,在策略中我們定義了兩種儲存,第一個是名為“hot”的卷,這個卷中有一個名為localdisk的磁碟並設定這個磁碟上的檔案最大值為1GB;第二個是名為“cold”的卷,這個卷中有一個名為cos的磁碟。

最後是move_factor引數,表示當卷的可用容量低於move_factor引數設定的值的時候,資料將被自動的移動到下一個卷,本例中當hot卷的容量低於30%的時候,hot卷中的資料將被自動的移動到cold卷。

<moving_from_local_to_cos>
    <volumes>
        <hot>
            <disk>localdisk</disk>
            <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
        </hot>
        <cold>
            <disk>cos</disk>
        </cold>
    </volumes>
    <move_factor>0.3</move_factor>
</moving_from_local_to_cos>

有一點需要強調的是,配置檔案裡各個卷的順序非常重要,當ClickHouse有新資料寫入的時候,資料會優先寫入到第一個卷,再依次寫入後面的卷。同時move factor的的移動策略也是將資料從前面的卷移動到後面的卷。所以我們在定義卷的時候,要把資料優先寫入的卷放在配置檔案的前面。在實際的使用場景中一般是把高效能儲存放在前面,把高容量低成本的儲存放在後面,這樣實現新的熱資料存放在高效能儲存以獲取極致的實時查詢效能、老的歷史冷資料存放在高容量儲存以獲取較低的儲存成本以及較好的批量查詢效能。

3.2 基於TTL的資料移動策略

ClickHouse支援表級別的TTL表示式,允許使用者設定基於時間的規則,從而能夠自動的在指定的磁碟或者卷之間移動資料,以實現了資料在不同的儲存層之間的分層儲存。下面列舉了幾種比較典型的TTL的寫法,從例子我們可以看出,TTL表示式只是一個簡單的SQL表示式,裡邊包含了時間以及時間的間隔,下面是TTL的一些例子:

TTL date_time + INTERVAL 1 MONTH
TTL date_time + INTERVAL 15 HOUR
TTL date_time + toIntervalMonth(ttl)
TTL date_time + toIntervalHour(ttl)
TTL date_time + INTERVAL ttl MONTH
TTL date_time + INTERVAL ttl HOUR

在新建表的時候,我們可以在建表的SQL語句後面加上TTL的表示式,用於根據TTL設定的時間策略在磁碟或者卷之間移動或者刪除資料塊。

TTL date_time + INTERVAL 6 MONTH DELETE,
   date_time + INTERVAL 1 WEEK TO VOLUME 'localdisk',
   date_time + INTERVAL 4 WEEK TO DISK 'cos';

下面是一個完整的建表的語句,並配置了TTL,根據LastModifiedDate中的時間,預設將資料塊放置到ttlhot卷,當LastModifiedDate的值超過三個月時將對應的資料塊移動到ttlcold卷。

CREATE TABLE cos_inventory_ttl (
 appid UInt64,
 bucket String,
 key String,
 size UInt64,
 LastModifiedDate DateTime,
 etag String,
 storage_class String,
 IsMultipartUploaded String,
 Replicationstatus String
) ENGINE = MergeTree() 
ORDER BY LastModifiedDate
TTL LastModifiedDate to volume 'ttlhot',
  LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'
SETTINGS
storage_policy='ttl',
index_granularity=8192;

四、基於騰訊雲端儲存COS的分層儲存實現

在前面的章節,我們介紹了ClickHouse分散式表的資料是如何儲存、ClickHouse支援的磁碟型別以及如何配置資料在各型別儲存中移動的策略,接下來我們來詳細介紹一下如何利用ClickHouse的這些特性以及物件儲存COS的優勢來解決我們在使用ClickHouse中遇到的一些問題。

1. 當前ClickHouse資料儲存的問題

在和使用ClickHouse交流的時候,客戶經常會有這樣一個困擾:追求極致查詢效能一般是客戶選擇使用ClickHouse的原因,所以客戶一般會選擇騰訊雲的增強型SSD雲硬碟存放ClickHouse的資料,用於提升查詢的效能,但是增強型SSD雲硬碟價格昂貴,綜合性能及成本考慮,客戶會選擇將比較老的歷史資料從ClickHouse中清除。雖然絕大多數的查詢都集中在最新的資料上,但是業務方偶爾還是會有訪問老的歷史資料的需求,如何平衡成本以及業務方偶爾訪問歷史資料的需求成為ClickHouse系統管理者頭疼的問題。

以上面提到的客戶的困擾為例,根據業務方的需求,ClickHouse叢集需要儘可能儲存更長時間的資料,如果這些長時間儲存的資料都存放在增強型SSD雲盤上,成本將會非常的高。而在實際的業務場景中,可能有95%以上的查詢互動都發生在最近一天生成的資料上,剩下5%的的任務都是發生在較早的資料上的批量查詢任務,如果將大量的訪問頻率較低的歷史資料都放在高成本的增強型SSD上,會造成極大的容量及效能的浪費。

下圖是引用Altinity的一個ClickHouse在實際使用中關於查詢頻率和對應的資料時間的統計:

2. 騰訊雲端儲存COS的優勢

物件儲存COS是騰訊雲端儲存產品,是無目錄層次結構、無資料格式限制、無容量上限,支援 HTTP/HTTPS 協議訪問的分散式儲存服務。

COS以儲存桶的方式組織資料,儲存桶空間無容量上限,按需使用、按量計費、按需擴充套件。使用COS作為備份儲存有如下優勢:

按需使用按量結算:COS開服即用,開通即可用,登入騰訊雲官網註冊賬號後,一鍵式開通COS服務,就可使用,無需建設成本。COS提供海量的儲存空間,無需規劃儲存容量。COS提供按量付費的方式,避免資源浪費、降低使用成本。
高可靠高可用性:COS提供高達99.99%的服務可用性,以及高達12個9的資料永續性,為資料提供可靠的保障。
高效能:單個儲存桶QPS可達30,000以及15Gbit/s頻寬。
開放相容:COS提供全相容行業標杆AWS S3的介面,提供terrafrom等多種生態工具支援。
資料安全:COS提供多租戶許可權隔離,支援HTTPS加密傳輸,支援SSE-KMS加密等多種資料加密方式。
低成本:提供具有競爭力的產品定價,提供標準儲存、低頻儲存以及歸檔儲存三種類型,並支援資料生命週期管理,進一步降低雲端儲存成本。

基於以上推騰訊雲物件儲存COS的優勢,我們推薦使用騰訊雲增強型SSD雲盤以及騰訊雲物件儲存COS構建ClickHouse的分層儲存結構。增強型SSD雲盤存放最近時間生成並且訪問頻繁的“熱資料”、COS存放較早時間生成且訪問不頻繁的“冷資料”,並在建表的時候使用TTL實現資料根據特定時間策略的自動沉降。

通過設定的資料分層策略,我們實現了將最新生成的、互動式查詢頻率較高的資料存放在高效能的增強型SSD雲盤上,同時根據資料的訪問場景設定策略,當資料不再被高頻率互動式查詢訪問時將資料轉移到高容量、低成本的二級儲存上COS,在不犧牲互動式查詢效能的情況下極大地降低了總體使用成本。

通過該方案我們能夠同時兼顧以下各方面:

極致效能:最新的資料存放在增強型SSD雲盤,為業務的即時查詢提供極致效能 ;同時COS提供的高頻寬、高併發為歷史資料的批量查詢提供了較高的效能。
超大容量:騰訊雲物件儲存COS提供了無容量上限的儲存空間,將歷史資料存放在COS上後,不用再擔心磁碟空間不足刪除資料後導致無法滿足業務部門較早資料查詢的需求。
低成本:相對於本地儲存,COS提供了更低的成本和更高的可用性。除了標準儲存以外,COS還提供成本更低的標準、低頻、歸檔以及深度歸檔四種類型儲存,根據資料需要訪問的頻率需求,將資料沉降至對應的儲存型別,進一步降低成本。

3. 基於COS的ClickHouse資料分層實現

在配置資料分層之前,我們提前準備如下環境:

本地儲存:掛載增強型SSD硬碟,並格式化為本地檔案系統,掛載到/data路徑,用於存放熱資料。
COS儲存桶:新建COS儲存桶,用於存放冷資料,獲取具有訪問該儲存桶許可權賬號的SecretId以及SecretKey。

3.1 配置ClickHouse磁碟及策略
首先我們需要配置/etc/clickhouse-server/config.d/storage.xml檔案,在配置中的部分定義本地磁碟的路徑以及COS儲存桶的URL、訪問賬號的SecretId和SecretKey,同時在中定義名為的策略,該策略中定義了兩個卷,分別包含本地儲存以及COS儲存桶。

以下是配置檔案的詳細內容(請根據實際場景替換本地路徑以及COS的URL、access_key_id和secret_access_key):

<yandex>
    <storage_configuration>
        <disks>
            <localdisk> <!-- disk name -->
                <path>/data/</path>
            </localdisk>
            <cos>
                <type>s3</type>
                <endpoint>http://example-1250000000.cos.ap-shanghai.myqcloud.com/ck/</endpoint>
                <access_key_id>AKIDxxxxxxxx</access_key_id>
                <secret_access_key>xxxxxxxxxxx</secret_access_key>
            </cos>
        </disks>
        <policies>
            <ttl>
                <volumes>
                    <ttlhot>
                        <disk>localdisk</disk>
                        <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                    </ttlhot>
                    <ttlcold>
                        <disk>cos</disk>
                      <max_data_part_size_bytes>5368709119</max_data_part_size_bytes>
                    </ttlcold>
                </volumes>
            </ttl>
        </policies>
    </storage_configuration>
</yandex>

修改完配置檔案之後,在clickhouse客戶端重新載入配置後就能看到新配置的磁碟及策略:

3.2 匯入資料至ClickHouse
完成儲存配置後,我們需要建立一個配置了TTL策略的表,並往表中匯入資料以驗證我們配置的分層策略。

這裡我選擇我們一個COS儲存桶的清單作為匯入的資料來源,首先根據清單中各列的內容,在ClickHouse中新建一個名為cos_inventory_ttl的表,同時配置TTL策略,根據LastModifiedDate的值將熱資料存放至ttlhot卷,而三個月以上的冷資料存放至ttlcold卷。

CREATE TABLE cos_inventory_ttl (
 appid UInt64,
 bucket String,
 key String,
 size UInt64,
 LastModifiedDate DateTime('Asia/Shanghai'),
 etag String,
 storage_class String,
 IsMultipartUploaded String,
 Replicationstatus String
) ENGINE = MergeTree() 
ORDER BY LastModifiedDate
TTL LastModifiedDate to volume 'ttlhot',
  LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'
SETTINGS
storage_policy='ttl',
index_granularity=8192;

然後再將生成的清單檔案下載到本地並解壓成csv檔案,然後將csv資料批量匯入到ClickHouse資料庫中:

for i in *.csv
do
echo $i;
cat $i |sed 's/\+08:00//g' |clickhouse-client -u default --password='123456' --query="INSERT INTO cos_inventory_ttl FORMAT CSV";
done

3.3 驗證資料

資料匯入完成後,我們首先檢視總共匯入的資料的行數:

接下來,我們可以查詢資料的分割槽存放的儲存卷:

這裡我們可以看到,資料已經按照預期儲存在不同的磁碟上,其中約兩千多萬行資料存放在本地磁碟,約六千多萬行資料存放在COS上。

接下來我們可以做一個查詢測試,這裡我們統計一下cos-user/目錄下最近三個月份生成的檔案的總大小:

五、總結

通過配置在ClickHouse中配置不同的儲存介質以及相應的策略,我們實現了ClickHouse資料在不同儲存介質的自動儲存。COS無限的儲存容量以及超低的儲存成本,使我們的ClickHouse叢集在提供極致查詢效能的同時又能以低成本的方式實現資料的長期存放。

六、參考文件

1、ClickHouse官方文件:https://clickhouse.tech/docs/zh/

2、Altinity網站參考文件

https://altinity.com/blog/2019/11/27/amplifying-clickhouse-capacity-with-multi-volume-storage-part-1
https://altinity.com/blog/2020/3/23/putting-things-where-they-belong-using-new-ttl-moves
https://altinity.com/presentations/clickhouse-tiered-storage-intro

3、《騰訊雲ClickHouse支援資料均衡服務》:https://cloud.tencent.com/developer/article/1688478

4、《互動式分析領域,為何ClickHouse能夠殺出重圍?》:https://mp.weixin.qq.com/s/9PZTws3KSzlybHXM6XC2hg

5、物件儲存COS文件中心:https://cloud.tencent.com/document/product/436