SQL治理高階實踐:異常防御體系建設(shè)與應(yīng)用挖掘
一、防微杜漸:異常SQL防御體系建設(shè)
1.SQL治理階段
如上圖所示,SQL治理的基本階段主要包括開發(fā)(事前)、測試(事中)、生產(chǎn)運維(事后)三階段。
在開發(fā)階段,研發(fā)通常不受相應(yīng)開發(fā)規(guī)范和SQL審核約束。從開發(fā)到測試或生產(chǎn)發(fā)布時,才會進行DDL和DML的審核。目前業(yè)內(nèi)SQL治理,主要還是在SQL出問題之后進行相應(yīng)的治理。
所以我們思考:能否在測試階段提前發(fā)現(xiàn)有問題的SQL,提前預(yù)判性能并治理?如何在事中進行SQL的兜底和止損?
之所以要把治理能力前置到測試階段,是因為越早發(fā)現(xiàn)有問題的SQL,對整體治理或改造的成本就越低,對生產(chǎn)的影響也越小。
2.事前發(fā)現(xiàn)
1)SQLReview
SQLReview是在開發(fā)環(huán)境向測試環(huán)境或生產(chǎn)環(huán)境發(fā)布時,對語句進行基本審核。此部分的整體能力建設(shè)與當(dāng)前業(yè)界主流的開源沒有太大差別,只是我們的集成規(guī)范會更個性化或更豐富。
第一,根據(jù)DBA在日常中的反饋,完善相應(yīng)規(guī)則并集成經(jīng)驗,如攔截特殊語法;
第二,集成三方規(guī)范。比如大數(shù)據(jù)包含某些特殊要求,要求每一張表必須有時間字段等特定字段、特定類型和特定索引,以供大數(shù)據(jù)抽取數(shù)據(jù);
第三,廣播變更消息,比如提供安全審計,變更大數(shù)據(jù)訂閱結(jié)構(gòu)變更;
第四,日志分析,分析熱點表。DBA在日常運維時,需要一定數(shù)據(jù)統(tǒng)計來總結(jié)經(jīng)驗,梳理重點關(guān)注的業(yè)務(wù),了解攔截最多的規(guī)則和問題最多的部門。
2)新增SQL檢測
新增SQL檢測是指在SQL執(zhí)行到生產(chǎn)環(huán)節(jié)之前,將它攔截。實現(xiàn)流程中最重要的一點是,通過數(shù)據(jù)庫代理中間件記錄全量測試及生產(chǎn)的全量SQL、然后統(tǒng)一進行消費處理,識別出生產(chǎn)環(huán)境新增的SQL。
例如通過指紋計算,對比測試環(huán)境下SQL的指紋是否出現(xiàn)在生產(chǎn)最后的指紋庫里。若不存在的話,就把它認(rèn)定為一個新增的SQL,再放到生產(chǎn)環(huán)境中進行特征判斷,比如它的掃描行數(shù)是否太多,是否存在全表掃描,索引特征是否出現(xiàn)index merge、file sort等,也包含執(zhí)行時長,特殊禁止語法等全方位的特征判斷。
但這種實現(xiàn)存在兩個問題:
一是據(jù)統(tǒng)計,生產(chǎn)環(huán)境峰值QPS每秒上百萬。由于生產(chǎn)的真實流量比較大,改進后,我們不再轉(zhuǎn)發(fā)全量SQL,而是根據(jù)SQL指紋進行采樣避免流量太大,但即便如此,每天處理的SQL量仍接近5TB。
二是指紋計算。上述SQL通過DBA直觀去看,指紋計算應(yīng)該是一致的。但由于早期我們采用開源的基于正則的SQL指紋計算庫存在的不足,無法識別SQL在細微上的差異,導(dǎo)致指紋計算準(zhǔn)確度差影結(jié)果判斷。
改進后的指紋算法則采用語法解析樹的方式,將SQL的關(guān)鍵對象抽取出來做特征處理,比如取出查詢字段后做排序后再計算指紋,對where條件同樣做排序處理,防止sharding表由于表名字不同,造成的計算差異同樣進行特殊處理。
3)統(tǒng)計分析
我們統(tǒng)計了最近一個月的攔截量。在TP場景下,SQL問題大部分是索引問題,由上圖可知,“索引不合理”和“缺少索引”的情況占比之和達到80%。因此能否通過技術(shù)手段進行自動合理索引創(chuàng)建就是解決問題的重點。
4)研發(fā)視角新增SQL質(zhì)量報告
通過上圖視角,研發(fā)可以了解每個DBA或每個部門,在具體時間范圍內(nèi)新增哪些 SQL,發(fā)到生產(chǎn)的新增SQL是否高危SQL,并清晰地記錄下來。
質(zhì)量報告還包含其他重要信息,比如 SQL被認(rèn)定為高風(fēng)險的原因。如上圖所示,質(zhì)量報告提示可能存在全表掃描的情況,然后記錄其首次出現(xiàn)的時長和時間,使用開源索引工具給出基本建議。
但初期的建設(shè)還不太完善,開源工具僅基于單條SQL提出建議,缺少評估意見合理性的全局視角,我們后續(xù)會整體改寫這部分。
5)不帶隱患上生產(chǎn)
實現(xiàn)攔截功能需要與整個研發(fā)流程結(jié)合。
在CICD環(huán)節(jié)的準(zhǔn)出階段進行卡口集成,若出現(xiàn)高風(fēng)險的慢查詢或SQL沒有處理的情況,會提示“不可上線”,避免隱患SQL上生產(chǎn)。
3.事中兜底
無論防御做得多好,隨著數(shù)據(jù)庫容量、QPS的增長,一些SQL會不可避免地逐步惡化為慢SQL,因此要具備兜底能力。
第一,通過中間件進行主動或被動的SQL限流或熔斷,比如DBA會主動介入對某個SQL限流或者熔斷;
第二,自研數(shù)據(jù)庫管控平臺。平臺集成數(shù)據(jù)庫自愈系統(tǒng),通過查殺模塊,實時檢測每一個數(shù)據(jù)庫實例的健康狀況,并根據(jù)特征進行相應(yīng)的SQL查殺等。
我們整體構(gòu)建在混合云上,包含阿里云、華為云,AWS,Azure。每一家云對于數(shù)據(jù)庫的保護機制存在很大差別且是不可以跨云移植適用的,所以要打造自己統(tǒng)一的、通用的保護能力。
4.事后治理
事后治理主要是慢查詢治理。由于混合云上要兼容產(chǎn)品比較多通過云商接口,拉文件的原始分析方式實現(xiàn)比較麻煩,具備全量SQL的能力后實現(xiàn)就較為簡潔,后續(xù)接入多家云或兼容MySQL協(xié)議的產(chǎn)品時,能更好實現(xiàn)慢查詢分析、分析及安全審計等能力。
使用單一云較為簡單,而在混合云上時,為了某一能力的統(tǒng)一化或標(biāo)準(zhǔn)化,就不得不把管控系統(tǒng)設(shè)計得很復(fù)雜。
5.后續(xù)計劃
前文提到,我們統(tǒng)計80%的SQL問題是索引問題。如上圖統(tǒng)計,生產(chǎn)環(huán)境中單列索引占比77%,復(fù)合索引只占了13%,同時復(fù)合查詢條件占比91%。由此可以看出,用23%的復(fù)合索引服務(wù)91%的復(fù)合查詢顯然是不夠的,意味著可能是存在很多SQL執(zhí)行計劃不佳的情況。
過去的開源建設(shè)是針對單個索引、單個SQL的最佳推薦,但具備了全量SQL采集分析能力后,可以做全局性最佳索引的推薦。在數(shù)據(jù)統(tǒng)計維度,可以基于代價進行評估給出整張表綜合索引的建議,進而自動創(chuàng)建和維護索引。
二、深度觀測:全量SQL分析與挖掘
1.為什么要做全量SQL分析?
1)應(yīng)用場景:問題分析定位
全量SQL的應(yīng)用場景比較多。如上圖所示,例如數(shù)據(jù)庫CPU很高或抖了一下是哪些SQL導(dǎo)致的,這些SQL的具體執(zhí)行情況,包括時間響應(yīng)、返回行數(shù)、掃描行數(shù)等。
2)SQL挖掘:深度治理
基于全量SQL分析表、索引是否已廢棄,不同db的熱點表、熱點SQL,單條SQL RT是否穩(wěn)定,甚至可以分析表的活躍數(shù)據(jù)情況等治理場景。
3)兼容混合云產(chǎn)品、統(tǒng)一問題排查
由于混合云產(chǎn)品的差異性與企業(yè)統(tǒng)一管理的矛盾,給問題分析或日常應(yīng)用帶來很大困擾,因此產(chǎn)品設(shè)計時要格外考慮多云兼容性。
有時候,單一云確實提升了某一能力,但混合云下,服務(wù)整體功能的設(shè)計更加復(fù)雜。
2.全量SQL分析實現(xiàn)
全量SQL分析實現(xiàn)的基本流程:SQL請求DAL之后,DAL將SQL轉(zhuǎn)發(fā)到Kafka里面,然后再根據(jù)業(yè)務(wù)場景需要進行消費處理。
比如分析某一個字段是否有在用,只需要通過指紋去重,抓取這一段時間內(nèi)所有這個表的SQL請求,并進行參數(shù)解析,就能輕易分析出所需要的字段。
還比如熱點表、熱點SQL、SQL波動,經(jīng)過先前處理后,可直接通過原數(shù)據(jù)查詢。
通過對一段時間內(nèi)的SQL查詢返回數(shù)據(jù)記錄,分析出活躍數(shù)據(jù)量占比,來指導(dǎo)研發(fā)合理的規(guī)定設(shè)置。
上圖是做采樣的一個樣例,它的維度很豐富,我們可以基于SQL的采樣,進行大量統(tǒng)計分析的工作。
通過top SQL可以分析某個時間段內(nèi)SQL執(zhí)行占比情況,進而推測數(shù)據(jù)庫性能開銷情況,對深入問題分析有比較大的幫助作用。
上圖是第二個應(yīng)用場景,通過波動SQL,查詢不穩(wěn)定集群。預(yù)處理每條SQL時,我們記錄了SQL RT 的p50跟p95時長,把每一個集群下每一條SQL的p95跟p50去做差,然后聚合、排序。波動越大,聚合的差值越大,就大致能推測這個集群是不穩(wěn)定的。
從上圖左下方的圖表可知,它的CPU經(jīng)常具有毛刺。但日常中DBA很難根據(jù)經(jīng)驗照顧到每一個集群,所以需要拉取這些數(shù)據(jù)進行分析或日常治理。
再如DBA發(fā)現(xiàn)某個DB TOP 1的SQL執(zhí)行的次數(shù)幾乎是TOP 2的10倍,分析這個SQL發(fā)現(xiàn)它是一個司機登錄場景。由于活躍的司機體量是有限的,司機登錄動作達到每秒幾萬,這顯然是不合理的。
與研發(fā)溝通后,我們找到了原因:這是典型的業(yè)務(wù)設(shè)計問題,也是一個基礎(chǔ)編碼問題。
三、容量預(yù)測:數(shù)據(jù)庫仿真流量測壓
1.數(shù)據(jù)庫容量評估
基于云上技術(shù)的紅利,從存儲計算一體化的架構(gòu)演進為存儲計算分離的架構(gòu),具備了快速容量彈性的能力。未來目標(biāo)是做到ServerLess化,但目前仍需要一些時間和數(shù)據(jù)進行驗證。
雖然實現(xiàn)了存算分離實現(xiàn)快速擴縮容,但是容量評估仍舊是根據(jù)DBA經(jīng)驗來判斷的,缺乏一些相應(yīng)的數(shù)據(jù)支撐。
2.數(shù)據(jù)庫容量壓測
1)BenchMark
由于BenchMark壓測與真實環(huán)境的SQL表現(xiàn)差距巨大,因此不能用于容量評估。
近年來流行的SQLReplay等流量回放工具,核心就是利用抓包的方式將SQL記錄下來然后機械能回放。它主要的問題是:一方面抓包容易缺漏,另一方面是SQL維度信息缺失難以支持還原真實場景。
2)全鏈路壓測
現(xiàn)在比較流行的方式是全鏈路壓測。它存在的問題是,在真實的業(yè)務(wù)場景下,APP ID之間的調(diào)用關(guān)系極其復(fù)雜。理論上使用全鏈路壓測的方式可以進行壓測評估,但實際應(yīng)用中數(shù)據(jù)上下游調(diào)用可能會造失真的問題,會存在壓不到、壓得過多或過少的情況。
同時,也存在數(shù)據(jù)熱點問題。全鏈路壓測有時會模擬一定的用戶、司機數(shù)據(jù),通常這個量不會特別大,幾百條、上千條就已經(jīng)算是比較多的。由于數(shù)據(jù)庫有cache,很多查詢不回表,所以無法反映真實的數(shù)據(jù)庫的實際負(fù)載情況。
3)仿真流量壓測
在具備了全量SQL后,我們提出了仿真流量壓測。它的大概流程是:高峰期內(nèi),SQL將流量錄制下來保存至Kafka低峰期內(nèi),進行相應(yīng)的消息處理后進行仿真回放。
主要問題:
壓測冪:比如壓測1000次理論上這1000次在任意時間點執(zhí)行SQL的內(nèi)容、數(shù)量以及并發(fā)度都要求保持一致,這是非常困難的;
流量縮放:如果是1:1的回放,理論上是可以還原的。但研發(fā)可能對放量百分比產(chǎn)生疑問,比如流量增加120%,數(shù)據(jù)庫能否撐得住?這種時候只能通過經(jīng)驗預(yù)估容量。成倍放大是容易的,但成比例放大就很麻煩。
主要缺點:
- 使用真實生產(chǎn)環(huán)境進行回訪,不能執(zhí)行DML導(dǎo)致失真;
- 不能保證100%的仿真度,只能無限接近。
3.數(shù)據(jù)庫容量評估應(yīng)用
實際進行壓縮時,我們劃出一條以CPU為主的基準(zhǔn)線,安全的上限值是45%。超過45%之后,無論數(shù)據(jù)庫是否能承受都需要進行擴容。基于這個基線進行壓測,CPU壓到45%時當(dāng)前QPS即是容量的上限水位,這就有利于研發(fā)和DBA后續(xù)直觀地看到容量情況。
目前這一塊內(nèi)容并未完全落地,整體處于開發(fā)階段,我們在理論上還原了SQL執(zhí)行順序與并發(fā)情況。整體并發(fā)模型還需要做深入的打磨跟優(yōu)化。
4.為什么要圍繞SQL死磕?
根據(jù)真實生產(chǎn)的統(tǒng)計,我們將近70%的數(shù)據(jù)庫實際規(guī)格都低于8C。
使用這種小規(guī)格的服務(wù)器,數(shù)據(jù)庫的彈性能力是非常差的,SQL稍有問題都可能擊穿數(shù)據(jù)庫。由于使用的是混合云,無法將數(shù)據(jù)庫穩(wěn)定性保障交給云商統(tǒng)一解決,因此我們只能在現(xiàn)有能力下,構(gòu)建兼容多云的統(tǒng)一管理能力。
數(shù)據(jù)庫最大的兩個挑戰(zhàn):高并發(fā)+大容量。雖然目前貨拉拉還沒有面臨大容量與高并發(fā)的場景,但已初顯端倪,不到3年,我們數(shù)據(jù)庫QPS流量增長了近10倍。
在可預(yù)見的未來,如果我們的訂單再增加1倍,流量可能會增加10倍,現(xiàn)存的SQL問題到時將會更加突出,這也是DBA圍繞SQL進行能力建設(shè)的原因之一。
5.后續(xù)規(guī)劃
目前平臺初步具備了DAS功能的雛形,距離比較完善的產(chǎn)品形態(tài)還要繼續(xù)進行打磨。