背景
隨著互聯(lián)網(wǎng)的快速發(fā)展和互聯(lián)網(wǎng)+物聯(lián)網(wǎng)的場(chǎng)景不斷增加惫搏,信息數(shù)據(jù)量正在呈幾何式的爆發(fā)辜昵。這些海量數(shù)據(jù)決定著企業(yè)的未來(lái)發(fā)展歼争。這些數(shù)據(jù)中铃慷,有用的價(jià)值數(shù)據(jù)就需要數(shù)據(jù)分析師或分析系統(tǒng)去分析蹋笼。
但是使用一般的工具己滿(mǎn)足不了和承受不住龐大的數(shù)據(jù)帶來(lái)的壓力展姐。近兩年針對(duì)大數(shù)據(jù)的開(kāi)發(fā)工具開(kāi)啟了開(kāi)源大潮躁垛,為大數(shù)據(jù)開(kāi)發(fā)者提供了多個(gè)選擇,但是也增加了開(kāi)發(fā)者選擇合適的工具的難度圾笨。
尤其是新入行的開(kāi)發(fā)者教馆,會(huì)增加很大的學(xué)習(xí)成本,框架的多樣化和復(fù)雜度成了很大的難題擂达。有時(shí)候會(huì)需要各種框架土铺、工具、中間件板鬓、平臺(tái)等整合到一起才能完成數(shù)據(jù)分析悲敷。
因此,大數(shù)據(jù)分析平臺(tái)簡(jiǎn)單化和統(tǒng)一化成了開(kāi)發(fā)者剛需俭令。
什么是ClickHouse后德?
ClickHouse是一個(gè)用于聯(lián)機(jī)分析(OLAP)的列式數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)。我們可能都聽(tīng)過(guò)clickhouse速度很快抄腔,也聽(tīng)說(shuō)過(guò)它不能處理高并發(fā)等各種特性瓢湃,下面我們就從它的工作原理來(lái)分析下這些結(jié)論到底對(duì)不對(duì),以及為什么會(huì)是這樣赫蛇。 要想弄清楚ClickHouse做查詢(xún)分析那么快的原因箱季,咱們可以反客為主,先想想自己設(shè)計(jì)一款OLAP數(shù)據(jù)庫(kù)的核心技術(shù)應(yīng)該有哪些棍掐?然后我們?cè)賮?lái)看看ClickHouse是如何實(shí)現(xiàn)如何工作的藏雏。 我們先看兩條查詢(xún)語(yǔ)句場(chǎng)景一:select username, number from user where id = 1;場(chǎng)景二:select department, avg(age) from student group by department;第一種場(chǎng)景: 如果數(shù)據(jù)量小,并且數(shù)據(jù)是結(jié)構(gòu)化的作煌,使用MySQL去存儲(chǔ)即可掘殴; 如果數(shù)據(jù)量大,不管是不是結(jié)構(gòu)化的粟誓,可以轉(zhuǎn)成key-value的存儲(chǔ)奏寨,使用 HBase,Cassandra等來(lái)解決。 第二種場(chǎng)景: 如果數(shù)據(jù)量小鹰服,并且數(shù)據(jù)是結(jié)構(gòu)化的病瞳,使用MySQL去存儲(chǔ)即可; 如果數(shù)據(jù)量大悲酷,不管是不是結(jié)構(gòu)化的套菜,設(shè)計(jì)一個(gè)專(zhuān)門(mén)用來(lái)做分析的存儲(chǔ)計(jì)算引擎解決分析的低效率問(wèn)題。
一设易、如何設(shè)計(jì)一個(gè)oltp數(shù)據(jù)庫(kù)逗柴?
- 內(nèi)存 + 磁盤(pán):保證處理效率,也保證數(shù)據(jù)安全
- 內(nèi)存:必須經(jīng)過(guò)設(shè)計(jì)顿肺,內(nèi)存具備優(yōu)秀的數(shù)據(jù)結(jié)構(gòu)戏溺,保證基本的讀寫(xiě)高效渣蜗,甚至為了不同的需求,可以讓讀寫(xiě)效率傾斜旷祸。
- 磁盤(pán):數(shù)據(jù)必須存放在磁盤(pán)耕拷,保證數(shù)據(jù)安全。磁盤(pán)數(shù)據(jù)文件必須經(jīng)過(guò)精心設(shè)計(jì)托享,保證掃描磁盤(pán)數(shù)據(jù)文件的高效率
- 數(shù)據(jù)排序:在海量數(shù)據(jù)中要想保證低延時(shí)的隨機(jī)讀寫(xiě)操作斑胜,數(shù)據(jù)最好是排序的
- 范圍分區(qū):當(dāng)數(shù)據(jù)排序之后,可以進(jìn)行范圍分區(qū)嫌吠,來(lái)平攤負(fù)載,讓多臺(tái)服務(wù)器聯(lián)合起來(lái)對(duì)外提供服務(wù)
- 跳表:基于數(shù)據(jù)排序+范圍分區(qū)構(gòu)建索引表掺炭,形成跳表的拓?fù)浣Y(jié)構(gòu)辫诅,方便用戶(hù)操作時(shí)快速定位數(shù)據(jù)分區(qū)的位置
-
LSM-Tree存儲(chǔ)引擎:把隨機(jī)寫(xiě)變成順序追加,在通過(guò)定期合并的方式來(lái)合并數(shù)據(jù)涧狮,去除無(wú)效數(shù)據(jù)炕矮,從而實(shí)現(xiàn)數(shù)據(jù)的刪除和修改。
海量數(shù)據(jù)中者冤,如果進(jìn)行高效率的查詢(xún)的核心思想:設(shè)計(jì)一種架構(gòu)肤视,能夠快速把待搜尋的數(shù)據(jù)范圍降低到原來(lái)的1/n,然后再結(jié)合索引或者熱點(diǎn)數(shù)據(jù)放在內(nèi)存等思路涉枫,就能實(shí)現(xiàn)高效率的查詢(xún)了邢滑。 那么一個(gè)專(zhuān)門(mén)用來(lái)做OLAP分析的存儲(chǔ)引擎該如何設(shè)計(jì)呢?如何在海量數(shù)據(jù)中愿汰,針對(duì)大量數(shù)據(jù)進(jìn)行查詢(xún)分析呢困后?一些常見(jiàn)的方案和手段如下:
- 列式存儲(chǔ) + 字段類(lèi)型統(tǒng)一
- 列裁剪
- 數(shù)據(jù)排序
- 數(shù)據(jù)分區(qū)分片 + 分布式查詢(xún)
- 預(yù)聚合
- 利用CPU特性:向量化引擎,操作系統(tǒng)必須支持
- 主鍵索引+二級(jí)索引+位圖索引+布隆索等
- 支持近似計(jì)算pv
- 定制引擎:多樣化的存儲(chǔ)引擎滿(mǎn)足不同場(chǎng)景的特定需要
- 多樣化算法選擇:Volnitsky高效字符串搜索算法和HyperLogLog基于概率高效去重算法
總結(jié)一下:?jiǎn)螚l記錄的增刪改等操作衬廷,通過(guò)數(shù)據(jù)的橫向劃分摇予,做到數(shù)據(jù)操作的快速定位,在海量數(shù)據(jù)查詢(xún)分析中吗跋,一般就是針對(duì)某些列做分析侧戴,既然并不是全部列,那么把數(shù)據(jù)做縱向切分把表中的數(shù)據(jù)按照列來(lái)單獨(dú)存儲(chǔ)跌宛,那么在做分析的時(shí)候酗宋,同樣可以快速把待查詢(xún)分析的數(shù)據(jù)總量降低到原來(lái)表的1/n,同樣提高效率疆拘。
二本缠、總體介紹:
ClickHouse是一個(gè)用于聯(lián)機(jī)分析(OLAP)的列式數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)。來(lái)自于2011 年在納斯達(dá)克上市的俄羅斯本土搜索引擎企業(yè)Yandex公司入问,誕生之初就是為了服務(wù)Yandex公司自家的Web流量分析產(chǎn)品Yandex.Metrica丹锹,后來(lái)經(jīng)過(guò)演變稀颁,逐漸形成為現(xiàn)在的 ClickHouse,全稱(chēng)是:Click Stream,Data WareHouse ClickHouse.
官網(wǎng):https://clickhouse.tech/
ClickHouse具有ROLAP楣黍、在線(xiàn)實(shí)時(shí)查詢(xún)匾灶、完整的DBMS功能支持、列式存儲(chǔ)租漂、不需要任何數(shù)據(jù)預(yù)處理阶女、支持批量更新、擁有非常完善的SQL支持和函數(shù)哩治、支持高可用秃踩、不依賴(lài) Hadoop復(fù)雜生態(tài)、開(kāi)箱即用等許多特點(diǎn)业筏。
在1億數(shù)據(jù)集體量的情況下憔杨,ClickHouse的平均響應(yīng)速度是Vertica的2.63倍、InfiniDB的17倍蒜胖、MonetDB的27倍消别、Hive的126倍、MySQL的429倍以及Greenplum的10倍台谢。
詳細(xì)的測(cè)試結(jié)果可以查閱:https://clickhouse.tech/benchmark/dbms/寻狂。
ClickHouse非常適用于商業(yè)智能領(lǐng)域(也就是我們所說(shuō)的BI領(lǐng)域),除此之外朋沮,它也能夠被廣泛應(yīng)用于廣告流量蛇券、Web、App流量樊拓、電信怀读、金融、電子商務(wù)骑脱、信息安全菜枷、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)等眾多其他領(lǐng)域叁丧。
ClickHouse是近年來(lái)備受關(guān)注的開(kāi)源列式數(shù)據(jù)庫(kù)啤誊,主要用于數(shù)據(jù)分析(OLAP)領(lǐng)域。目前國(guó)內(nèi)社區(qū)火熱拥娄,各個(gè)大廠紛紛跟進(jìn)大規(guī)模使用:
- 今日頭條內(nèi)部用ClickHouse來(lái)做用戶(hù)行為分析蚊锹,內(nèi)部一共幾千個(gè)ClickHouse節(jié)點(diǎn),單集群最大1200節(jié)點(diǎn)稚瘾,總數(shù)據(jù)量幾十PB牡昆,日增原始數(shù)據(jù)300TB左右。
- 騰訊內(nèi)部用ClickHouse做游戲數(shù)據(jù)分析,并且為之建立了一整套監(jiān)控運(yùn)維體系丢烘。
- 攜程內(nèi)部從18年7月份開(kāi)始接入試用柱宦,目前80%的業(yè)務(wù)都跑在ClickHouse上。每天數(shù)據(jù)增量十多億播瞳,近百萬(wàn)次查詢(xún)請(qǐng)求掸刊。
- 快手內(nèi)部也在使用ClickHouse,存儲(chǔ)總量大約10PB赢乓,每天新增200TB忧侧,90%查詢(xún)小于3S。
三:ClickHouse表引擎介紹
表引擎在ClickHouse中的作用十分關(guān)鍵牌芋,直接決定了數(shù)據(jù)如何存儲(chǔ)和讀取蚓炬、是否支持并發(fā)讀寫(xiě)、是否支持index躺屁、支持的query種類(lèi)肯夏、是否支持主備復(fù)制等。
- 數(shù)據(jù)的存儲(chǔ)方式和位置楼咳,寫(xiě)到哪里以及從哪里讀取數(shù)據(jù)
- 支持哪些查詢(xún)以及如何支持。
- 并發(fā)數(shù)據(jù)訪(fǎng)問(wèn)烛恤。
- 索引的使用(如果存在)母怜。
- 是否可以執(zhí)行多線(xiàn)程請(qǐng)求。
- 數(shù)據(jù)復(fù)制參數(shù)
具體可看官網(wǎng):https://clickhouse.tech/docs/zh/engines/table-engines/
關(guān)于ClickHouse的底層引擎缚柏,其實(shí)可以分為數(shù)據(jù)庫(kù)引擎和表引擎兩種苹熏。在此,我們重點(diǎn)關(guān)注表引擎币喧。
關(guān)于庫(kù)引擎轨域,簡(jiǎn)單總結(jié)一下:ClickHouse也支持在創(chuàng)建庫(kù)的時(shí)候,指定庫(kù)引擎杀餐,目前支持5種干发,分別是:Ordinary,Dictionary史翘,Memory枉长,Lazy,MySQL琼讽,其實(shí)Ordinary 是默認(rèn)庫(kù)引擎必峰,在此類(lèi)型庫(kù)引擎下,可以使用任意類(lèi)型的表引擎钻蹬。5種庫(kù)引擎說(shuō)明:
- Ordinary引擎:默認(rèn)引擎吼蚁,如果不指定數(shù)據(jù)庫(kù)引擎創(chuàng)建的就是Ordinary數(shù)據(jù)庫(kù)
- Dictionary引擎:此數(shù)據(jù)庫(kù)會(huì)自動(dòng)為所有數(shù)據(jù)字典創(chuàng)建表
- Memory引擎:所有數(shù)據(jù)只會(huì)保存在內(nèi)存中,服務(wù)重啟數(shù)據(jù)消失问欠,該數(shù)據(jù)庫(kù)引擎只能夠創(chuàng)建Memory引擎表
- MySQL引擎:改引擎會(huì)自動(dòng)拉取遠(yuǎn)端MySQL中的數(shù)據(jù)肝匆,并在該庫(kù)下創(chuàng)建 MySQL表引擎的數(shù)據(jù)表
- Lazy延時(shí)引擎:在距最近一次訪(fǎng)問(wèn)間隔expiration_time_in_seconds時(shí)間段內(nèi)粒蜈,將表保存在內(nèi)存中,僅適用于Log引擎表
ClickHouse的表引擎提供了四個(gè)系列(Log术唬、MergeTree薪伏、Integration、Special)大約28種表引擎粗仓,各有各的用途嫁怀。
比如Log系列用來(lái)做小表數(shù)據(jù)分析,MergeTree系列用來(lái)做大數(shù)據(jù)量分析借浊,而Integration系列則多用于外表數(shù)據(jù)集成塘淑。Log、Special蚂斤、Integration系列的表引擎相對(duì)來(lái)說(shuō)存捺,應(yīng)用場(chǎng)景有限,功能簡(jiǎn)單曙蒸,應(yīng)用特殊用途捌治,MergeTree系列表引擎又和兩種特殊表引擎(Replicated,Distributed)正交形成多種具備不同功能的MergeTree表引擎纽窟。
這是ClickHouse的表引擎系列家譜:
MergeTree作為家族中最基礎(chǔ)的表引擎肖油,提供了主鍵索引、數(shù)據(jù)分區(qū)臂港、數(shù)據(jù)副本和數(shù)據(jù)采樣等基本能力森枪,而家族中其他的表引擎則在 MergeTree 的基礎(chǔ)之上各有所長(zhǎng):
四:MergeTree 引擎工作機(jī)制詳解
MergeTree系列是官方主推的存儲(chǔ)引擎,支持幾乎所有ClickHouse核心功能审孽,該系列中县袱,常用的表引擎有:MergeTree、ReplacingMergeTree佑力、CollapsingMergeTree式散、VersionedCollapsingMergeTree、SummingMergeTree打颤、AggregatingMergeTree等杂数。學(xué)習(xí)好MergeTree表引擎的工作機(jī)制,是應(yīng)用好ClickHouse的最基本基礎(chǔ)瘸洛。
4.1 關(guān)于表引擎類(lèi)型
第一:MergeTree表引擎主要用于海量數(shù)據(jù)分析揍移,支持?jǐn)?shù)據(jù)分區(qū)、存儲(chǔ)有序反肋、主鍵索引那伐、稀疏索引、數(shù)據(jù)TTL等。MergeTree支持所有ClickHouse SQL語(yǔ)法罕邀,但是有些功能與 MySQL并不一致畅形,比如在MergeTree中主鍵并不用于去重。
第二:為了解決MergeTree相同主鍵無(wú)法去重的問(wèn)題诉探,ClickHouse提供了ReplacingMergeTree引擎日熬,用來(lái)做去重。ReplacingMergeTree確保數(shù)據(jù)最終被去重肾胯,但是無(wú)法保證查詢(xún)過(guò)程中主鍵不重復(fù)竖席。因?yàn)橄嗤麈I的數(shù)據(jù)可能被shard到不同的節(jié)點(diǎn),但是 compaction只能在一個(gè)節(jié)點(diǎn)中進(jìn)行敬肚,而且optimize的時(shí)機(jī)也不確定毕荐。
第三:CollapsingMergeTree引擎要求在建表語(yǔ)句中指定一個(gè)標(biāo)記列Sign(插入的時(shí)候指定為1,刪除的時(shí)候指定為-1)艳馒,后臺(tái)Compaction時(shí)會(huì)將主鍵相同憎亚、Sign相反的行進(jìn)行折疊,也即刪除弄慰。來(lái)消除ReplacingMergeTree的限制第美。
第四:為了解決CollapsingMergeTree亂序?qū)懭肭闆r下無(wú)法正常折疊問(wèn)題,VersionedCollapsingMergeTree表引擎在建表語(yǔ)句中新增了一列Version陆爽,用于在亂序情況下記錄狀態(tài)行與取消行的對(duì)應(yīng)關(guān)系什往。主鍵相同,且Version相同墓陈、Sign相反的行恶守,在 Compaction時(shí)會(huì)被刪除第献。
第五:ClickHouse通過(guò)SummingMergeTree來(lái)支持對(duì)主鍵列進(jìn)行預(yù)先聚合贡必。在后臺(tái) Compaction時(shí),會(huì)將主鍵相同的多行進(jìn)行sum求和庸毫,然后使用一行數(shù)據(jù)取而代之仔拟,從而大幅度降低存儲(chǔ)空間占用,提升聚合計(jì)算性能飒赃。
第六:AggregatingMergeTree也是預(yù)先聚合引擎的一種利花,用于提升聚合計(jì)算的性能。與SummingMergeTree的區(qū)別在于:SummingMergeTree對(duì)非主鍵列進(jìn)行sum聚合载佳,而 AggregatingMergeTree則可以指定各種聚合函數(shù)炒事。
4.2 MergeTree的建表語(yǔ)法:
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (
name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
name2 [type] [DEFAUErEMAMLERLALLIZED|ALIAS expr],
省略...
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, 省略...]
介紹一下其中的幾個(gè)關(guān)鍵選項(xiàng):
- PARTITION BY:分區(qū)鍵。指定表數(shù)據(jù)以何種標(biāo)準(zhǔn)進(jìn)行分區(qū)蔫慧。分區(qū)鍵既可以是單個(gè)列字段挠乳,也可以通過(guò)元組的形式使用多個(gè)列字段,同時(shí)它也支持使用列表達(dá)式。
- ORDER BY:排序鍵睡扬,用于指定在一個(gè)數(shù)據(jù)片段內(nèi)盟蚣,數(shù)據(jù)以何種標(biāo)準(zhǔn)排序。默認(rèn)情況下主鍵(PRIMARY KEY)與排序鍵相同卖怜。
- PRIMARY KEY:主鍵屎开。聲明后會(huì)依照主鍵字段生成一級(jí)索引。默認(rèn)情況下马靠,主鍵與排序鍵(ORDER BY)相同奄抽,所以通常直接使用ORDER BY代為指定主鍵。
- SETTINGS:index_granularity選項(xiàng)表示索引的粒度虑粥,默認(rèn)值為8192如孝。MergeTree 索引在默認(rèn)情況下,每間隔8192行數(shù)據(jù)才生成一條索引娩贷。
- SAMPLE BY:抽樣表達(dá)式第晰,用于聲明數(shù)據(jù)以何種標(biāo)準(zhǔn)進(jìn)行采樣。
注意settings中的重要參數(shù):
- index_granularity 默認(rèn)是8192
- index_granularity_bytes 默認(rèn)10M彬祖,需要通過(guò)enable_mixed_granularity_parts=1來(lái)開(kāi)啟
五:ClickHouse 工作原理
MergeTree表引擎的內(nèi)部工作細(xì)節(jié)茁瘦!最終就是告訴你:為什么clickhouse做查詢(xún)分析,那么快储笑?
ClickHouse從OLAP場(chǎng)景需求出發(fā)甜熔,定制開(kāi)發(fā)了一套全新的高效列式存儲(chǔ)引擎,并且實(shí)現(xiàn)了數(shù)據(jù)有序存儲(chǔ)突倍、主鍵索引腔稀、稀疏索引、數(shù)據(jù)Sharding羽历、數(shù)據(jù)Partitioning焊虏、TTL、主備復(fù)制等豐富功能秕磷。這些功能共同為ClickHouse極速的分析性能奠定了基礎(chǔ)诵闭。
5.1 數(shù)據(jù)分區(qū)
CREATE TABLE user(
id String,Name String,age UInt8,create_time DateTime
) ENGINE = MergeTree
PARTITION BY toYYYYMMDD(create_time)
ORDER BY age SETTINGS index_granularity = 8192
關(guān)于表分區(qū)目錄結(jié)構(gòu):MergeTree 表的分區(qū)目錄物理結(jié)構(gòu):
關(guān)于這些文件的解釋?zhuān)?/strong>
- 分區(qū)目錄:20210427_1_1_0,一個(gè)分區(qū)可能會(huì)有多個(gè)不同的目錄澎嚣,該目錄下存儲(chǔ)該分區(qū)的數(shù)據(jù)及其他各種形式的數(shù)據(jù)疏尿。后臺(tái)會(huì)執(zhí)行合并,把相同分區(qū)的多個(gè)目錄合并到一個(gè)分區(qū)易桃。
- checksums.txt:校驗(yàn)文件褥琐。使用二進(jìn)制格式存儲(chǔ)。它保存了余下各類(lèi)文件(primary.idx晤郑、count.txt等)的size大小及size的哈希值敌呈,用于快速校驗(yàn)文件的完整性和正確性嚼鹉。
- columns.txt:列信息文件,使用明文格式存儲(chǔ)驱富。用于保存此數(shù)據(jù)分區(qū)下的列字段信息锚赤。
- count.txt:計(jì)數(shù)文件,使用明文格式存儲(chǔ)褐鸥。用于記錄當(dāng)前數(shù)據(jù)分區(qū)目錄下數(shù)據(jù)的總行數(shù)线脚。
- primary.idx:一級(jí)索引文件,主鍵索引文件叫榕。
- xxx.bin:數(shù)據(jù)文件浑侥,使用壓縮格式存儲(chǔ),默認(rèn)為L(zhǎng)Z4壓縮格式晰绎,用于存儲(chǔ)某一列的數(shù)據(jù)寓落,每一列都對(duì)應(yīng)一個(gè)該文件,如列date為date.bin荞下。
- xxx.mrk2:列字段標(biāo)記文件伶选,如果使用了自適應(yīng)大小的索引間隔,則標(biāo)記文件以.mrk2命名尖昏,否則以.mrk命名仰税。它建立primary.idx稀疏索引與xxx.bin數(shù)據(jù)文件之間的映射關(guān)系,先通過(guò)主鍵索引找到數(shù)據(jù)的偏移量抽诉,然后去 xxx.bin數(shù)據(jù)文件中找到真實(shí)數(shù)據(jù)陨簇。
- ...還有二級(jí)索引和分區(qū)鍵相關(guān)信息文件等等。
相比于行式存儲(chǔ),列式存儲(chǔ)在分析場(chǎng)景下有著許多優(yōu)良的特性唉窃。
- 分析場(chǎng)景中往往需要讀大量行但是少數(shù)幾個(gè)列耙饰。在行存模式下,數(shù)據(jù)按行連續(xù)存儲(chǔ)句携,所有列的數(shù)據(jù)都存儲(chǔ)在一個(gè)block中榔幸,不參與計(jì)算的列在IO時(shí)也要全部讀出允乐,讀取操作被嚴(yán)重放大矮嫉。而列存模式下,只需要讀取參與計(jì)算的列即可牍疏,極大的減低了IO cost蠢笋,加速了查詢(xún)。
- 同一列中的數(shù)據(jù)屬于同一類(lèi)型鳞陨,壓縮效果顯著昨寞。列存往往有著高達(dá)十倍甚至更高的壓縮比瞻惋,節(jié)省了大量的存儲(chǔ)空間,降低了存儲(chǔ)成本援岩。
- 更高的壓縮比意味著更小的data size歼狼,從磁盤(pán)中讀取相應(yīng)數(shù)據(jù)耗時(shí)更短。
- 自由的壓縮算法選擇享怀。不同列的數(shù)據(jù)具有不同的數(shù)據(jù)類(lèi)型羽峰,適用的壓縮算法也就不盡相同√泶桑可以針對(duì)不同列類(lèi)型梅屉,選擇最合適的壓縮算法。
- 高壓縮比鳞贷,意味著同等大小的內(nèi)存能夠存放更多數(shù)據(jù)坯汤,系統(tǒng)cache效果更好。
5.4 一級(jí)索引
關(guān)于一級(jí)索引:MergeTree的主鍵使用PRIMARY KEY定義搀愧,待主鍵定義之后惰聂,MergeTree會(huì)依據(jù)index_granularity 間隔(默認(rèn) 8192 行),為數(shù)據(jù)表生成一級(jí)索引并保存至 primary.idx 文件內(nèi)咱筛。
一級(jí)索引是稀疏索引庶近,意思就是說(shuō):每一段數(shù)據(jù)生成一條索引記錄,而不是每一條數(shù)據(jù)都生成索引眷蚓,如果是每一條數(shù)據(jù)都生成索引鼻种,則是稠密索引。稀疏索引的好處沙热,就是少量的索引標(biāo)記叉钥,就能記錄大量的數(shù)據(jù)區(qū)間位置信息,比如不到24414條標(biāo)記信息篙贸,就能為2E條數(shù)據(jù)提供索引(算法:200000000/8192)投队。
在 ClickHouse中,一級(jí)索引常駐內(nèi)存爵川》笱唬總的來(lái)說(shuō):一級(jí)索引和標(biāo)記文件一一對(duì)齊,兩個(gè)索引標(biāo)記之間的數(shù)據(jù)寝贡,就是一個(gè)數(shù)據(jù)區(qū)間扒披,在數(shù)據(jù)文件中,這個(gè)數(shù)據(jù)區(qū)間的所有數(shù)據(jù)圃泡,生成一個(gè)壓縮數(shù)據(jù)塊碟案。需要注意的是:ClickHouse的主鍵索引與MySQL等數(shù)據(jù)庫(kù)不同,它并不用于去重颇蜡,即便primary key相同的行价说,也可以同時(shí)存在于數(shù)據(jù)庫(kù)中辆亏。要想實(shí)現(xiàn)去重效果,需要結(jié)合具體的表引擎ReplacingMergeTree鳖目、CollapsingMergeTree扮叨、VersionedCollapsingMergeTree實(shí)現(xiàn)。
5.5.二級(jí)索引
關(guān)于二級(jí)索引:又稱(chēng)之為跳數(shù)索引领迈。目的和一級(jí)索引一樣甫匹,是為了減少待搜尋的數(shù)據(jù)的范圍。
跳數(shù)索引的默認(rèn)是關(guān)閉的惦费,需要通過(guò)SET allow_experimental_data_skipping_indices = 1 來(lái)開(kāi)啟兵迅,索引生成粒度由granularity控制,如果生成了二級(jí)索引薪贫,則會(huì)在分區(qū)目錄下生成額外的:skp_idx_[Column].idx與skp_idx_[Column].mrk文件恍箭。
跳數(shù)索引的生成規(guī)則:按照特定規(guī)則每隔granularity個(gè)index_granularity條數(shù)據(jù),就會(huì)生成一條跳數(shù)索引瞧省。 比如minmax跳數(shù)索引扯夭,生成的是:granularity個(gè)index_granularity條數(shù)據(jù)內(nèi)的最大值最小值生成一條索引,如果將來(lái)需要針對(duì)構(gòu)建二級(jí)索引的這個(gè)字段求最大值最小值鞍匾,則可以幫助提高效率交洗。
跳數(shù)索引一共支持四種類(lèi)型:minmax(最大最小)橡淑、set(去重集合)构拳、ngrambf_v1(ngram分詞布隆索引)和tokenbf_v1(標(biāo)點(diǎn)符號(hào)分詞布隆索引),一張數(shù)據(jù)表支持同時(shí)聲明多個(gè)跳數(shù)索引梁棠。比如:
GRANULARITY = 你在創(chuàng)建二級(jí)索引索引的指定的
INDEX_GRANULARITY = 8192 GRANULARITY * INDEX_GRANULARITY
CREATE TABLE skip_test(
ID String,
URL String,
Code String,
EventTime Date,
INDEX a ID TYPE minmax GRANULARITY 5,
INDEX b (length(ID) * 8) TYPE set(2) GRANULARITY 5,
INDEX c (ID, Code) TYPE ngrambf_v1(3, 256, 2, O) GRANULARITY 5,
INDEX d ID TYPE tokenbf_v1(256, 2, 0) GRANULARITY 5
) ENGINE= MergeTree()
order by id;
關(guān)于跳數(shù)索引支持的多種類(lèi)型的區(qū)別:
- minmax:以index_granularity為單位置森,存儲(chǔ)指定表達(dá)式計(jì)算后的min、max值符糊;在等值和范圍查詢(xún)中能夠幫助快速跳過(guò)不滿(mǎn)足要求的塊凫海,減少I(mǎi)O。
- set(max_rows):以index granularity為單位男娄,存儲(chǔ)指定表達(dá)式的distinct value集合行贪,用于快速判斷等值查詢(xún)是否命中該塊,減少I(mǎi)O模闲。
- ngrambf_v1(n,size_of_bloom_filter_in_bytes,number_of_hash_functions, random_seed):將string進(jìn)行ngram分詞后建瘫,構(gòu)建bloom filter,能夠優(yōu)化等值围橡、like暖混、in等查詢(xún)條件缕贡。
- tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed):與ngrambf_v1類(lèi)似翁授,區(qū)別是不使用ngram進(jìn)行分詞拣播,而是通過(guò)標(biāo)點(diǎn)符號(hào)進(jìn)行詞語(yǔ)分割。
- bloom_filter([false_positive]):對(duì)指定列構(gòu)建bloom filter收擦,用于加速等值贮配、like、in等查詢(xún)條件的執(zhí)行塞赂。
5.6 數(shù)據(jù)壓縮
關(guān)于數(shù)據(jù)壓縮:ClickHouse的數(shù)據(jù)存儲(chǔ)文件column.bin中存儲(chǔ)是一列的數(shù)據(jù)泪勒,由于一列是相同類(lèi)型的數(shù)據(jù),所以方便高效壓縮宴猾。
在進(jìn)行壓縮的時(shí)候圆存,請(qǐng)注意:一個(gè)壓縮數(shù)據(jù)塊由頭信息和壓縮數(shù)據(jù)兩部分組成,頭信息固定使用9位字節(jié)表示仇哆,具體由1個(gè)UInt8(1字節(jié))整型和 2個(gè)UInt32(4字節(jié))整型組成沦辙,分別代表使用的壓縮算法類(lèi)型、壓縮后的數(shù)據(jù)大小和壓縮前的數(shù)據(jù)大小讹剔。
單個(gè)壓縮數(shù)據(jù)塊的體積,按照其壓縮前的數(shù)據(jù)字節(jié)大小,都被嚴(yán)格控制在64KB~1MB逞带,其上下限分別由min_compress_block_size(默認(rèn)65536=64KB)與 max_compress_block_size(默認(rèn)1048576=1M)參數(shù)指定铡原。
具體壓縮規(guī)則:
原理的說(shuō)法:每8192條記錄,其實(shí)就是一條一級(jí)索引一個(gè)索引區(qū)間 壓縮成一個(gè)數(shù)據(jù)塊由捎。自適應(yīng)壓縮
- 單個(gè)批次數(shù)據(jù)size < 64KB:如果單個(gè)批次數(shù)據(jù)小于64KB兔综,則繼續(xù)獲取下一批數(shù)據(jù),直至累積到size >= 64KB時(shí)狞玛,生成下一個(gè)壓縮數(shù)據(jù)塊邻奠。如果平均每條記錄小于8byte,多個(gè)數(shù)據(jù)批次壓縮成一個(gè)數(shù)據(jù)塊为居。
- 單個(gè)批次數(shù)據(jù)64KB<= size <=1MB:如果單個(gè)批次數(shù)據(jù)大小恰好在64KB 與1MB之間碌宴,則直接生成下一個(gè)壓縮數(shù)據(jù)塊。
- 單個(gè)批次數(shù)據(jù)size > 1MB:如果單個(gè)批次數(shù)據(jù)直接超過(guò)1MB蒙畴,則首先按照1MB大小截?cái)嗖⑸上乱粋€(gè)壓縮數(shù)據(jù)塊贰镣。剩余數(shù)據(jù)繼續(xù)依照上述規(guī)則執(zhí)行。此時(shí)膳凝,會(huì)出現(xiàn)一個(gè)批次數(shù)據(jù)生成多個(gè)壓縮數(shù)據(jù)塊的情況碑隆。如果平均每條記錄的大小超過(guò) 128byte,則會(huì)把當(dāng)前這一個(gè)批次的數(shù)據(jù)壓縮成多個(gè)數(shù)據(jù)塊。
5.7 數(shù)據(jù)標(biāo)記
關(guān)于數(shù)據(jù)標(biāo)記:數(shù)據(jù)標(biāo)記文件也與.bin文件一一對(duì)應(yīng)蹬音。即每一個(gè)列字段[Column].bin文件都有一個(gè)與之對(duì)應(yīng)的 [Column].mrk2 數(shù)據(jù)標(biāo)記文件上煤,用于記錄數(shù)據(jù)在 .bin 文件中的偏移量信息。
一行標(biāo)記數(shù)據(jù)使用一個(gè)元組表示著淆,元組內(nèi)包含兩個(gè)整型數(shù)值的偏移量信息劫狠。它們分別表示在此段數(shù)據(jù)區(qū)間內(nèi)拴疤,在對(duì)應(yīng)的.bin壓縮文件中,壓縮數(shù)據(jù)塊的起始偏移量独泞;以及將該數(shù)據(jù)壓縮塊解壓后呐矾,其未壓縮數(shù)據(jù)的起始偏移量。每一行標(biāo)記數(shù)據(jù)都表示了一個(gè)片段的數(shù)據(jù)(默認(rèn)8192行)在.bin壓縮文件中的讀取位置信息懦砂。標(biāo)記數(shù)據(jù)與一級(jí)索引數(shù)據(jù)不同蜒犯,它并不能常駐內(nèi)存,而是使用LRU(最近最少使用)緩存策略加快其取用速度荞膘。
總結(jié)數(shù)據(jù)讀取流程:先根據(jù)一級(jí)索引罚随,找到標(biāo)記文件中的對(duì)應(yīng)數(shù)據(jù)壓縮塊信息(壓縮塊在.bin文件中的起始偏移量和未壓縮之前該條數(shù)據(jù)的是偏移量)然后從.bin文件中,把壓縮塊加載到內(nèi)存羽资,解壓縮之后毫炉,執(zhí)行讀取。建立了主鍵索引到數(shù)據(jù)文件的映射削罩!
5.8 查詢(xún)數(shù)據(jù)
指定分區(qū) ==> 指定字段(xxx.bin)==> 根據(jù)一級(jí)索引(primary.idx)定位到 標(biāo)記文件(name.mrk2)中的那一條記錄 ==> 掃描對(duì)應(yīng)字段的 mark 標(biāo)記文件 獲取兩個(gè)偏移量信息(當(dāng)前要查找的數(shù)據(jù)瞄勾,處于這個(gè).bin數(shù)據(jù)文件中的那個(gè)壓縮數(shù)據(jù)塊,這個(gè)壓縮數(shù)據(jù)塊在 .bin 文件的偏移量弥激,這個(gè)壓縮數(shù)據(jù)塊解壓縮 出來(lái)之后进陡,要找的數(shù)據(jù)在當(dāng)前這個(gè)壓縮數(shù)據(jù)快的偏移量)==> 根據(jù)第一個(gè)偏移量去.bin文件中定位到一個(gè)壓縮數(shù)據(jù)快 ==> 讀取數(shù)據(jù)到內(nèi)存執(zhí)行解壓縮 ==> 根據(jù)第二個(gè)偏移量去內(nèi)存解壓縮數(shù)據(jù)中找到對(duì)應(yīng)的數(shù)據(jù)。
提高數(shù)據(jù)查詢(xún)效率的核心原則只有一個(gè):誰(shuí)做的輔助動(dòng)作能快速的幫助我們?nèi)タ焖俳档痛褜さ臄?shù)據(jù)范圍微服。
六:總結(jié)
在大數(shù)據(jù)分析領(lǐng)域中趾疚,傳統(tǒng)的大數(shù)據(jù)分析需要不同框架和技術(shù)組合才能達(dá)到最終的效果,在人力成本以蕴,技術(shù)能力和硬件成本上以及維護(hù)成本讓大數(shù)據(jù)分析變得成為昂貴的事情糙麦。讓很多中小型企業(yè)非常苦惱丛肮,不得不被迫租賃第三方大型公司的數(shù)據(jù)分析服務(wù)赡磅。ClickHouse開(kāi)源的出現(xiàn)讓許多想做大數(shù)據(jù)并且想做大數(shù)據(jù)分析的很多公司和企業(yè)耳目一新。ClickHouse 正是以不依賴(lài)Hadoop 生態(tài)宝与、安裝和維護(hù)簡(jiǎn)單焚廊、查詢(xún)速度快、可以支持SQL等特點(diǎn)在大數(shù)據(jù)分析領(lǐng)域越走越遠(yuǎn)习劫。
關(guān)注IT巔峰技術(shù)咆瘟,私信作者,獲取以下2021全球架構(gòu)師峰會(huì)PDF資料诽里。