背景
小編最近在做一個(gè)數(shù)據(jù)類產(chǎn)品項(xiàng)目,每天涉及到幾十億數(shù)據(jù)的匯總計(jì)算,從不同維度、不同的關(guān)聯(lián)關(guān)系進(jìn)行匯總統(tǒng)計(jì),剛開(kāi)始時(shí)項(xiàng)目組使用的是hive,寫好大量的業(yè)務(wù)SQL計(jì)算邏輯后(中間有一些其他程序處理腳本),每天通過(guò)定時(shí)任務(wù)來(lái)生成數(shù)據(jù),然后把生成的數(shù)據(jù)推送到研發(fā)端的ES(Elasticsearch),研發(fā)端基于ES查詢數(shù)據(jù),給到前端來(lái)展示
但是,隨著項(xiàng)目的不斷深入,產(chǎn)品需求的快速迭代,之前的各種統(tǒng)計(jì)指標(biāo)更新迭代,基于hive數(shù)據(jù)庫(kù)的計(jì)算方式不能再滿足當(dāng)前快速迭代的場(chǎng)景。項(xiàng)目組經(jīng)過(guò)調(diào)研,最終選擇Clickhouse數(shù)據(jù)庫(kù),讓研發(fā)來(lái)每天通過(guò)查詢Clickhouse數(shù)據(jù)庫(kù),來(lái)統(tǒng)計(jì)生成各種統(tǒng)計(jì)指標(biāo),并把結(jié)果緩存至ES
項(xiàng)目數(shù)據(jù)架構(gòu)的大概思路:
- hive每日生成明細(xì)數(shù)據(jù),把這些明細(xì)數(shù)據(jù)導(dǎo)入Clickhouse
- 在Clickhouse中生成一些中間表,供研發(fā)人員查詢數(shù)據(jù)使用,方便進(jìn)行各種拼接組合
- 研發(fā)人員每日基于明細(xì)表、中間表,計(jì)算統(tǒng)計(jì)指標(biāo),把結(jié)果緩存至ES
小編環(huán)境
操作系統(tǒng)版本 與 Clickhouse 版本
cat /etc/redhat-release
# CentOS Linux release 7.2.1511 (Core)
clickhouse -V
#ClickHouse local version 24.7.2.13 (official build)
登錄客戶端
clickhouse-client -u xxxx --password xxxxxx -m
-u 或者 --user :指定用戶名
--password :密碼
-m 或者 --multiline :進(jìn)入客戶端后,運(yùn)行輸入多行sql語(yǔ)句
建表
在Clickhouse中,數(shù)據(jù)既可以存放到單個(gè)服務(wù)器節(jié)點(diǎn),也可以把數(shù)據(jù)分散存放到集群中各個(gè)節(jié)點(diǎn)服務(wù)器中,這個(gè)需要看數(shù)據(jù)量大小,來(lái)選擇合適的表類型
-
創(chuàng)建本地表
如果數(shù)據(jù)量比較小的話,建議選擇本地表,在數(shù)據(jù)查詢時(shí)以提高性能,可以節(jié)省節(jié)點(diǎn)之間數(shù)據(jù)傳輸?shù)臅r(shí)間,比如有幾千萬(wàn)行數(shù)據(jù)的表,完全可以選擇本地表,但是查詢數(shù)據(jù)時(shí),只能在當(dāng)前服務(wù)器節(jié)點(diǎn)查詢,其他服務(wù)器節(jié)點(diǎn)沒(méi)有該表
下面以用戶表為列,進(jìn)行建表操作:
create table test.user_table (
uid String comment '用戶id',
sex String comment '性別',
age UInt16 comment '年齡',
phone String comment '聯(lián)系電話'
)
engine = MergeTree()
order by uid;
- 數(shù)據(jù)類型需要注意是大寫開(kāi)頭 ,
String
、UInt16
,表引擎類型也必須大寫MergeTree
- 如果沒(méi)有指定主鍵的話,默認(rèn)用 order by 指定的字段
-
創(chuàng)建分布式表
分布式表在Clickhouse中,只是一個(gè)視圖,不實(shí)際存放數(shù)據(jù),指向?qū)嶋H存放數(shù)據(jù)的本地表,所以在創(chuàng)建分布式表時(shí),需要在各個(gè)服務(wù)器節(jié)點(diǎn)創(chuàng)建名字一模一樣的本地表
--在集群中創(chuàng)建實(shí)際存放數(shù)據(jù)的本地表
create table test.user_event on cluster data_cluster(
uid String comment '用戶id',
event String comment '事件名稱',
c_time DateTime comment '點(diǎn)擊時(shí)間',
dt Date comment '日期'
)
engine = MergeTree()
partition by dt
order by uid;
--創(chuàng)建分布式表
create table test.user_event_distributed (
uid String comment '用戶id',
event String comment '事件名稱',
c_time DateTime comment '點(diǎn)擊時(shí)間',
dt Date comment '日期'
)
engine = Distributed('data_cluster', 'test', 'user_event', rand())
;
分布式表需要選擇 Distributed
表引擎,其中
第1個(gè)參數(shù):集群名稱
第2個(gè)參數(shù):數(shù)據(jù)庫(kù)名
第3個(gè)參數(shù):數(shù)據(jù)表名
第3個(gè)參數(shù):分片key,數(shù)據(jù)被到不同服務(wù)器依據(jù)的字段,相同的值會(huì)被分配到同一臺(tái)服務(wù)器
如果在創(chuàng)建分布式表 test.user_event_distributed
時(shí)沒(méi)有指定 on cluster data_cluster
,那么創(chuàng)建是本地表,后續(xù)的查詢只能在建表的那個(gè)節(jié)點(diǎn)服務(wù)器查詢數(shù)據(jù),這里小編就創(chuàng)建的是一個(gè)本地表
查詢
Clickhouse 的sql 查詢語(yǔ)句和hive的比較類似,使用起來(lái)基本沒(méi)啥差距,只有極個(gè)別的函數(shù)不支持,下面小編列舉一下自己在使用時(shí),遇到的個(gè)別函數(shù):
- 沒(méi)有
nvl
函數(shù),需要用coalesce
代替 - 支持窗口函數(shù),
row_number
等 - 沒(méi)有
concat_ws
,需要用arrayStringConcat
代替 - 沒(méi)有
collect_list
,需要用groupArray
代替 - 一個(gè)好用的函數(shù),
arrayZip
,類似python中的zip - 沒(méi)有
split
函數(shù),需要用splitByString
代替 -
arrayMap
、arraySum
、arraySlice
等函數(shù)很好用,性能高
表變更
- 刪除特定分區(qū)
alter table test.user_event on cluster data_cluster drop partition '2024-11-30';
alter table test.user_event on cluster data_cluster delete where dt > '2024-11-15';
alter table test.user_event on cluster data_cluster delete where dt='2024-11-30';
- 刪除滿足特定條件數(shù)據(jù)
alter table test.user_event on cluster data_cluster delete where user_id='u00001';
自定義函數(shù)
不推薦使用外部語(yǔ)言編寫自定義函數(shù),例如:java、python 等,推薦使用自有的函數(shù),逐步組合實(shí)現(xiàn)自定義函數(shù),性能高
一個(gè)樣例:
--分割字符串并把類型轉(zhuǎn)換為整數(shù)
create function x_split as (x) ->
(
arrayMap(
y -> toUInt32(y),
splitByString(',', x)
)
);
歷史相關(guān)文章
- Clickhouse中創(chuàng)建生成日期序列自定義函數(shù)
- Python 基于pyhive庫(kù)操作hive
- Rust 是否會(huì)重寫 Python 解釋器與有關(guān)的庫(kù),替代 C 語(yǔ)言地位?
- Python中的Lambda匿名函數(shù)
以上是自己實(shí)踐中遇到的一些問(wèn)題,分享出來(lái)供大家參考學(xué)習(xí),歡迎關(guān)注微信公眾號(hào):DataShare ,不定期分享干貨