聊聊分布式 SQL 数据库Doris(七)
LSM-Tree
Doris的存儲(chǔ)結(jié)構(gòu)是類(lèi)似LSM-Tree設(shè)計(jì)的,因此很多方面都是通用的,先閱讀了解LSM相關(guān)的知識(shí),再看Doris的底層存儲(chǔ)與讀取流程會(huì)清晰透徹很多,如下是幾個(gè)關(guān)鍵的設(shè)計(jì):
SSTable: Sorted Strings Table; 一般由一組數(shù)據(jù)block和一組元數(shù)據(jù)block組成,數(shù)據(jù)是已序的。元數(shù)據(jù)會(huì)存儲(chǔ)數(shù)據(jù)block的描述信息,如索引、BloomFilter、壓縮、統(tǒng)計(jì)等信息。
MemTable: 內(nèi)存里的表,有序且存儲(chǔ)在Buffer中;可以用多種數(shù)據(jù)結(jié)構(gòu)來(lái)組織,一般是用跳表(SkipList),也可以是有序數(shù)組或紅黑樹(shù)等二叉搜索樹(shù);最后會(huì)被轉(zhuǎn)化成SSTable格式刷入磁盤(pán)持久化存儲(chǔ)。
Compaction: 合并壓縮SSTable。
參考:
LSM 樹(shù)設(shè)計(jì)原理
LSM Tree索引:高性能寫(xiě)引擎
索引
官網(wǎng)文檔: 索引概述.
Doris內(nèi)建的索引: 前綴索引(Short key Index)、ZoneMap索引,默認(rèn)是根據(jù)建表時(shí)的key列生成的。
Doris 的數(shù)據(jù)存儲(chǔ)在類(lèi)似 SSTable(Sorted String Table)的數(shù)據(jù)結(jié)構(gòu)中。該結(jié)構(gòu)是一種有序的數(shù)據(jù)結(jié)構(gòu),可以按照指定的列進(jìn)行排序存儲(chǔ)。在這種數(shù)據(jù)結(jié)構(gòu)上,以排序列作為條件進(jìn)行查找,會(huì)非常的高效。
在 Aggregate、Unique 和 Duplicate 三種數(shù)據(jù)模型中。底層的數(shù)據(jù)存儲(chǔ),是按照各自建表語(yǔ)句中,AGGREGATE KEY、UNIQUE KEY 和 DUPLICATE KEY 中指定的列進(jìn)行排序存儲(chǔ)的。因此在此排序列的基礎(chǔ)上根據(jù)不同的場(chǎng)景構(gòu)建內(nèi)置的索引,提高查詢(xún)的性能與效率。
Duplicate、Aggregate、Unique 模型,都會(huì)在建表指定 key 列,然而實(shí)際上是有所區(qū)別的:對(duì)于 Duplicate 模型,表的key列, 可以認(rèn)為只是 “排序列”,并非起到唯一標(biāo)識(shí)的作用。而 Aggregate、Unique 模型這種聚合類(lèi)型的表,key 列是兼顧 “排序列” 和 “唯一標(biāo)識(shí)列”,是真正意義上的“ key 列”。
參考: Apache Doris 索引機(jī)制解析
Join
官網(wǎng)文檔: Doris Join 優(yōu)化原理
概覽
Doris 支持兩種物理算子,一類(lèi)是 Hash Join,另一類(lèi)是 Nest Loop Join。
Doris 支持 4 種數(shù)據(jù) Shuffle 方式:
-
BroadCast Join: 要求把右表全量的數(shù)據(jù)都發(fā)送到左表上,即每一個(gè)參與 Join 的節(jié)點(diǎn),它都擁有右表全量的數(shù)據(jù)
-
Shuffle Join: 只支持hash join場(chǎng)景(即等值匹配). 當(dāng)進(jìn)行 Hash Join 時(shí)候,可以通過(guò) Join 列計(jì)算對(duì)應(yīng)的 Hash 值,并進(jìn)行 Hash 分桶,并將分桶后的數(shù)據(jù)分散到節(jié)點(diǎn)中進(jìn)行計(jì)算
-
Bucket Shuffle Join: 右表數(shù)據(jù)掃描出來(lái)之后進(jìn)行數(shù)據(jù)分區(qū)的 Hash 計(jì)算,根據(jù)左表本身的數(shù)據(jù)分布發(fā)送到右表對(duì)應(yīng)的 Join 計(jì)算節(jié)點(diǎn)上。
-
Colocation: 導(dǎo)入數(shù)據(jù)時(shí),提前將join表的數(shù)據(jù)分散到一個(gè)節(jié)點(diǎn)
Runtime Filter
Doris 在進(jìn)行 Hash Join 計(jì)算時(shí)會(huì)在右表構(gòu)建一個(gè)哈希表,左表流式的通過(guò)右表的哈希表從而得出 Join 結(jié)果。而 RuntimeFilter 就是充分利用了右表的 Hash 表,在右表生成哈希表的時(shí)候,同時(shí)生成一個(gè)基于哈希表數(shù)據(jù)的一個(gè)過(guò)濾條件(Filter),然后下推到左表的數(shù)據(jù)掃描節(jié)點(diǎn),通過(guò)這樣的方式,左表在運(yùn)行時(shí)(Runtime)提前進(jìn)行數(shù)據(jù)過(guò)濾,提高查詢(xún)效率。
Runtime Filter是分布式SQL查詢(xún)引擎框架通用的一種優(yōu)化手段,具體可參考: Join優(yōu)化技術(shù)之Runtime Filter.
Runtime Filter涉及到的下推技術(shù)同樣也是查詢(xún)引擎框架常用的優(yōu)化手段; 常見(jiàn)的下推優(yōu)化技術(shù)有:謂詞下推, 存儲(chǔ)層下推等。
Doris支持的三種類(lèi)型RuntimeFilter:
- IN 的優(yōu)點(diǎn)是過(guò)濾效果明顯,且快速。它的缺點(diǎn)首先第一個(gè)它只適用于 BroadCast,第二,它右表超過(guò)一定數(shù)據(jù)量的時(shí)候就失效了,當(dāng)前 Doris 目前配置的是1024,即右表如果大于 1024,IN 的 Runtime Filter 就直接失效了,其余的RuntimeFileter則沒(méi)有限制。
- MinMax 的優(yōu)點(diǎn)是開(kāi)銷(xiāo)比較小。它的缺點(diǎn)就是對(duì)數(shù)值列還有比較好的效果,但對(duì)于非數(shù)值列,基本上就沒(méi)什么效果。
- Bloom Filter 的特點(diǎn)就是通用,適用于各種類(lèi)型、效果也比較好。缺點(diǎn)就是它的配置比較復(fù)雜并且計(jì)算較高。
使用場(chǎng)景的要求:
- 第一個(gè)要求就是左表大右表小,因?yàn)闃?gòu)建 Runtime Filter是需要承擔(dān)計(jì)算成本的,包括一些內(nèi)存的開(kāi)銷(xiāo)。
- 第二個(gè)要求就是左右表 Join 出來(lái)的結(jié)果很少,說(shuō)明這個(gè) Join 可以過(guò)濾掉左表的絕大部分?jǐn)?shù)據(jù)。
Join Reorder
Join Reorder 是指在執(zhí)行SQL查詢(xún)時(shí),決定多個(gè)表進(jìn)行 join 的順序。它是數(shù)據(jù)庫(kù)查詢(xún)優(yōu)化的一個(gè)重要方面,對(duì)查詢(xún)性能和效率有著重要的影響, 不同的 join order 對(duì)性能可能有數(shù)量級(jí)的影響。
從定義來(lái)看,其實(shí)就是尋找最短路徑(最優(yōu)解)的過(guò)程,因此可以從算法的角度考慮,比如動(dòng)態(tài)規(guī)劃算法與貪心算法;同時(shí)也可以基于規(guī)則來(lái)做。
Doris中Join Reorder的實(shí)現(xiàn)是基于規(guī)則策略的,其規(guī)則定義如下:
- 讓大表、跟小表盡量做 Join,它生成的中間結(jié)果是盡可能小的。
- 把有條件的 Join 表往前放,也就是說(shuō)盡量讓有條件的 Join 表進(jìn)行過(guò)濾
- Hash Join 的優(yōu)先級(jí)高于 Nest Loop Join,因?yàn)?Hash join 本身是比 Nest Loop Join 快很多的。
Join Reorder 也是SQL查詢(xún)引擎框架通用的一種優(yōu)化手段, 在PolarDB、TiDB、StarRocks等數(shù)據(jù)庫(kù)框架中都有涉及與應(yīng)用。其實(shí)現(xiàn)與說(shuō)明如下:
- TiDB Join Reorder 算法簡(jiǎn)介
- StarRocks Join Reorder 源碼解析
- PolarDB-X 優(yōu)化器核心技術(shù) ~ Join Reorder
總結(jié)
以上是生活随笔為你收集整理的聊聊分布式 SQL 数据库Doris(七)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MAUI Blazor 如何通过url使
- 下一篇: EF 6 code first - 从S