背景
有一個系統(tǒng)的業(yè)務(wù)正在膨脹中琼讽,某一些報表(報表數(shù)據(jù)在mysql中)數(shù)據(jù)量增長比較厲害哗戈,報表頁面已經(jīng)處于卡爆了
的狀態(tài)荒椭。中間經(jīng)過mysql本身的優(yōu)化,已經(jīng)到了當(dāng)前系統(tǒng)架構(gòu)+存儲模型的瓶頸笔链。本文提供一種優(yōu)化思路段只,拋磚引玉。
任務(wù)分析
以一條sql的優(yōu)化為例(這條sql里面的字段隨便改了改鉴扫,不保證正確性)赞枕。
SELECT d.col, COUNT(DISTINCT risk.inst_id) AS `count`
FROM risk
INNER JOIN d
ON d.inst_id = risk.inst_id
AND d.id = risk.id
INNER JOIN b
ON b.business_key = d.id
AND d.type = b.type
INNER JOIN r
ON risk.inst_id = r.inst_id
AND risk.id = r.id
WHERE (r.visit_time >= '2018-10-27 00:00:00'
AND r.visit_time <= '2018-11-28 15:54:40'
AND d.id = '22821111115042'
AND b.business_key = concat('22821111115042', ''))
GROUP BY d.col
其中,risk表大小112MB坪创,d表大小為9.5GB炕婶,b表208KB,r表大小為4.2GB莱预。這個報表的生成邏輯中含有較多inner join柠掂。經(jīng)過一些列的索引優(yōu)化之后,該條sql的查詢時間是36s依沮,前端體驗(yàn)仍然不是很好陪踩,且隨著報表時間范圍的拉長,用戶數(shù)據(jù)量的增長悉抵,查詢時間會持續(xù)惡化肩狂。
這里就不討論更改表結(jié)構(gòu)、遷移數(shù)據(jù)來優(yōu)化查詢了姥饰。
優(yōu)化思路
本身沒有太多技術(shù)難度傻谁,但中間經(jīng)過一段時間的摸索,直接說結(jié)論吧列粪,希望對有需要的同學(xué)帶來便利审磁。
用SparkSQL分布式計算的能力來加速查詢,SparkSQL原生支持通過jdbc連接外部存儲岂座。
首先态蒂,嘗試了直接在sparksql的jdbc連接中執(zhí)行上述sql,結(jié)果在意料之中费什,36秒左右钾恢。通過spark監(jiān)控頁面看到,該任務(wù)task數(shù)量為1,沒有并發(fā)起來瘩蚪,SparkSQL將查詢完全下推給mysql執(zhí)行泉懦。
那么問題來了,如何提升并發(fā)度呢疹瘦?
根據(jù)官方文檔崩哩,使用jdbc連接有這么幾個可用參數(shù),這些參數(shù)的含義參考附錄鏈接言沐。
numPartitions
邓嘹,partitionColumn
,lowerBound
险胰,upperBound
值得注意的是汹押,partitionColumn
必須為數(shù)值類型,日期或者時間戳鸯乃。lowerBound
和upperBound
必須為數(shù)字鲸阻。在上面的case中跋涣,我們可以對r表的visit_time進(jìn)行分區(qū)缨睡,并根據(jù)范圍設(shè)置上下界線。(時間戳轉(zhuǎn)化成long型)
分別在SparkSQL load這4張表陈辱,其中對r表的visit_time進(jìn)行分區(qū)奖年,并分別在SparkSQL中注冊臨時表,在SparkSQL內(nèi)執(zhí)行上述SQL沛贪,上述SQL執(zhí)行時間由36s降低到12s陋守,如果調(diào)調(diào)SparkSQL的參數(shù),性能可能會更好利赋。
這個方法從理論上來說水评,適用于任何單機(jī)關(guān)系型數(shù)據(jù)庫。
原理簡單剖析
這里是將SparkSQL作為一個分布式查詢引擎媚送,mysql作為SparkSQL的一種數(shù)據(jù)源中燥。SparkSQL內(nèi)部有高度的統(tǒng)一抽象(DataFrame/DataSet)。SparkSQL從mysql中抽取數(shù)據(jù)然后根據(jù)自身的邏輯來進(jìn)行運(yùn)算塘偎。如果對細(xì)節(jié)感興趣可以參考鏈接2疗涉。
參考文檔
[1] http://spark.apache.org/docs/latest/sql-data-sources-jdbc.html
[2] http://spark.apache.org/docs/latest/sql-programming-guide.html