自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

訪問數(shù)據(jù)庫總超時(shí)?這份避坑指南請(qǐng)收好

運(yùn)維 數(shù)據(jù)庫運(yùn)維
電商公司大都希望做社交引流,社交公司大都希望做電商,從而將流量變現(xiàn),所以社交電商一直是熱門的創(chuàng)業(yè)方向。這個(gè)真實(shí)的案例來自某家做社交電商的創(chuàng)業(yè)公司。

本文轉(zhuǎn)載自微信公眾號(hào)「數(shù)倉寶貝庫」,作者李玥   。轉(zhuǎn)載本文請(qǐng)聯(lián)系數(shù)倉寶貝庫公眾號(hào)。

 01事故排查過程

電商公司大都希望做社交引流,社交公司大都希望做電商,從而將流量變現(xiàn),所以社交電商一直是熱門的創(chuàng)業(yè)方向。這個(gè)真實(shí)的案例來自某家做社交電商的創(chuàng)業(yè)公司。下面就來一起看下這個(gè)典型的數(shù)據(jù)庫超時(shí)案例。

從圣誕節(jié)平安夜開始,每天晚上固定十點(diǎn)到十一點(diǎn)這個(gè)時(shí)間段,該公司的系統(tǒng)會(huì)癱瘓一個(gè)小時(shí)左右的時(shí)間,過了這個(gè)時(shí)間段,系統(tǒng)就會(huì)自動(dòng)恢復(fù)正常。系統(tǒng)癱瘓時(shí),網(wǎng)頁和App都打不開,數(shù)據(jù)庫服務(wù)請(qǐng)求超時(shí)。

如圖1所示,該公司的系統(tǒng)架構(gòu)是一個(gè)非常典型的小型創(chuàng)業(yè)公司的微服務(wù)架構(gòu)。

圖1 典型的小型創(chuàng)業(yè)公司系統(tǒng)架構(gòu)

該公司將整個(gè)系統(tǒng)托管在公有云上,Nginx作為前置網(wǎng)關(guān)承接前端的所有請(qǐng)求。后端根據(jù)業(yè)務(wù),劃分了若干個(gè)微服務(wù)分別進(jìn)行部署。數(shù)據(jù)保存在MySQL數(shù)據(jù)庫中,部分?jǐn)?shù)據(jù)用Memcached做了前置緩存。數(shù)據(jù)并沒有按照微服務(wù)最佳實(shí)踐的要求,進(jìn)行嚴(yán)格的劃分和隔離,而是為了方便,存放在了一起。

這種存儲(chǔ)設(shè)計(jì)方式,對(duì)于一個(gè)業(yè)務(wù)變化極快的創(chuàng)業(yè)公司來說是比較合理的。因?yàn)樗拿總€(gè)微服務(wù),隨時(shí)都在隨著業(yè)務(wù)需求的變化而發(fā)生改變,如果做了嚴(yán)格的數(shù)據(jù)隔離,反而不利于應(yīng)對(duì)需求的變化。

開始分析這個(gè)案例時(shí),我首先注意到的一個(gè)關(guān)鍵現(xiàn)象是,每天晚上十點(diǎn)到十一點(diǎn)這個(gè)時(shí)間段,是絕大多數(shù)內(nèi)容類App訪問量的高峰期。因?yàn)檫@個(gè)時(shí)間段很多人都會(huì)躺在床上玩手機(jī),因此我初步判斷,這個(gè)故障可能與訪問量有關(guān)。圖2所示的是該系統(tǒng)每天各個(gè)時(shí)間段的訪問量趨勢(shì)圖,正好可以印證我的初步判斷。

圖2 系統(tǒng)訪問量

基于這個(gè)判斷,排查問題的重點(diǎn)應(yīng)該放在那些服務(wù)于用戶訪問的功能上,比如,首頁、商品列表頁、內(nèi)容推薦等功能。

在訪問量達(dá)到峰值的時(shí)候,請(qǐng)求全部超時(shí)。而隨著訪問量的減少,系統(tǒng)又能自動(dòng)恢復(fù),因此基本上可以排除后臺(tái)服務(wù)被大量請(qǐng)求沖垮,進(jìn)程僵死或退出的可能性。因?yàn)槿绻M(jìn)程出現(xiàn)這種情況,一般是不會(huì)自動(dòng)恢復(fù)的。排查問題的重點(diǎn)應(yīng)該放在MySQL上。

觀察圖3所示的MySQL服務(wù)器各時(shí)段的CPU利用率監(jiān)控圖,我們可以發(fā)現(xiàn)其中的問題。從監(jiān)控圖上可以看出,故障時(shí)段MySQL的CPU利用率一直是100%。這種情況下,MySQL基本上處于不可用的狀態(tài),執(zhí)行所有的SQL都會(huì)超時(shí)。在MySQL中,這種CPU利用率高的現(xiàn)象,絕大多數(shù)情況下都是由慢SQL導(dǎo)致的,所以需要優(yōu)先排查慢SQL。MySQL和各大云廠商提供的RDS(關(guān)系型數(shù)據(jù)庫服務(wù))都能提供慢SQL日志,分析慢SQL日志,是查找造成類似問題的原因最有效的方法。

圖3 MySQL服務(wù)器各時(shí)段的CPU利用率監(jiān)控圖

一般來說,慢SQL日志中,會(huì)包含這樣一些信息:SQL語句、執(zhí)行次數(shù)、執(zhí)行時(shí)長(zhǎng)。通過分析慢SQL查找問題,并沒有什么標(biāo)準(zhǔn)的方法,主要還是依靠經(jīng)驗(yàn)。

首先,我們需要知道的一點(diǎn)是,當(dāng)數(shù)據(jù)庫非常忙的時(shí)候,任何一個(gè)SQL的執(zhí)行都會(huì)很慢。所以并不是說,慢SQL日志中記錄的這些慢SQL都是有問題的SQL。大部分情況下,導(dǎo)致問題的SQL只是其中的一條或幾條,不能簡(jiǎn)單地依據(jù)執(zhí)行次數(shù)和執(zhí)行時(shí)長(zhǎng)進(jìn)行判斷。但是,單次執(zhí)行時(shí)間特別長(zhǎng)的SQL,仍然是應(yīng)該重點(diǎn)排查的對(duì)象。

通過分析這個(gè)系統(tǒng)的慢SQL日志,我首先找到了一條特別慢的SQL。以下代碼是這條SQL的完整語句:

  1.  1select fo.FollowId as vid, count(fo.id) as vcounts 
  2.  2 
  3.  3from follow fo, user_info ui 
  4.  4 
  5.  5where fo.userid = ui.userid 
  6.  6 
  7.  7and fo.CreateTime between 
  8.  8 
  9.  9str_to_date(?, '%Y-%m-%d %H:%i:%s'
  10. 10 
  11. 11and str_to_date(?, '%Y-%m-%d %H:%i:%s'
  12. 12 
  13. 13and fo.IsDel = 0 
  14. 14 
  15. 15and ui.UserState = 0 
  16. 16 
  17. 17group by vid 
  18. 18 
  19. 19order by vcounts desc 
  20. 20 
  21. 21limit 0,10 

這條SQL支撐的功能是一個(gè)“網(wǎng)紅”排行榜,用于排列出“粉絲”數(shù)最多的前10名“網(wǎng)紅”。

請(qǐng)注意,這種排行榜的查詢,一定要做緩存。在上述案例中,排行榜是新上線的功能,由于沒有做緩存,導(dǎo)致訪問量高峰時(shí)間段服務(wù)卡死,因此增加緩存應(yīng)該可以有效解決上述問題。

為排行榜增加緩存后,新版本立即上線。本以為問題就此可以得到解決,結(jié)果到了晚高峰時(shí)間段,系統(tǒng)仍然出現(xiàn)了各種請(qǐng)求超時(shí),頁面打不開的問題。

再次分析慢SQL日志,我發(fā)現(xiàn)排行榜的慢SQL不見了,說明緩存生效了。日志中的其他慢SQL,查詢次數(shù)和查詢時(shí)長(zhǎng)的分布都很均勻,找不到明顯有問題的SQL。

于是,我再次查看MySQL服務(wù)器各時(shí)段的CPU利用率監(jiān)控圖,如圖4所示。

圖4 系統(tǒng)增加緩存后,MySQL服務(wù)器各時(shí)段的CPU利用率

把圖放大后,我又從中發(fā)現(xiàn)了如下兩點(diǎn)規(guī)律。

1)CPU利用率,以20分鐘為周期,非常有規(guī)律地進(jìn)行波動(dòng)。

2)總體的趨勢(shì)與訪問量正相關(guān)。

那么,我們是不是可以猜測(cè)一下,如圖5所示,MySQL服務(wù)器的CPU利用率監(jiān)控圖的波形主要由兩個(gè)部分構(gòu)成:參考線以下的部分,是正常處理日常訪問請(qǐng)求的部分,它與訪問量是正相關(guān)的;參考線以上的部分,來自某個(gè)以20分鐘為周期的定時(shí)任務(wù),與訪問量關(guān)系不大。

圖5 系統(tǒng)增加緩存后,MySQL服務(wù)器各時(shí)段的CPU利用率(附帶參考線)

排查整個(gè)系統(tǒng),并未發(fā)現(xiàn)有以20分鐘為周期的定時(shí)任務(wù),繼續(xù)擴(kuò)大排查范圍,排查周期小于20分鐘的定時(shí)任務(wù),最后終于定位到了問題所在。

該公司App的首頁聚合了大量的內(nèi)容,比如,精選商品、標(biāo)題圖、排行榜、編輯推薦,等等。這些內(nèi)容會(huì)涉及大量的數(shù)據(jù)庫查詢操作。該系統(tǒng)在設(shè)計(jì)之初,為首頁做了一個(gè)整體的緩存,緩存的過期時(shí)間是10分鐘。但是隨著需求的不斷變化,首頁上需要查詢的內(nèi)容越來越多,導(dǎo)致查詢首頁的全部?jī)?nèi)容變得越來越慢。

通過檢查日志可以發(fā)現(xiàn),刷新一次緩存的時(shí)間竟然長(zhǎng)達(dá)15分鐘。緩存是每隔10分鐘整點(diǎn)刷新一次,因?yàn)?0分鐘內(nèi)刷不完,所以下次刷新就推遲到了20分鐘之后,這就導(dǎo)致了圖5中,參考線以上每20分鐘一個(gè)周期的規(guī)律波形。由于緩存的刷新比較慢,導(dǎo)致很多請(qǐng)求無法命中緩存,因此大量請(qǐng)求只能穿透緩存直接查詢數(shù)據(jù)庫。圖9-5中參考線以下的部分,包含了很多這類請(qǐng)求占用的CPU利用率。

找到了問題的原因所在,下面就來進(jìn)行針對(duì)性的優(yōu)化,問題很快就得到了解決。新版本上線之后,再也沒有出現(xiàn)過“午夜宕機(jī)”的問題。如

圖6所示,對(duì)比優(yōu)化前后MySQL服務(wù)器的CPU利用率,可以看出,優(yōu)化的效果非常明顯。

圖6 優(yōu)化前后MySQL服務(wù)器的CPU利用率對(duì)比

02如何避免悲劇重演

至此,導(dǎo)致問題的原因找到了,問題也得到了圓滿解決。單從這個(gè)案例來看,問題的原因在于,開發(fā)人員在編寫SQL時(shí),沒有考慮數(shù)據(jù)量和執(zhí)行時(shí)間,緩存的使用也不合理。最終導(dǎo)致在訪問高峰期時(shí),MySQL服務(wù)器被大量的查詢請(qǐng)求卡死,而無法提供服務(wù)。

作為系統(tǒng)的開發(fā)人員,對(duì)于上述問題,我們可以總結(jié)出如下兩點(diǎn)經(jīng)驗(yàn)。

第一,在編寫SQL的時(shí)候,一定要小心謹(jǐn)慎、仔細(xì)評(píng)估,首先思考如下三個(gè)問題。

  • SQL所涉及的表,其數(shù)據(jù)規(guī)模是多少?
  • SQL可能會(huì)遍歷的數(shù)據(jù)量是多少?
  • 如何盡量避免寫出慢SQL?

第二,能不能利用緩存減少數(shù)據(jù)庫查詢的次數(shù)?在使用緩存的時(shí)候,我們需要特別注意緩存命中率,應(yīng)盡量避免請(qǐng)求因?yàn)槊胁涣司彺妫苯哟┩傅綌?shù)據(jù)庫上。

不過,我們無法保證,整個(gè)團(tuán)隊(duì)的所有開發(fā)人員以后都不會(huì)再犯這類錯(cuò)誤。但是,這并不意味著,上述問題就無法避免了,否則大企業(yè)的服務(wù)系統(tǒng)會(huì)因?yàn)槊刻焐暇€大量的BUG而無法正常工作。實(shí)際情況是,大企業(yè)的系統(tǒng)通常都是比較穩(wěn)定的,基本上不會(huì)出現(xiàn)全站無法訪問的問題,這要?dú)w功于其優(yōu)秀的系統(tǒng)架構(gòu)。優(yōu)秀的系統(tǒng)架構(gòu),可以在一定程度上,減輕故障對(duì)系統(tǒng)的影響。

針對(duì)這次事故,我在系統(tǒng)架構(gòu)層面,為該公司提了兩條改進(jìn)的建議。

第一條建議是,上線一個(gè)定時(shí)監(jiān)控和殺掉慢SQL的腳本。這個(gè)腳本每分鐘執(zhí)行一次,檢測(cè)在上一分鐘內(nèi),有沒有執(zhí)行時(shí)間超過一分鐘(這個(gè)閾值可以根據(jù)實(shí)際情況進(jìn)行調(diào)整)的慢SQL,如果發(fā)現(xiàn),就直接殺掉這個(gè)會(huì)話。

這樣可以有效地避免因?yàn)橐粋€(gè)慢SQL而拖垮整個(gè)數(shù)據(jù)庫的悲劇。即使出現(xiàn)慢SQL,數(shù)據(jù)庫也可以在至多1分鐘內(nèi)自動(dòng)恢復(fù),從而避免出現(xiàn)數(shù)據(jù)庫長(zhǎng)時(shí)間不可用的問題。不過,這樣做也是有代價(jià)的,可能會(huì)導(dǎo)致某些功能,之前運(yùn)行是正常的,在這個(gè)腳本上線后卻出現(xiàn)了問題。但是,總體來說,這個(gè)代價(jià)還是值得付出的,同時(shí)也可以反過來督促開發(fā)人員,使其更加小心謹(jǐn)慎,避免寫出慢SQL。

第二條建議是,將首面做成一個(gè)簡(jiǎn)單的靜態(tài)頁面,作為降級(jí)方案,首頁上只要包含商品搜索欄、大的品類和其他頂級(jí)功能模塊入口的鏈接就可以了。在Nginx上實(shí)現(xiàn)一個(gè)策略,如果請(qǐng)求首頁數(shù)據(jù)超時(shí),則直接返回這個(gè)靜態(tài)頁面的首頁作為替代。后續(xù)即使首頁再出現(xiàn)任何故障,也可以暫時(shí)降級(jí),用靜態(tài)首頁替代,至少不會(huì)影響到用戶使用其他功能。

這兩條改進(jìn)建議的實(shí)施都是非常容易的,不需要對(duì)系統(tǒng)進(jìn)行很大的改造,而且效果也是立竿見影的。

當(dāng)然,這個(gè)系統(tǒng)的存儲(chǔ)架構(gòu)還有很多可以改進(jìn)的地方,比如,對(duì)數(shù)據(jù)做適當(dāng)?shù)母綦x,改進(jìn)緩存置換策略,將數(shù)據(jù)庫升級(jí)為主從部署,把非業(yè)務(wù)請(qǐng)求的數(shù)據(jù)庫查詢遷移到單獨(dú)的從庫上,等等,只是這些改進(jìn)都需要對(duì)系統(tǒng)做出比較大的改動(dòng)升級(jí),需要從長(zhǎng)計(jì)議之后再在系統(tǒng)后續(xù)的迭代過程中逐步實(shí)施。

03小結(jié)

本文分析了一個(gè)由于慢SQL導(dǎo)致網(wǎng)站服務(wù)器訪問故障的案例。在“破案”的過程中,我分享了一些很有用的經(jīng)驗(yàn),這些經(jīng)驗(yàn)對(duì)于大家在工作中遇到類似問題時(shí)會(huì)有很大的參考作用。下面再來梳理一下這些經(jīng)驗(yàn)。

1)根據(jù)故障時(shí)段出現(xiàn)在系統(tǒng)繁忙時(shí)這一現(xiàn)象,推斷出故障原因與支持用戶訪問的功能有關(guān)。

2)根據(jù)系統(tǒng)能在流量峰值過后自動(dòng)恢復(fù)這一現(xiàn)象,排除后臺(tái)服務(wù)被大量請(qǐng)求沖垮的可能性。

3)根據(jù)服務(wù)器的CPU利用率曲線的規(guī)律變化,推斷出故障原因可能與定時(shí)任務(wù)有關(guān)。

在故障復(fù)盤階段,我們針對(duì)故障問題本身的原因,做了針對(duì)性的預(yù)防和改進(jìn),除此之外,更重要的是,在系統(tǒng)架構(gòu)層面也進(jìn)行了改進(jìn),整個(gè)系統(tǒng)變得更加健壯,不至于因?yàn)槟硞€(gè)小的失誤,就導(dǎo)致出現(xiàn)全站無法訪問的問題。

我為該系統(tǒng)提出的第一個(gè)建議是定時(shí)自動(dòng)殺死慢SQL,原因是:系統(tǒng)的關(guān)鍵部分要有自我保護(hù)機(jī)制,以避免因?yàn)橥獠康腻e(cuò)誤而影響到系統(tǒng)的關(guān)鍵部分。第二個(gè)建議是首頁降級(jí),原因是:當(dāng)關(guān)鍵系統(tǒng)出現(xiàn)故障的時(shí)候,要有臨時(shí)的降級(jí)方案,以盡量減少故障造成的不良影響。

這些架構(gòu)上的改進(jìn)措施,雖然不能完全避免故障,但是可以在很大程度上減小故障的影響范圍,減輕故障帶來的損失,希望大家能夠仔細(xì)體會(huì),活學(xué)活用。

關(guān)于作者:李玥,美團(tuán)基礎(chǔ)技術(shù)部高級(jí)技術(shù)專家,極客時(shí)間《后端存儲(chǔ)實(shí)戰(zhàn)課》《消息隊(duì)列高手課》等專欄作者。曾在當(dāng)當(dāng)網(wǎng)、京東零售等公司任職。從事互聯(lián)網(wǎng)電商行業(yè)基礎(chǔ)架構(gòu)領(lǐng)域的架構(gòu)設(shè)計(jì)和研發(fā)工作多年,曾多次參與雙十一和618電商大促。專注于分布式存儲(chǔ)、云原生架構(gòu)下的服務(wù)治理、分布式消息和實(shí)時(shí)計(jì)算等技術(shù)領(lǐng)域,致力于推進(jìn)基礎(chǔ)架構(gòu)技術(shù)的創(chuàng)新與開源。

本文摘編自《電商存儲(chǔ)系統(tǒng)實(shí)戰(zhàn):架構(gòu)設(shè)計(jì)與海量數(shù)據(jù)處理》,經(jīng)出版方授權(quán)發(fā)布。(ISBN:9787111697411)轉(zhuǎn)載請(qǐng)保留文章出處。

 

責(zé)任編輯:武曉燕 來源: 數(shù)倉寶貝庫
相關(guān)推薦

2023-12-13 09:08:26

CPU性能分析Linux

2021-05-13 23:39:19

勒索軟件攻擊數(shù)據(jù)泄露

2023-02-10 18:32:21

項(xiàng)目管理實(shí)踐

2020-07-02 09:55:32

運(yùn)維架構(gòu)技術(shù)

2023-05-03 20:53:48

2021-02-26 00:46:11

CIO數(shù)據(jù)決策數(shù)字化轉(zhuǎn)型

2020-03-16 10:41:38

服務(wù)器開發(fā) Web

2021-09-07 15:41:35

Bug誘因代碼

2024-08-09 08:28:14

品牌數(shù)據(jù)庫產(chǎn)品

2024-04-03 12:30:00

C++開發(fā)

2024-04-24 13:45:00

2021-02-22 17:00:31

Service Mes微服務(wù)開發(fā)

2022-03-04 18:11:16

信服云

2021-05-08 12:30:03

Pythonexe代碼

2023-05-24 10:06:42

多云實(shí)踐避坑

2021-05-07 21:53:44

Python 程序pyinstaller

2019-12-24 15:14:24

技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)