原文地址:https://blog.csdn.net/weixin_45596022/article/details/115358757
一覆获,clickhouse特點(diǎn)
1.列式存儲
行存儲
好處是想查某個人所有的屬性時,可以通過一次磁盤查找加順序讀取就可以挠将。但是當(dāng)想查所有人的年齡時啄枕,需要不停的查找,或者全表掃描才行棍丐,遍歷的很多數(shù)據(jù)都是不需要的。
列存儲
列存儲的好處
1 對于列的聚合沧踏,計數(shù)歌逢,求和等統(tǒng)計操作要優(yōu)于行式存儲。
2 由于某一列的數(shù)據(jù)類型都是相同的翘狱,針對于數(shù)據(jù)存儲更容易進(jìn)行數(shù)據(jù)壓縮趋翻,每一列選擇更優(yōu)的數(shù)據(jù)壓縮算法,大大提高了數(shù)據(jù)的壓縮比重盒蟆。
3 由于數(shù)據(jù)壓縮比更好踏烙,一方面節(jié)省了磁盤空間,另一方面對于cache也有了更大的發(fā)揮空間历等。
2.DBMS的功能
幾乎覆蓋了標(biāo)準(zhǔn)SQL的大部分語法讨惩,包括 DDL和 DML ,以及配套的各種函數(shù)。
用戶管理及權(quán)限管理
數(shù)據(jù)的備份與恢復(fù)
3.多樣化引擎
clickhouse和mysql類似寒屯,把表級的存儲引擎插件化荐捻,根據(jù)表的不同需求可以設(shè)定不同的存儲引擎。目前包括合并樹寡夹、日志处面、接口和其他四大類20多種引擎。
4.高吞吐寫入能力
ClickHouse采用類LSM Tree的結(jié)構(gòu)菩掏,數(shù)據(jù)寫入后定期在后臺Compaction魂角。通過類LSM tree的結(jié)構(gòu),ClickHouse在數(shù)據(jù)導(dǎo)入時全部是順序append寫智绸,寫入后數(shù)據(jù)段不可更改野揪,在后臺compaction時也是多個段merge sort后順序?qū)懟卮疟P。順序?qū)懙奶匦郧评酰浞掷昧舜疟P的吞吐能力斯稳,即便在HDD上也有著優(yōu)異的寫入性能。
官方公開benchmark測試顯示能夠達(dá)到50MB-200MB/s的寫入吞吐能力迹恐,按照每行100Byte估算挣惰,大約相當(dāng)于50W-200W條/s的寫入速度。
5.數(shù)據(jù)分區(qū)與線程級并行
ClickHouse將數(shù)據(jù)劃分為多個partition,每個partition再進(jìn)一步劃分為多個index granularity憎茂,然后通過多個CPU核心分別處理其中的一部分來實現(xiàn)并行數(shù)據(jù)處理珍语。
在這種設(shè)計下,單條Query就能利用整機(jī)所有CPU唇辨。極致的并行處理能力廊酣,極大的降低了查詢延時。
所以赏枚,clickhouse即使對于大量數(shù)據(jù)的查詢也能夠化整為零平行處理亡驰。但是有一個弊端就是對于單條查詢使用多cpu,就不利于同時并發(fā)多條查詢饿幅。所以對于高qps的查詢業(yè)務(wù)凡辱,clickhouse并不是強(qiáng)項。
6.關(guān)聯(lián)查詢
clickhouse像很多OLAP數(shù)據(jù)庫一樣栗恩,單表查詢速度由于關(guān)聯(lián)查詢透乾,而且clickhouse的兩者差距更為明顯。
二磕秤,clickhouse安裝
1.取消打開文件數(shù)限制
在/etc/security/limits.conf乳乌、/etc/security/limits.d/90-nproc.conf這2個文件的末尾加入以下內(nèi)容:
2.取消SELINUX
修改/etc/selinux/config中的SELINUX=disabled后重啟。
3.開放端口
HTTP:8123
TCP:9000
4.安裝
5.修改配置文件
把 <listen_host>::</listen_host>的注解打開市咆,這樣的話才能讓clickhouse被除本機(jī)以外的服務(wù)器訪問汉操。
6.啟動ClickServer
7.使用client連接server
三,數(shù)據(jù)類型
1.整型
固定長度的整型蒙兰,包括有符號整型或無符號整型磷瘤。
適用場景:個數(shù),數(shù)量搜变,存儲id等采缚。
2.浮點(diǎn)型
建議盡可能以整數(shù)形式存儲數(shù)據(jù)。例如挠他,將固定精度的數(shù)字轉(zhuǎn)換為整數(shù)值扳抽,如時間用毫秒為單位表示,因為浮點(diǎn)型進(jìn)行計算時可能引起四舍五入的誤差绩社。
適用場景:一般數(shù)據(jù)值比較小摔蓝,不涉及大量的統(tǒng)計計算,精度要求不高的時候愉耙。比如保存商品的重量。
3.布爾型
沒有單獨(dú)的類型來存儲布爾值拌滋∑友兀可以使用 UInt8 類型,取值限制為 0 或 1。
4.Decimal型
有符號的浮點(diǎn)數(shù)赌渣,可在加魏铅、減和乘法運(yùn)算過程中保持精度。對于除法坚芜,最低有效數(shù)字會被丟棄(不舍入)览芳。
有三種聲明:
適用場景:一般金額字段,匯率鸿竖,利率等字段為了保證小數(shù)點(diǎn)精度沧竟,都是用Decimal進(jìn)行存儲。
5.字符串
1)String
字符串可以任意長度的缚忧。它可以包含任意的字節(jié)集悟泵,包含空字節(jié)。
2)FixedString(N)
固定長度 N 的字符串闪水,N 必須是嚴(yán)格的正自然數(shù)糕非。當(dāng)服務(wù)端讀取長度小于 N 的字符串時候,通過在字符串末尾添加空字節(jié)來達(dá)到 N 字節(jié)長度球榆。 當(dāng)服務(wù)端讀取長度大于 N 的字符串時候朽肥,將返回錯誤消息。
與String相比持钉,極少會使用FixedString衡招,因為使用起來不是很方便。
適用場景:名稱右钾,文字描述蚁吝,字符型編碼。固定長度的可以保存一些定長的內(nèi)容舀射,比如一些編碼窘茁,性別等,但是考慮到一定的變化風(fēng)險脆烟,帶來收益不夠明顯山林,所以定長字符串使用意義有限。
6.枚舉類型
包括 Enum8 和 Enum16 類型邢羔。Enum 保存'string'= integer 的對應(yīng)關(guān)系驼抹。
Enum8 用 'String'= Int8 對描述。
Enum16 用'String'= Int16對描述拜鹤。
用法演示:
創(chuàng)建一個帶有一個枚舉 Enum8('hello' = 1, 'world' = 2) 類型的列:
這個 x 列只能存儲類型定義中列出的值:'hello'或'world'框冀。如果嘗試保存任何其他值,ClickHouse 拋出異常敏簿。
從表中查詢數(shù)據(jù)時明也,ClickHouse 從 Enum 中輸出字符串值宣虾。
如果需要看到對應(yīng)行的數(shù)值,則必須將 Enum 值轉(zhuǎn)換為整數(shù)類型温数。
適用場景:對于一些狀態(tài)绣硝,類型的字段算是一種空間優(yōu)化,也算是一種數(shù)據(jù)約束撑刺。但是實際使用中往往因為一些數(shù)據(jù)內(nèi)容的變化增加一定的維護(hù)成本鹉胖,甚至是數(shù)據(jù)丟失的問題。所以謹(jǐn)慎使用够傍。
7.時間類型
目前clickhouse 有三種時間類型
Date 接受 年-月-日 的字符串比如 ‘2019-12-16’
Datetime 接受 年-月-日 時:分:秒 的字符串比如 ‘2019-12-16 20:50:10’
Datetime64 接受 年-月-日 時:分:秒.亞秒 的字符串比如 ‘2019-12-16 20:50:10.66’
日期類型甫菠,用兩個字節(jié)存儲,表示從 1970-01-01 (無符號) 到當(dāng)前的日期值王带。
還有很多數(shù)據(jù)結(jié)構(gòu)淑蔚,可以參考官方文檔:https://clickhouse.yandex/docs/zh/data_types/
8.數(shù)組
Array(T):由 T 類型元素組成的數(shù)組。
T 可以是任意類型愕撰,包含數(shù)組類型刹衫。 但不推薦使用多維數(shù)組,ClickHouse 對多維數(shù)組的支持有限搞挣。例如带迟,不能在 MergeTree 表中存儲多維數(shù)組。
可以使用array函數(shù)來創(chuàng)建數(shù)組囱桨,也可以使用方括號:[]仓犬。
創(chuàng)建數(shù)組案例:
四,表引擎
1.表引擎的使用
表引擎是clickhouse的一大特色舍肠〔蠹蹋可以說, 表引擎決定了如何存儲表的數(shù)據(jù)翠语。包括:
1)數(shù)據(jù)的存儲方式和位置叽躯,寫到哪里以及從哪里讀取數(shù)據(jù)。
2)支持哪些查詢以及如何支持肌括。
3)并發(fā)數(shù)據(jù)訪問点骑。
4)索引的使用(如果存在)。
5)是否可以執(zhí)行多線程請求谍夭。
6)數(shù)據(jù)復(fù)制參數(shù)黑滴。
表引擎的使用方式就是必須顯形在創(chuàng)建表時定義該表使用的引擎,以及引擎使用的相關(guān)參數(shù)紧索。如:
引擎的名稱大小寫敏感袁辈。
2.TinyLog
以列文件的形式保存在磁盤上,不支持索引珠漂,沒有并發(fā)控制吵瞻。一般保存少量數(shù)據(jù)的小表葛菇,生產(chǎn)環(huán)境上作用有限甘磨∠鹦撸可以用于平時練習(xí)測試用。
3.Memory
內(nèi)存引擎济舆,數(shù)據(jù)以未壓縮的原始形式直接保存在內(nèi)存當(dāng)中卿泽,服務(wù)器重啟數(shù)據(jù)就會消失。讀寫操作不會相互阻塞滋觉,不支持索引签夭。簡單查詢下有非常非常高的性能表現(xiàn)(超過10G/s)。
一般用到它的地方不多椎侠,除了用來測試第租,就是在需要非常高的性能,同時數(shù)據(jù)量又不太大(上限大概 1 億行)的場景我纪。
4.MergeTree
Clickhouse 中最強(qiáng)大的表引擎當(dāng)屬 MergeTree (合并樹)引擎及該系列(MergeTree)中的其他引擎慎宾。地位可以相當(dāng)于innodb之于Mysql。 而且基于MergeTree浅悉,還衍生出了很多小弟趟据,也是非常有特色的引擎。
建表語句
MergeTree其實還有很多參數(shù)(絕大多數(shù)用默認(rèn)值即可)术健,但是三個參數(shù)是更加重要的汹碱,也涉及了關(guān)于MergeTree的很多概念。
1)partition by 分區(qū)(可選項)
作用: 學(xué)過hive的應(yīng)該都不陌生荞估,分區(qū)的目的主要是降低掃描的范圍咳促,優(yōu)化查詢速度。
如果不填: 只會使用一個分區(qū)勘伺。
分區(qū)目錄: MergeTree 是以列文件+索引文件+表定義文件組成的跪腹,但是如果設(shè)定了分區(qū)那么這些文件就會保存到不同的分區(qū)目錄中。
**并行:**分區(qū)后娇昙,面對涉及跨分區(qū)的查詢統(tǒng)計尺迂,clickhouse會以分區(qū)為單位并行處理。
數(shù)據(jù)寫入與分區(qū)合并:
任何一個批次的數(shù)據(jù)寫入都會產(chǎn)生一個臨時分區(qū)冒掌,不會納入任何一個已有的分區(qū)噪裕。寫入后的某個時刻(大概10-15分鐘后),clickhouse會自動執(zhí)行合并操作(等不及也可以手動通過optimize執(zhí)行)股毫,把臨時分區(qū)的數(shù)據(jù)膳音,合并到已有分區(qū)中。
2) primary key主鍵(可選)
clickhouse中的主鍵铃诬,和其他數(shù)據(jù)庫不太一樣祭陷,它只提供了數(shù)據(jù)的一級索引苍凛,但是卻不是唯一約束。這就意味著是可以存在相同primary key的數(shù)據(jù)的兵志。
主鍵的設(shè)定主要依據(jù)是查詢語句中的 where 條件醇蝴。
根據(jù)條件通過對主鍵進(jìn)行某種形式的二分查找,能夠定位到對應(yīng)的index granularity,避免了全表掃描想罕。
index granularity: 直接翻譯的話就是索引粒度悠栓,指在稀疏索引中兩個相鄰索引對應(yīng)數(shù)據(jù)的間隔。clickhouse中的MergeTree默認(rèn)是8192按价。官方不建議修改這個值惭适,除非該列存在大量重復(fù)值,比如在一個分區(qū)中幾萬行才有一個不同數(shù)據(jù)楼镐。
稀疏索引:
稀疏索引的好處就是可以用很少的索引數(shù)據(jù)癞志,定位更多的數(shù)據(jù),代價就是只能定位到索引粒度的第一行框产,然后再進(jìn)行進(jìn)行一點(diǎn)掃描凄杯。
3)order by(必選)
order by 設(shè)定了分區(qū)內(nèi)的數(shù)據(jù)按照哪些字段順序進(jìn)行有序保存。
order by是MergeTree中唯一一個必填項茅信,甚至比primary key 還重要盾舌,因為當(dāng)用戶不設(shè)置主鍵的情況,很多處理會依照order by的字段進(jìn)行處理(比如去重和匯總)蘸鲸。
要求:主鍵必須是order by字段的前綴字段妖谴。
比如order by 字段是 (id,sku_id) 那么主鍵必須是id 或者(id,sku_id)
4)二級索引
目前在clickhouse的官網(wǎng)上二級索引的功能是被標(biāo)注為實驗性的。
所以使用二級索引前需要增加設(shè)置酌摇。
其中GRANULARITY N 是設(shè)定二級索引對于一級索引粒度的粒度膝舅。
那么在使用下面語句進(jìn)行測試,可以看出二級索引能夠為非主鍵字段的查詢發(fā)揮作用窑多。
5)數(shù)據(jù)TTL
TTL即Time To Live仍稀,MergeTree提供了可以管理數(shù)據(jù)或者列的生命周期的功能。
①列級別TTL
插入數(shù)據(jù)
②表級TTL
針對整張表埂息,下面的這條語句是數(shù)據(jù)會在create_time之后10秒丟失技潘。
涉及判斷的字段必須是Date或者Datetime類型,推薦使用分區(qū)的日期字段千康。
能夠使用的時間周期:
5.ReplacingMergeTree
ReplacingMergeTree是MergeTree的一個變種享幽,它存儲特性完全繼承MergeTree,只是多了一個去重的功能拾弃。
盡管MergeTree可以設(shè)置主鍵值桩,但是primary key其實沒有唯一約束的功能。如果你想處理掉重復(fù)的數(shù)據(jù)豪椿,可以借助這個ReplacingMergeTree奔坟。
去重時機(jī):數(shù)據(jù)的去重只會在合并的過程中出現(xiàn)携栋。合并會在未知的時間在后臺進(jìn)行,所以你無法預(yù)先作出計劃咳秉。有一些數(shù)據(jù)可能仍未被處理婉支。
去重范圍:如果表經(jīng)過了分區(qū),去重只會在分區(qū)內(nèi)部進(jìn)行去重滴某,不能執(zhí)行跨分區(qū)的去重磅摹。
所以ReplacingMergeTree能力有限, ReplacingMergeTree 適用于在后臺清除重復(fù)的數(shù)據(jù)以節(jié)省空間霎奢,但是它不保證沒有重復(fù)的數(shù)據(jù)出現(xiàn)。
ReplacingMergeTree()填入的參數(shù)為版本字段饼灿,重復(fù)數(shù)據(jù)保留版本字段值最大的幕侠。
如果不填版本字段,默認(rèn)保留最后一條碍彭。
通過測試得到結(jié)論:
實際上是使用order by 字段作為唯一鍵晤硕。
去重不能跨分區(qū)。
只有合并分區(qū)才會進(jìn)行去重庇忌。
認(rèn)定重復(fù)的數(shù)據(jù)保留舞箍,版本字段值最大的。
如果版本字段相同則保留最后一條皆疹。
6.SummingMergeTree
對于不查詢明細(xì)疏橄,只關(guān)心以維度進(jìn)行匯總聚合結(jié)果的場景。如果只使用普通的MergeTree的話略就,無論是存儲空間的開銷捎迫,還是查詢時臨時聚合的開銷都比較大。
Clickhouse 為了這種場景表牢,提供了一種能夠“預(yù)聚合”的引擎窄绒,SummingMergeTree.
表定義
插入數(shù)據(jù)
通過結(jié)果可以得到以下結(jié)論:
以SummingMergeTree()中指定的列作為匯總數(shù)據(jù)列〈扌耍可以填寫多列必須數(shù)字列彰导,如果不填,以所有非維度列且為數(shù)字列的字段為匯總數(shù)據(jù)列敲茄。
以order by 的列為準(zhǔn)位谋,作為維度列。
其他的列保留第一行折汞。
不在一個分區(qū)的數(shù)據(jù)不會被聚合倔幼。
設(shè)計聚合表的話,唯一鍵值爽待、流水號可以去掉损同,所有字段全部是維度翩腐、度量或者時間戳。
能不能直接 select total_amount from province_name=’’ and create_date=’xxx’ 來得到匯總值膏燃?
不行茂卦,可能會包含一些還沒來得及聚合的臨時明細(xì)
select sum(total_amount) from province_name=’’ and create_date=’xxx’
五,SQL操作
基本上來說傳統(tǒng)關(guān)系型數(shù)據(jù)庫(以MySQL為例)的SQL語句组哩,基本支持但是也有不一樣的地方等龙。這里不會從頭講解SQL語法只介紹Clickhouse與標(biāo)準(zhǔn)SQL(MySQL)不一致的地方。
1.insert
基本與標(biāo)準(zhǔn)SQL(MySQL)基本一致
包括標(biāo)準(zhǔn) insert into [table_name] values(…),(….)
以及從表到表的插入
2.update和delete
ClickHouse提供了Delete 和Update的能力,這類操作被稱為Mutation查詢,它可以看做Alter 的一種肤无。
雖然可以實現(xiàn)修改和刪除亦渗,但是和一般的OLTP數(shù)據(jù)庫不一樣,Mutation語句是一種很“重”的操作,而且不支持事務(wù)。
“重”的原因主要是每次修改或者刪除都會導(dǎo)致放棄目標(biāo)數(shù)據(jù)的原有分區(qū),重建新分區(qū)位仁。所以盡量做批量的變更,不要進(jìn)行頻繁小數(shù)據(jù)的操作方椎。
刪除操作
修改操作
由于操作比較“重”聂抢,所以 Mutation語句分兩步執(zhí)行,同步執(zhí)行的部分其實只是進(jìn)行新增數(shù)據(jù)新增分區(qū)和并把舊分區(qū)打上邏輯上的失效標(biāo)記棠众。直到觸發(fā)分區(qū)合并的時候琳疏,才會刪除舊數(shù)據(jù)釋放磁盤空間。
3.查詢操作
clickhouse基本上與標(biāo)準(zhǔn)SQL 差別不大摄欲。
支持子查詢
支持CTE(with 子句)
支持各種JOIN轿亮, 但是JOIN操作無法使用緩存,所以即使是兩次相同的JOIN語句胸墙,Clickhouse也會視為兩條新SQL我注。
不支持窗口函數(shù)。
不支持自定義函數(shù)迟隅。
GROUP BY 操作增加了 with rollup\with cube\with total 用來計算小計和總計但骨。
模擬數(shù)據(jù)
with rollup : 從右至左去掉維度進(jìn)行小計。
with cube : 從右至左去掉維度進(jìn)行小計智袭,再從左至右去掉維度進(jìn)行小計奔缠。
with totals: 只計算合計。
4.alter操作
同mysql的修改字段基本一致吼野。
5.導(dǎo)出數(shù)據(jù)
"select toHour(create_time) hr? ,count(*) from test1.order_wide where dt='2020-06-23'? group by hr" --format CSVWithNames> ~/rs1.csv
支持格式的地址
六校哎,副本
副本的目的主要是保障數(shù)據(jù)的高可用性,即使一臺clickhouse節(jié)點(diǎn)宕機(jī),那么也可以從其他服務(wù)器獲得相同的數(shù)據(jù)闷哆。
1.副本寫入流程
2.配置
這時需要啟動zookeeper集群 和另外一臺clickhouse 服務(wù)器腰奋。
另外一臺clickhouse服務(wù)器的安裝完全和第一臺一直即可。
在兩臺服務(wù)器的/etc/clickhouse-server/config.d目錄下創(chuàng)建一個名為metrika.xml的配置文件:
在 /etc/clickhouse-server/config.xml中增加
在兩臺電腦上分別建表
A機(jī)器
B機(jī)器
3.參數(shù)解釋
ReplicatedMergeTree 中抱怔,
第一參數(shù)是分片的zk_path劣坊,一般按照:
/clickhouse/table/{shard}/{table_name} 的格式寫,如果只有一個分片就寫01即可屈留。
第二個參數(shù)是副本名稱局冰,相同的分片副本名稱不能相同。
insert語句
七灌危,分片集群
副本雖然能夠提高數(shù)據(jù)的可用性康二,降低丟失風(fēng)險,但是對數(shù)據(jù)的橫向擴(kuò)容沒有解決乍狐。每臺機(jī)子實際上必須容納全量數(shù)據(jù)赠摇。
要解決數(shù)據(jù)水平切分的問題,需要引入分片的概念浅蚪。通過分片把一份完整的數(shù)據(jù)進(jìn)行切分,不同的分片分布到不同的節(jié)點(diǎn)上烫罩。在通過Distributed表引擎把數(shù)據(jù)拼接起來一同使用惜傲。
Distributed表引擎本身不存儲數(shù)據(jù),有點(diǎn)類似于MyCat之于MySql贝攒,成為一種中間件盗誊,通過分布式邏輯表來寫入、分發(fā)隘弊、路由來操作多臺節(jié)點(diǎn)不同分片的分布式數(shù)據(jù)哈踱。
1.配置
配置的位置還是在之前的metrika.xml,配置分片如下的結(jié)構(gòu)
2.讀寫原理
3.三節(jié)點(diǎn)版本配置
metrika.xml
4.Distribute 分布式表
其中參數(shù):
Distributed( 集群名稱梨熙,庫名开镣,本地表名,分片鍵)
分片鍵必須是整型數(shù)字
也可以rand()
插入數(shù)據(jù)
來觀察數(shù)據(jù)的分布是否正確咽扇。
八邪财,java操作clickHouse
1.依賴
2.基本操作
九,SpringBoot整合ClickHouse
案例基于:Druid連接池和mybatis進(jìn)行整合质欲。Druid 1.1.10 版本 SQL Parser對clickhouse的開始提供支持树埠。