圍剿慢SQL,工行MySQL研發(fā)管控和治理實(shí)踐
本文根據(jù)魏亞?wèn)|老師在〖2021 DAMS中國(guó)數(shù)據(jù)智能管理峰會(huì)〗現(xiàn)場(chǎng)演講內(nèi)容整理而成。
講師介紹
魏亞?wèn)|,中國(guó)工商銀行 軟件開(kāi)發(fā)中心三級(jí)經(jīng)理,資深架構(gòu)師,杭州研發(fā)部數(shù)據(jù)庫(kù)專家團(tuán)隊(duì)牽頭人和開(kāi)發(fā)中心安全團(tuán)隊(duì)成員,負(fù)責(zé)技術(shù)管理、數(shù)據(jù)庫(kù)、安全相關(guān)工作,目前負(fù)責(zé)SaaS云產(chǎn)品建設(shè)。2009年加入中國(guó)工商銀行軟件開(kāi)發(fā)中心,致力于推動(dòng)管理創(chuàng)新、效能提升,提供全面技術(shù)管控,推動(dòng)自動(dòng)化實(shí)施,實(shí)現(xiàn)業(yè)務(wù)價(jià)值的高質(zhì)量快速交付;同時(shí)作為技術(shù)專家,為生產(chǎn)安全提供技術(shù)支持。
分享概要
- 風(fēng)險(xiǎn)介紹
- 風(fēng)險(xiǎn)防范
- 方法論
- 確??陕涞?/li>
- 生產(chǎn)防控
- 生產(chǎn)防控
- SRE管控體系
- 未來(lái)暢想
大家好,感謝dbaplus社群給我這個(gè)和大家交流的機(jī)會(huì),今天分享的主題是《工行MySQL研發(fā)管控和治理實(shí)踐》。之前我在各種分享過(guò)程中,也多次強(qiáng)調(diào)過(guò)只有對(duì)自己來(lái)說(shuō)最合適的產(chǎn)品,而沒(méi)有所謂最好的產(chǎn)品,雖然每種數(shù)據(jù)庫(kù)產(chǎn)品都把自己形容得很好,但實(shí)際上也都是針對(duì)一些特定場(chǎng)景去做的開(kāi)發(fā),即每種產(chǎn)品都有自己適用的場(chǎng)景,沒(méi)有可以包打天下的產(chǎn)品。
一、風(fēng)險(xiǎn)介紹
首先介紹MySQL的痛點(diǎn)。因?yàn)镸ySQL是免費(fèi)的,所以我們?cè)谑褂眠^(guò)程中必須承擔(dān)它所帶來(lái)的風(fēng)險(xiǎn),換句話說(shuō),這就是生命中不可承受之痛。比如慢SQL在業(yè)界就算是一種通病,不論哪個(gè)公司,只要用了MySQL數(shù)據(jù)庫(kù),慢SQL就必然是所有問(wèn)題的重中之重。
像阿里在一篇介紹SRE團(tuán)隊(duì)建設(shè)與職能分工的文章中曾提及:在SRE建設(shè)過(guò)程中,他們發(fā)現(xiàn),慢SQL已經(jīng)成為了一種挑戰(zhàn):數(shù)據(jù)庫(kù)出現(xiàn)瓶頸,無(wú)法支撐業(yè)務(wù)發(fā)展;慢SQL的數(shù)量呈爆發(fā)式增長(zhǎng),應(yīng)用穩(wěn)定性岌岌可危等。
而對(duì)于工行來(lái)說(shuō),同樣遇到類似的問(wèn)題,可以說(shuō)是不可避免的問(wèn)題:
數(shù)據(jù)庫(kù)性能急劇下降,CPU占用100%
大家可以看圖中左下角位置,這其實(shí)就是一個(gè)CPU在慢SQL影響下急劇飆升的情況。大量數(shù)據(jù)掃描會(huì)導(dǎo)致CPU飚高,1個(gè)線程最高可以把一個(gè)CPU吃滿,如果并發(fā)線程多的話,整體的CPU使用率就會(huì)急劇飆升,后果很嚴(yán)重。大家都知道,InnoDB有一個(gè)線程池innodb_thread_concurrency,這個(gè)池是有大小上限的,如果它用盡了,就會(huì)導(dǎo)致整個(gè)交易堵塞。以前再快的交易最后都會(huì)變慢。平時(shí)零點(diǎn)幾秒就可以解決的事情,最后可能需要幾秒、十幾秒,這實(shí)際上就引發(fā)出一種暴風(fēng)式的連鎖反應(yīng)。之前我所在的研發(fā)部就有一個(gè)MySQL應(yīng)用,其拆分為4個(gè)群組,其中一個(gè)群組就是因?yàn)橐粋€(gè)慢SQL,導(dǎo)致服務(wù)器完全不可用,無(wú)法對(duì)外提供服務(wù)。最后緊急進(jìn)行了主備切換才解決了生產(chǎn)穩(wěn)定性的問(wèn)題。
主從復(fù)制時(shí)間延遲,影響RPO和RTO時(shí)效性,存在生產(chǎn)隱患
涉及主備切換時(shí)通常做法都會(huì)檢查主備的不一致性,確保備庫(kù)追平主庫(kù)后才做切換。我們金融行業(yè)對(duì)高可用性要求非常嚴(yán)謹(jǐn),RPO需要小于60秒。但慢SQL會(huì)導(dǎo)致60秒內(nèi)無(wú)法完成切換,之前我們有應(yīng)用一個(gè)交易的主從復(fù)制時(shí)間增至24小時(shí)都未結(jié)束,所以后面我們會(huì)采取一系列措施對(duì)這方面進(jìn)行強(qiáng)化治理。
讀寫(xiě)分離存在過(guò)期讀,影響數(shù)據(jù)一致性
對(duì)于傳統(tǒng)公司來(lái)說(shuō),如果想做讀寫(xiě)分離,應(yīng)該是用一些不變的或者極少變化的數(shù)據(jù)去做。但我們有的應(yīng)用因?yàn)閷?duì)讀寫(xiě)分離機(jī)制了解不深,也沒(méi)有考慮主從復(fù)制的時(shí)效性,把一些時(shí)效性要求非常高的數(shù)據(jù)從備庫(kù)去讀,這就導(dǎo)致了數(shù)據(jù)的不一致,引發(fā)生產(chǎn)隱患。最后領(lǐng)導(dǎo)只能選擇“一刀切”,原則上禁止我們將MySQL備庫(kù)作為讀庫(kù)進(jìn)行讀寫(xiě)分離,因?yàn)榧幢闶褂脭?shù)據(jù)分布式訪問(wèn)中間層,比如MyCAT、愛(ài)可生的DBLE、阿里的 TDDL或網(wǎng)易的DDB等,如果把備庫(kù)當(dāng)作讀庫(kù),還是會(huì)存在過(guò)期讀這種生產(chǎn)隱患。
二、風(fēng)險(xiǎn)防范
之前我在歷次分享中多次強(qiáng)調(diào)過(guò),免費(fèi)的午餐并不好吃。無(wú)數(shù)的案例告訴我們,慢SQL如果不加處理,最后很容易引發(fā)一個(gè)血案。大家如果看過(guò)電影《無(wú)極》的話,應(yīng)該知道它又被稱為“一個(gè)饅頭引發(fā)的血案”。
工行的MySQL數(shù)據(jù)庫(kù)實(shí)例近8000個(gè),云化占比在90%以上,慢SQL數(shù)量呈爆發(fā)式增長(zhǎng),一條慢SQL就可以導(dǎo)致服務(wù)不可用,降低用戶幸福指數(shù)。而對(duì)于金融行業(yè)來(lái)說(shuō),社會(huì)聲譽(yù)性是必須要考慮的關(guān)鍵因素之一,當(dāng)服務(wù)不可用之后,很容易存在擠兌的風(fēng)潮。我們幾年前上了CCTV其實(shí)也是同樣的道理,工行代表的是社會(huì)穩(wěn)定性的基礎(chǔ)。
從我們治理的統(tǒng)計(jì)結(jié)果來(lái)看,還是相當(dāng)有成效的。大家可以看到,我們單個(gè)事務(wù)超過(guò)10萬(wàn)的大事務(wù)的報(bào)警次數(shù),通過(guò)治理,由年初的每月500萬(wàn)次左右,逐月下降至目前的100萬(wàn)次左右,問(wèn)題收斂趨勢(shì)明顯,但數(shù)量級(jí)擺在那兒,所以我們還是任重而道遠(yuǎn)。用屈原的話說(shuō)就是“路漫漫其修遠(yuǎn)兮,吾將上下而求索”。
工行的治理實(shí)踐大概分4個(gè)階段,我們基本上是基于自動(dòng)化的流水線,也就是DevOps去做這些事情的。
1、設(shè)計(jì)階段
首先,在設(shè)計(jì)階段我們會(huì)規(guī)范一些設(shè)計(jì)指引。大家如果有做過(guò)編碼,或者本身就是數(shù)據(jù)庫(kù)領(lǐng)域的專家的話就會(huì)知道,我們必須要夯實(shí)我們的方法論,而這個(gè)方法論就代表著我們?cè)O(shè)計(jì)指引的處理。比如數(shù)據(jù)庫(kù)必須要建主鍵等,這其實(shí)都屬于我們方法論的層面。
然后就是元數(shù)據(jù)管理,將數(shù)據(jù)標(biāo)準(zhǔn)按照應(yīng)用、產(chǎn)品線等進(jìn)行規(guī)范,抽取制定數(shù)據(jù)標(biāo)準(zhǔn),形成元數(shù)據(jù)字典?,F(xiàn)在流行一個(gè)概念叫元宇宙,而元數(shù)據(jù)我們把它簡(jiǎn)稱為Meta。Facebook最近也改名為 Meta,這說(shuō)明我們?cè)?0年前就已經(jīng)預(yù)見(jiàn)到了這種問(wèn)題。
第三是建立能力提升課程。我們將數(shù)據(jù)庫(kù)的使用人分成三級(jí)。第一級(jí)是基礎(chǔ)開(kāi)發(fā)人員,他需要滿足一些MySQL常見(jiàn)的使用方式;第二級(jí)我們定位為DBA的處理,DBA需要分析InnoDB的本質(zhì),進(jìn)行語(yǔ)句調(diào)優(yōu)等;而第三級(jí)就是高階,我們希望他去對(duì)一些底層的邏輯進(jìn)行處理,比如通過(guò)查看MySQL的源代碼,判斷死鎖等,從深處進(jìn)行發(fā)掘,幫助大家快速定位和解決問(wèn)題。
最后我們落實(shí)自動(dòng)化處理,建立表結(jié)構(gòu)設(shè)計(jì)工具。我們?cè)贓xcel的基礎(chǔ)上做了一個(gè)元數(shù)據(jù)表結(jié)構(gòu)設(shè)計(jì)工具,同時(shí)將它與我們的元數(shù)據(jù)管理系統(tǒng)進(jìn)行連接。我們規(guī)定了業(yè)務(wù)線的數(shù)據(jù)標(biāo)準(zhǔn),所有基于這條業(yè)務(wù)線的應(yīng)用都必須滿足所制定的數(shù)據(jù)基礎(chǔ),這就是我們所謂的元數(shù)據(jù)的概念。這樣一來(lái),后續(xù)我們的數(shù)據(jù)治理,包括從數(shù)據(jù)湖中撈取數(shù)據(jù)等都能保持一致的數(shù)據(jù)標(biāo)準(zhǔn),對(duì)我們進(jìn)行一些數(shù)據(jù)挖掘、上下游聯(lián)動(dòng),以及后面會(huì)提到的根因分析,都會(huì)起到非常好的作用。
2、編碼層面
在編碼層面,我們強(qiáng)調(diào)規(guī)范的自動(dòng)化。如果只有規(guī)范而沒(méi)有落地執(zhí)行,那就相當(dāng)于紙上談兵,永遠(yuǎn)無(wú)法落于實(shí)處。所以我們基于SonarQube擴(kuò)展建立一些規(guī)則,在開(kāi)發(fā)階段就去檢查大家的語(yǔ)法是否正確、是否存在安全隱患等,防患于未然。
同時(shí),考慮到一些安全性相關(guān)的問(wèn)題,這其中還包含了SQL注入的檢查。比如MyBatis到底用“$”還是“#”號(hào)去處理等問(wèn)題,防止SQL注入的風(fēng)險(xiǎn)。
還有就是對(duì)SQL寫(xiě)法的規(guī)則。這里會(huì)講到我們經(jīng)歷過(guò)的一個(gè)案例:開(kāi)發(fā)人員在update的時(shí)候少了一個(gè)逗號(hào),用and進(jìn)行了連接,并由此引發(fā)了一個(gè)更新血案。因此后來(lái)我們?cè)诒镜鼗赟onarLint的插件做了一個(gè)擴(kuò)展,將SonarLint安裝在開(kāi)發(fā)人員的本地。因?yàn)镾onarLint跟SonarQube是完整的一個(gè)契合體,這樣一來(lái),云端的規(guī)則制定以后,我們本地的規(guī)則也會(huì)進(jìn)行同步,避免了開(kāi)發(fā)人員自己再去安裝插件的過(guò)程,減少對(duì)開(kāi)發(fā)人員的工作干擾。大家看阿里的開(kāi)發(fā)手冊(cè),p3c的一些組件檢查規(guī)則現(xiàn)在也在Sonar中進(jìn)行了一些擴(kuò)展。
3、測(cè)試階段
測(cè)試階段包含兩個(gè)方面的內(nèi)容,一個(gè)是安全測(cè)試,一個(gè)是性能測(cè)試。
因?yàn)楹芏鄷r(shí)候我們都必須預(yù)估交易量,例如預(yù)測(cè)半年內(nèi)交易量的增長(zhǎng)趨勢(shì),同時(shí)判斷會(huì)不會(huì)有其他場(chǎng)景的影響等,所以我們必須進(jìn)行壓測(cè),這部分我們可以借助一些壓測(cè)平臺(tái)進(jìn)行數(shù)據(jù)庫(kù)的壓測(cè)。
同時(shí),針對(duì)安全測(cè)試我們也建立了DevSecOps這條黃金管道流水線,通過(guò)一些白盒測(cè)試(SAST)、黑盒測(cè)試(DAST)還有IAST等交互式的測(cè)試,來(lái)實(shí)現(xiàn)安全測(cè)試。
大家如果有關(guān)注“OWASP Top 10榜單”的話就能看到,注入風(fēng)險(xiǎn)的排名其實(shí)是比較高的。
4、交付后
最后是交付后。在這個(gè)階段我們會(huì)進(jìn)行SRE的管理。SRE這個(gè)概念由Google首先提出,大家也正在實(shí)踐過(guò)程中。但從個(gè)人角度來(lái)看,我們其實(shí)提概念要大于實(shí)施。所以參照Google的實(shí)踐體系,我們重建了一個(gè)自己的SRE的管理體系,這其中就包含了慢SQL的監(jiān)控治理。
接下來(lái)是對(duì)生產(chǎn)案例的分析。當(dāng)出現(xiàn)一個(gè)生產(chǎn)案例以后,我們會(huì)分析它的解決路徑、記錄并分析在解決過(guò)程中遇到的好或不好的地方、思考后續(xù)的改進(jìn)方法等,將它們匯總成一個(gè)生產(chǎn)問(wèn)題分析文檔,定期在整個(gè)基地內(nèi)部組織各部門(mén)進(jìn)行學(xué)習(xí),以規(guī)避相同的問(wèn)題再度出現(xiàn)。因?yàn)槲蚁嘈?,不管你是否關(guān)注,只要看了文檔,有了一定的印象以后,后面如果再出現(xiàn)類似的場(chǎng)景就會(huì)去下意識(shí)地進(jìn)行規(guī)避,我們把這稱為潛移默化。
第三部分是AIOps的根因分析?,F(xiàn)在業(yè)界比較流行“1-5-10”這個(gè)概念,即一分鐘發(fā)現(xiàn)問(wèn)題,五分鐘定位問(wèn)題,十分鐘解決問(wèn)題。雖然這個(gè)理念很好,但從目前來(lái)看,“一”現(xiàn)在正在努力,“五”和“十”還屬于更加高階的處理,后面會(huì)簡(jiǎn)單再說(shuō)一下。
同時(shí),我們?cè)谏a(chǎn)上會(huì)建立一個(gè)慢SQL的查殺機(jī)制,將一些大事務(wù)提前進(jìn)行kill掉以進(jìn)行規(guī)避,將慢SQL對(duì)生產(chǎn)的一些風(fēng)險(xiǎn)提前扼殺。
理論說(shuō)起來(lái)很簡(jiǎn)單,但關(guān)鍵在于,大家是否愿意把它作為一個(gè)體系去做。也就是說(shuō),我們并不希望只是將它當(dāng)成一個(gè)工具去做,而是希望建成一個(gè)研發(fā)管控的完整生態(tài)體系。只有形成了生態(tài)圈,最后才能做好治理管控。
三、方法論
首先是方法論的建立。俗話說(shuō)萬(wàn)事開(kāi)頭難,我們的體系要想建立,就必須有方法論作為基石。這部分我們大致分為四步:
第一我們會(huì)做一些規(guī)范的說(shuō)明。比如:每個(gè)表必須建立主鍵;禁止給庫(kù)、表、字段單獨(dú)設(shè)置排序規(guī)則等。
第二是量化,通過(guò)精細(xì)化的理性思維去規(guī)范、約束大家。中國(guó)人其實(shí)感性思維占多數(shù),比如我們做菜的時(shí)候會(huì)說(shuō):“我們加少許醬油。”這個(gè)“少許”到底是多少?日本人可能會(huì)說(shuō)5克或10克來(lái)具體定量,但中國(guó)人喜歡說(shuō)少許。而對(duì)于我們來(lái)說(shuō),就是把掃描命中比等進(jìn)行量化,要求聯(lián)機(jī)情況下rows_examined:rows_sent<100:1,規(guī)定事務(wù)大小undo<10萬(wàn)等。不同的公司有不同的標(biāo)準(zhǔn),這是我們對(duì)于自己的要求。
19年我們?cè)诮ㄟ@個(gè)體系時(shí),正在跟愛(ài)可生公司合作,因此有機(jī)會(huì)了解到他們對(duì)大事務(wù)的規(guī)范是在1萬(wàn)條以內(nèi)。所以,因?yàn)椴煌墓鞠到y(tǒng)硬件等條件不同,我們必須要根據(jù)所在企業(yè)實(shí)際情況去進(jìn)行考量。
第三,我們要學(xué)會(huì)避坑。因?yàn)镸ySQL畢竟是一個(gè)開(kāi)源免費(fèi)的產(chǎn)品,所以它會(huì)有很多bug。比如大表的truncate,它其實(shí)會(huì)引發(fā)MySQL服務(wù)hang死的現(xiàn)象,最后大家可以在MySQL.err文件中發(fā)現(xiàn)一條 page_cleaner臟刷記錄的警告,同時(shí)還有它超過(guò)了多長(zhǎng)時(shí)間,以及一些LRU的提示。還有就是禁用replace into。因?yàn)閞eplace into它的風(fēng)險(xiǎn)大概有三種,我相信大家應(yīng)該也都遇見(jiàn)過(guò),這里的話就不細(xì)說(shuō)了。
第四,是易理解。通過(guò)一些方式,告訴他們?cè)鯓尤ダ斫?,讓他們既知其然,也知其所以然。?duì)此我們會(huì)做一些條款的解讀,方便用戶知道規(guī)范制定的原因,以及可能會(huì)引發(fā)的問(wèn)題等。
通過(guò)這四步,把方法論的基石建立起來(lái),同時(shí)我們會(huì)基于SonarQube擴(kuò)展一定的規(guī)則。大家從圖中右上角的截圖可以看到,我們現(xiàn)在已經(jīng)在質(zhì)量門(mén)禁中把這些規(guī)則加進(jìn)去了。
四、確??陕涞?/h2>
規(guī)范建立以后,如果依賴于人,那就有可能會(huì)產(chǎn)生許多不確定的額外風(fēng)險(xiǎn),所以我們要通過(guò)自動(dòng)化的質(zhì)量門(mén)禁來(lái)解決這個(gè)問(wèn)題。我們建立了一個(gè)重自動(dòng)化、輕指引的質(zhì)量門(mén)禁系統(tǒng)。這樣一來(lái),不管有沒(méi)有問(wèn)題,門(mén)禁系統(tǒng)都會(huì)幫你進(jìn)行把控,提前將風(fēng)險(xiǎn)扼殺。
如果大家有做過(guò)代碼復(fù)核或其他一些規(guī)范工作的話就會(huì)明白,人在看到東西非常多時(shí),就會(huì)下意識(shí)地產(chǎn)生逃避的想法,這樣很容易就會(huì)把一個(gè)本來(lái)可以控制住的場(chǎng)景直接忽略。像我們是基于druid擴(kuò)展Sonarqube的插件,實(shí)現(xiàn)mapper.xml文件的掃描分析,并做到了本地檢查規(guī)則與云端同步。
我們目前已經(jīng)建立了27條規(guī)則,后續(xù)也還在逐步完善豐富。從目前來(lái)看,已經(jīng)涵蓋了所有開(kāi)發(fā)人員最常見(jiàn)的一些問(wèn)題。
這里有一條業(yè)界可能沒(méi)有的規(guī)范,就是:MySQL的Update語(yǔ)句的SET中,出現(xiàn)and可能是一個(gè)問(wèn)題,根據(jù)SQL標(biāo)準(zhǔn)語(yǔ)法來(lái)看,原則上多個(gè)字段的更新中應(yīng)該用逗號(hào)進(jìn)行分割。在現(xiàn)實(shí)情況中,一般用逗號(hào)的人比較多,但確實(shí)也有開(kāi)發(fā)人員中間用and去做分割??梢钥磮D中備注舉例的語(yǔ)句,這樣會(huì)導(dǎo)致它一個(gè)字段被更新成一個(gè)不可靠的布爾值,最后導(dǎo)致結(jié)果跟預(yù)期完全不同,導(dǎo)致很嚴(yán)重的生產(chǎn)問(wèn)題產(chǎn)生。所以針對(duì)該情況我們進(jìn)行了一些額外的擴(kuò)展。同時(shí),對(duì)于replace into,我們也不建議去使用。還有truncate,這部分我們建議大家用Drop + create去解決這方面的問(wèn)題。
五、生產(chǎn)防控
生產(chǎn)上我們會(huì)通過(guò)監(jiān)控自動(dòng)查殺。但實(shí)際上,如果大家學(xué)過(guò)博弈論的話就會(huì)發(fā)現(xiàn):是否查殺?到底怎么保持?這其實(shí)很難平衡,可能要通過(guò)實(shí)際場(chǎng)景去評(píng)估到底要不要去做。
接下來(lái)是慢SQL的治理。我們?cè)?021年上半年大概發(fā)現(xiàn)了6670條慢SQL并落實(shí)版本優(yōu)化,但正確率其實(shí)并不高,后續(xù)我們會(huì)考慮優(yōu)化一些慢SQL的治理模型,將我們的準(zhǔn)確率從20%再進(jìn)行提升。
因?yàn)?0%就意味著,我們的開(kāi)發(fā)人員可能要花80%的無(wú)效時(shí)間去處理這方面的問(wèn)題,顯然違背了二八原則。雖然這個(gè)過(guò)程很痛苦,但我們確實(shí)收到一定的經(jīng)營(yíng)效果。本質(zhì)上我們可以看到performance_schema可以用于監(jiān)控MySQL運(yùn)行過(guò)程中的資源消耗、資源等待等情況。這應(yīng)該是MySQL 5.7以后會(huì)有的一個(gè)視圖,這個(gè)視圖中有一個(gè)表statements_summary_by_digest,它會(huì)記錄每一條SQL的執(zhí)行次數(shù)、時(shí)間,以及掃描的數(shù)據(jù)量等,通過(guò)對(duì)它們時(shí)間差的對(duì)比,獲取真正的處理時(shí)間,從而判斷語(yǔ)句是否存在問(wèn)題。
Oracle的awr報(bào)告也是這樣的道理,它是通過(guò)兩個(gè)快照之間的差去進(jìn)行比較。對(duì)于我們來(lái)說(shuō),比如8:00、9:00,我們的時(shí)間是一個(gè)語(yǔ)句。如圖所示,它在8點(diǎn)執(zhí)行了200次,執(zhí)行時(shí)間是1800秒,掃描的記錄數(shù)大概是1億8000萬(wàn);第二個(gè)是在9點(diǎn),執(zhí)行次數(shù)是300次,執(zhí)行時(shí)間是2700秒。通過(guò)時(shí)間差可以判斷,8:00~9:00之間只執(zhí)行了100次,執(zhí)行時(shí)間為900秒,那相當(dāng)于一次執(zhí)行花費(fèi)了9秒,這其實(shí)就是一個(gè)標(biāo)準(zhǔn)的慢SQL。
雖然我不清楚在座各位所屬應(yīng)用對(duì)慢SQL的判定標(biāo)準(zhǔn),默認(rèn)應(yīng)該是大于10秒的才算慢SQL。但對(duì)于我們金融行業(yè)來(lái)說(shuō),實(shí)際上超過(guò)一秒都屬于慢SQL的處理范圍。同時(shí)我們可以看到,它的掃描記錄數(shù)大概是9000萬(wàn),這樣算來(lái),它的掃描命中比例是900000:1,也就是說(shuō),我需要掃描90萬(wàn)條數(shù)據(jù)才能找到一條數(shù)據(jù),這樣的掃描比有很大的問(wèn)題,顯然存在效率問(wèn)題,而我們的規(guī)范要求是100:1。
接下來(lái)是自動(dòng)查殺。我們可以設(shè)置,當(dāng)聯(lián)機(jī)超過(guò)閾值時(shí)自動(dòng)執(zhí)行kill。但這樣的做法在批量聯(lián)機(jī)混合時(shí)存在風(fēng)險(xiǎn),因?yàn)槲覀儸F(xiàn)在的批量聯(lián)機(jī)用戶實(shí)際上都是混合在一起的,而我們?cè)试S批量耗時(shí)超過(guò)10秒,這就很容易出現(xiàn)誤殺。針對(duì)這一點(diǎn),我們可以通過(guò)show processlist命令查看或者是通過(guò) ps.threads去跟進(jìn)線程的執(zhí)行情況。
針對(duì)上述情況,我們做了兩件事情:第一是推聯(lián)機(jī)用戶跟批量用戶的分離,針對(duì)不同用戶進(jìn)行差異性處理。對(duì)于聯(lián)機(jī)用戶我們會(huì)進(jìn)行自動(dòng)查殺;而對(duì)于批量用戶,因?yàn)槲覀兣袛嗨Z(yǔ)句執(zhí)行所花費(fèi)的時(shí)間是合理的,所以就暫時(shí)先不管。
MySQL其實(shí)并不適合OLAP的應(yīng)用,按照我的理解,我們可以通過(guò)大數(shù)據(jù)平臺(tái),也就是Hive、Spark,或者通過(guò)一些其他的方式去處理。這實(shí)際上就代表:MySQL僅局限于OLTP,其他像一些大數(shù)據(jù)平臺(tái)等去做一些OLAP的處理,做到權(quán)責(zé)分離。
看到這里大家可能會(huì)說(shuō)HTAP,我覺(jué)得這是一個(gè)老概念,屬于新瓶裝舊酒,以前Oracle其實(shí)就是HTAP數(shù)據(jù)庫(kù),但MySQL不行,所以需要結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景做到功能和場(chǎng)景的分離。
六、生產(chǎn)防控
接下來(lái)是處理大事務(wù)的納什均衡,也就是對(duì)監(jiān)控和自動(dòng)查殺的危害進(jìn)行分析。因?yàn)槲覀儸F(xiàn)在的主從控制模式都是基于行復(fù)制的模式,所以,針對(duì)這種行復(fù)制模式,如果是大事務(wù),我們binlog寫(xiě)入、傳輸,還有在備機(jī)的回放速度都會(huì)很慢。我們之前有應(yīng)用被發(fā)現(xiàn)24小時(shí)都沒(méi)有在備庫(kù)完成重演,最后查出原因:因?yàn)檫@個(gè)表是新建的,所以它沒(méi)有建主鍵,相當(dāng)于每次都去做全掃,同時(shí)因?yàn)樗且粋€(gè)大事務(wù),最后就導(dǎo)致24小時(shí)都沒(méi)有回放完成。而解決方案也很簡(jiǎn)單,把事務(wù)量降低,同時(shí)對(duì)表進(jìn)行增加主鍵的處理。
然后就是交易寫(xiě)入堵塞,以及當(dāng)主庫(kù)出現(xiàn)故障時(shí)面臨的、切與不切之間的博弈。在這種大事務(wù)情況下,如果有些應(yīng)用比較著急,那就會(huì)切,但這樣可能會(huì)導(dǎo)致一些庫(kù)的數(shù)據(jù)沒(méi)有重演完成,使業(yè)務(wù)存在風(fēng)險(xiǎn);但如果選擇不切,而是等它自然結(jié)束的話,就有可能滿足不了我們3個(gè)9的高可用度。在這樣兩難的情況下,切與不切都會(huì)導(dǎo)致問(wèn)題。最后只能靠上帝或者靠領(lǐng)導(dǎo)拍板。但無(wú)論最后的決定是什么,我們都可能會(huì)面對(duì)在這方面受到業(yè)務(wù)或者客戶的投訴的情況,所以,根據(jù)我的親身經(jīng)歷,我認(rèn)為這種風(fēng)險(xiǎn)是非常巨大的。
為此我們做了自動(dòng)查殺。大家可以看到,MySQL可以通過(guò)執(zhí)行show engine innodb status這個(gè)命令,對(duì)事務(wù)進(jìn)行監(jiān)控。在事務(wù)還沒(méi)有結(jié)束時(shí),會(huì)提示這個(gè)事務(wù)更新的記錄數(shù),而/G是我們對(duì)結(jié)果進(jìn)行格式化,大家有機(jī)會(huì)的話可以嘗試一下。
如果超過(guò)設(shè)定好的閾值,我們會(huì)自動(dòng)執(zhí)行kill。但在執(zhí)行這個(gè)操作時(shí)我們需要規(guī)避一刀切的情況,所以我們現(xiàn)在僅進(jìn)行一些小規(guī)模的試點(diǎn)。在試點(diǎn)完成以后才會(huì)進(jìn)行大規(guī)模的處理,說(shuō)白了就是不敢強(qiáng)上,因?yàn)閺?qiáng)上很容易出問(wèn)題。
關(guān)于日志的導(dǎo)入問(wèn)題如圖所示,這個(gè)事務(wù)里有一個(gè)導(dǎo)入操作,目前已經(jīng)導(dǎo)入了3,245,700多條數(shù)據(jù),這個(gè)大事務(wù)會(huì)影響我們很多事務(wù)的處理,我們就可以通過(guò)后臺(tái)自動(dòng)把這個(gè)事務(wù)終止掉,避免問(wèn)題進(jìn)一步擴(kuò)大。
七、SRE管控體系
一般情況下,從Google對(duì)SRE的解釋來(lái)看,它實(shí)際上是從生產(chǎn)運(yùn)維層面去進(jìn)行生產(chǎn)事件的處理和回溯。但是從開(kāi)發(fā)團(tuán)隊(duì)的角度,因?yàn)閷?duì)于金融行業(yè)來(lái)說(shuō),運(yùn)維團(tuán)隊(duì)和開(kāi)發(fā)團(tuán)隊(duì)并不一樣,而且相互間容易存在掣肘。
這里我們分為三部分進(jìn)行分析:
1、生產(chǎn)應(yīng)急 運(yùn)維分析
1)牽頭生產(chǎn)應(yīng)急響應(yīng)。
協(xié)助處理緊急生產(chǎn)問(wèn)題,審核相關(guān)變更方案,確保問(wèn)題閉環(huán),形成總結(jié)文檔(包含影響、結(jié)果、待提升項(xiàng)、做的好的地方、處理時(shí)間線),定期更新“發(fā)布CheckList”。
牽頭重點(diǎn)問(wèn)題復(fù)盤(pán),組織專項(xiàng)排查治理,涉及性能容量、賬務(wù)一致性、分布式體系等,確保范圍無(wú)疏漏,制定方案、審核整改計(jì)劃。
2)分析確認(rèn)運(yùn)維效果
建立測(cè)試和生產(chǎn)巡檢機(jī)制,通過(guò)每日巡檢、重要節(jié)日深度巡檢、投產(chǎn)前風(fēng)險(xiǎn)評(píng)估多層次巡檢方式以保障生產(chǎn)運(yùn)行安全。
觀察生產(chǎn)運(yùn)維效果情況,確認(rèn)SLI、SLO和SLA等是否滿足設(shè)定目標(biāo),輔助產(chǎn)品經(jīng)理形成運(yùn)維分析報(bào)告。
組織建設(shè)進(jìn)階要求的相關(guān)配套工具,包括質(zhì)量門(mén)禁、白名單管控、代碼掃描、自動(dòng)運(yùn)維平臺(tái)和全息監(jiān)控平臺(tái)的數(shù)據(jù)分析等。
2、研發(fā)階段
1)規(guī)范升級(jí)研發(fā)流程。
需求分析階段提交待提升項(xiàng)給產(chǎn)品經(jīng)理,落實(shí)版本計(jì)劃安排。
設(shè)計(jì)階段指導(dǎo)架構(gòu)師完成非功能性需求評(píng)估,涉及監(jiān)控預(yù)警、灰度方案、發(fā)布方案、安全可信、應(yīng)急預(yù)案、SLI等;以未來(lái)視角指導(dǎo)架構(gòu)師完成性能和容量規(guī)劃;指導(dǎo)架構(gòu)師形成技術(shù)架構(gòu)的未來(lái)規(guī)劃,提供可執(zhí)行的路線路,推進(jìn)架構(gòu)轉(zhuǎn)型;做好標(biāo)準(zhǔn)化方案和組件。
3、發(fā)布階段
在發(fā)布時(shí),我們會(huì)根據(jù)CheckList,對(duì)相關(guān)實(shí)現(xiàn)情況進(jìn)行核對(duì)勾選,在確保所有指標(biāo)都達(dá)標(biāo)以后,才允許它進(jìn)行正式發(fā)布。這樣就能夠在應(yīng)用質(zhì)量方面有較大的提升。
八、未來(lái)暢想
最后簡(jiǎn)單介紹一下我們對(duì)未來(lái)的暢想,也就是我們現(xiàn)在正在做的事情。
上文提到,我們一直在做“1-5-10”。但是目前還處于“1”穩(wěn)步推進(jìn),“5”和“10”艱難實(shí)現(xiàn)的階段。
針對(duì)一分鐘定位我們發(fā)現(xiàn),我們其實(shí)并沒(méi)有那么多采集指標(biāo),所以對(duì)一些數(shù)據(jù)可以加大采集,比如常規(guī)數(shù)據(jù):CPU、內(nèi)存......等,目前對(duì)于中間件系統(tǒng)基礎(chǔ)監(jiān)控?cái)?shù)據(jù)已經(jīng)完成處理了,像網(wǎng)絡(luò)、QPS、連接數(shù)等。
針對(duì)MySQL數(shù)據(jù)庫(kù),其實(shí)它有一些性能指標(biāo)可以進(jìn)行高密度采集,也有一些影響數(shù)據(jù)庫(kù)性能的要素指標(biāo)需要進(jìn)行低密度采集。這部分主要分為兩類,第一類是像ps.threads這種可以高密度地處理的,同時(shí)show engine innodb status,這樣我們可以快速發(fā)現(xiàn)到底用哪些死鎖,或迅速了解某個(gè)事務(wù)處理的數(shù)據(jù)量,以及哪些線程在做哪些事情等。這些是我們要做高密度采集的事情。低密度采集也就是我們提到過(guò)的摘要信息的處理,每小時(shí)進(jìn)行一次快照的數(shù)據(jù)分析,同時(shí)通過(guò)events_statements_history,對(duì)數(shù)據(jù)進(jìn)行定時(shí)采集。
通過(guò)高密度采集,我們可以快速進(jìn)行一分鐘定位,查出出現(xiàn)問(wèn)題的具體位置。
接下來(lái)是五分鐘預(yù)判。我們工行的實(shí)驗(yàn)室之前有用“邏輯回歸加孤立森林算法進(jìn)行異常檢測(cè),用圖算法進(jìn)行根因定位”對(duì)全鏈路進(jìn)行一些根因的分析和追溯。但通過(guò)我們之前跟某Top企業(yè)交流時(shí)發(fā)現(xiàn),根因定位這個(gè)方法實(shí)際的正確率只在40%左右,波動(dòng)檢測(cè)精度可達(dá)到80以上,但該算法屬于監(jiān)督算法,需要針對(duì)性訓(xùn)練,無(wú)法大規(guī)模普及,且模型并沒(méi)有達(dá)到我們所預(yù)想的標(biāo)準(zhǔn)。之前阿里在中臺(tái)有一篇宣傳文章,介紹說(shuō)它的五分鐘預(yù)判準(zhǔn)確率可以達(dá)到90%,雖然我不太相信這個(gè)值,但他們的模型應(yīng)該是相對(duì)比較好的。
十分鐘自愈這部分算是我們對(duì)未來(lái)的期望,我們希望未來(lái)在發(fā)現(xiàn)問(wèn)題以后,系統(tǒng)可以直接自行處理。這部分其實(shí)我們現(xiàn)在在做的一些自動(dòng)化運(yùn)維可以達(dá)到這個(gè)要求。比如當(dāng)數(shù)據(jù)庫(kù)發(fā)現(xiàn)問(wèn)題以后,經(jīng)過(guò)一些檢測(cè),自動(dòng)進(jìn)行主從切換。這其實(shí)也屬于十分鐘自愈的范疇。
我們只能說(shuō)還在路上,但是未來(lái)具體是什么樣的?目前我們也只能猜測(cè)。希望未來(lái)會(huì)更加美好!