sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换
Bucket Table
Bucket?Table是一種Spark常見的優化查詢的建表方式。創建方式是使用distributed by語法進行創建,會根據spark.sql.shuffle.partitions的值創建若干個bucket。Spark中對于兩個大表的join,采用的方式是SortMergeJoin.而如果兩個表都是bucket表,而且bucket數量相同(業界有公司針對這塊的優化,如果兩個bucket表bucket數量是倍數關系也可以進行bucket join),那么可以跳過sort和shuffle,直接進行join, 會產生較好的性能,通常需要業務方會約定好bucket的數量。
Spark針對bucket表讀取的時候,會對每一個bucket分配一個task來讀取,因為如果進行bucket join就不能再對這個bucket的數據進行拆分。但是問題來了,我們并不是每次讀取bucket表都是為了進行bucket join,比如說有時候我們會對這個bucket進行更新操作。如果只是單純的對這個bucket表進行一些處理操作,例如就是一個單純的shuffle操作。而這個bucket表的每個bucket都特別大,例如大于1個G,而在shuffle write階段要生成3G的數據。那么這時候對每個bucket分配一個task來處理就會非常吃力。
其實Spark?SQL中有一個參數spark.sql.sources.bucketing.enabled,默認是true。如果我們將這個參數設置為false,那么spark就會將一個bucket table看做一個普通的table。這意味著什么呢?Spark對于普通表,如果他的單個文件大于一個hdfs ?block大小(通常是128M),而且這個文件又是可拆分的(例如text文本,snappy 壓縮格式的parquet文件等等),那么Spark會按照這個文件拆分,分配多個task來處理。因此,針對我們上面的場景,設置這個參數為false,可以大大的加快map階段的執行,起到優化的效果。
解析和更改Spark SQL語句
如果你有對一個Spark?SQL語句進行解析和更改部分語句的需求。
例如我需求對一條SQL中的表名進行映射修改,或者對其中的UDF(其實在Spark?SQL中function和table是很類似的東西)和location信息進行修改。
可能首先想到的就是使用正則進行字符串匹配,去尋找自己需要的字段,但是這種方法十分的不靠譜,因為SQL的語法十分復雜,我們很難完全準確的抓取到自己需要的信息。
所以我們能不能根據抽象語法樹去拿到我們想要的字段呢?答案當然是OK的,一條SQL語句進行解析器之后都成為一個抽象語法樹,每個TreeNode都有自己的類型,我們可以根據這些類型拿到自己想要的信息,比如table name,function name,location等等信息(table根據TableIdentifier類型節點獲得,function根據FunctionIdentifier, location信息從LoadDataCommand或者CreateTableCommand中獲取)。如下圖所以,一條SQL語句INSERT INTO TRABLE tb SELECT ta.id FROM ta JOIN tb on ta.id=tb.id會被大概轉化為下面一個AST.
但是,當我們拿到我們想要的信息,之后如何轉換想要的SQL呢?
我第一想法是說,直接修改這個AST,然后將這個AST轉化為一條SQL語句。但是AST轉SQL很麻煩的事情,需要你自己精通SQL語法,然后寫一套 Plan轉String的規則。這聽起來就很麻煩。好在經過一番探索:
Spark使用antlr v4進行sql解析
每個SQL最開始解析為一個原始的AST(parsedPlan,未經過analyze/optimize)
這個SQL也對應一個ParserRuleContext(package?org.antlr.v4.runtime)
ParserRuleContext其實也是一棵樹,類似于AST,但是它的每個葉子節點會對應一段text,也就是說對應一部分原始的SQL語句(table對應TableIdentifierContext,function對應QualifiedNameContext, location對應LocationSpecContext)。
感興趣的話可以去看這個類的源碼:
https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java。
前面我們提到的語句會被轉化為下面的一棵樹,我這里是將其轉為String打印出來,在每個節點處進行換行。
有了這樣的兩棵樹AST和ParserRuleContext,我們就可以根據第一棵樹,拿到我們想要的信息,然后再在第二棵樹上面找到其對應的偏移量。然后對對應部分進行替換,之后再把第二棵樹的碎片對應的文本拼接起來就好了。
HBase?官方社區推薦必讀好文
HBase 原理|HBase 內存管理之 MemStore 進化論
HBase 抗戰總結|阿里巴巴 HBase 高可用8年抗戰回憶錄
HBase 實踐|說好不哭,但 HBase 2.0 真的好用到哭
↓掃碼關注?HBase?技術社區公眾號↓
總結
以上是生活随笔為你收集整理的sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js 强校验 弱校验_还在手写表单校验逻
- 下一篇: 什么是随机存取_SRAM存储器是什么存储