問: 爲何300的併發能把支持最大鏈接數4000數據庫壓死?前端
買了一臺數據庫,最大鏈接數的參數是 4000,看起來很棒!可是 cpu 和內存並不咋好!是 2c4g的超低配製。mysql
可是想着反正業務量也不大,不如先扛着,等業務量上來再進行升配!sql
沒過多久,進行一次小量的營銷活動。粗略計算想了下,大約3-4臺應用服務器就沒問題了;而後再考慮下數據庫,應該沒有問題。數據庫
考慮到數據庫沒問題的緣由有二:後端
1. 應用服務器數量少,對數據庫壓力不會太大;api
2. 每一個應用都設置了最大鏈接池限制,單臺通常不會超過100的鏈接,與4000的併發鏈接指標還差很遠;緩存
活動開始後,開始一切都很正常,應用服務器監控正常,前端響應正常。覺得一切盡在掌握之中,結果倒是一場災難!服務器
前端頁面響應愈來愈慢了,監控應用服務器卻一點壓力沒上來!我知道是數據庫出問題了!網絡
因而,直接開了個db客戶端查看狀況,本身試着運行了直sql,響應的確很慢,可是也能幾十秒內返回;因此我數粗淺的結論是,應用響應會很慢,可是應該能響應完整!多線程
其實,我想錯了。
其一,前端訪問是有超時限制的,超過一段時間後,會自行斷開鏈接,因此後端超級卡頓時,前端用戶側是會沒法提供服務的!
其二,除去前端會有超時限制斷開外,應用api也會在一段時間沒有收到數據庫響應後,超時斷開返回,然而數據庫對斷開請求則可能收不到,從而繼續保持操做運行;從而應用服務器會再次發起下一個請求,從而使鏈接超過應用設置的鏈接池大小,進一步挑戰db極限;因此,前端仍然是不能正常服務的。
回到前面數據庫問題,爲何在還遠低於最大鏈接數的狀況下,db就開始不工做了呢?
其實,db的運行指標,不止有最大鏈接數一個!cpu,內存,磁盤,網絡 都是其運行指標,這些指標都會限制其能力!
第一層,磁盤io。
指標專業名詞:IOPS;由於全部的數據都是存儲在磁盤的,因此,在高併發的場景下,必定會受到磁盤能力的限制,普通磁盤 sata 可能只有7-10M/s 的能力,只要要求加載的數據遠遠大於這個速度,磁盤瓶頸就出來了。固然了,磁盤讀取後,結果是會緩存到內存的,因此又和內存有關了!
第二層,內存。
磁盤讀取出來的數據一定會放到內存進行數據運算處理,而後才能獲得結果。內存的速度固然是特別快了,我們不考慮它這方面的能力問題。可是,速度再快,沒有內存空間就沒辦法了,就像上面的配置 4g 的內存其實稍微幾個大點的數據查詢,基本就裝滿了。並且,在一次查詢完成後,還要負責將結果緩存起來。當內存運行不夠的時候,cpu會進行磁盤的swap操做,將須要運算的數據換入內存,從而保證運算正常進行,可是這個操做就很慢了,從而致使正常的查詢都變得緩慢起來。(索引會稍微好點,因其數據量比較小,內存swap機率也低)。 因此,低配內存將是一大體命弱點,不要指望過高;
第三層,cpu。
其實整個過程的調度都是由cpu來指揮若定的。只是,cpu運算速度每每都會很快,因此咱們把它稍微放後點!由於前面磁盤和內存,致使cpu會不停地運算操做。另外,因爲外部請求大量涌入,致使cpu要進行多線程的維護,即會有大量上下文切換,這個切換增長了cpu壓力,同時也使請求的響應變差,cpu也就愈來愈高,直到彪升到90+%,連操做系統的調度都很困難了。因此,只會雪上加霜地,下降請求的處理能力,從而致使db直接假死!可能只有重啓才能解決問題了!
第四層,網絡層。
通常來講,只要數據庫和應用是部署在一個內網裏,那麼,網絡通常不會限制能力(非絕對);可是對於一些遠程數據庫,就直接要當心了,好比一個數據包就是3M+,那麼若是是 10Mb/s 的帶寬,僅能傳輸3-4個數據包,從而使響應能力徹底限死;因此,數據庫通常須要部署內網機房,或者買雲數據庫時,最好在同一區。網絡層通常咱們能夠忽略,可是要知道這裏的原理!
最後,咱們來討論下,mysql中的最大鏈接數究竟是什麼?
1. 查看最大鏈接數
show variables like '%max_connections%'
2. 修改最大鏈接數
set GLOBAL max_connections = 200;
那麼,最大鏈接是什麼原理呢?
通常對於處理快速的狀況下,每一個鏈接進來後,會從mysql的線程池中取出線程來處理任務。可是當線程不夠用的時候,它會建立新的線程池來處理。
因此,併發鏈接數越大,則每每意味着mysql的線程會越多(不必定是一對一);線程越多意味着上下文切換將越頻繁,cpu壓力越大,服務器性能越差。因此,合理設置最大鏈接數,使服務器處於高效狀態,是一個優化方向!
查看線程相關的狀態變量:
SHOW STATUS LIKE 'Threads%';
那麼問題來了,爲何阿里雲上的rds設置了這麼高的最大鏈接數呢?我估計,他是爲了兼容最快速和最小數據量的併發鏈接狀況,而設置的。本身能夠壓測下!
綜上,四個指標。只要有一個成爲瓶頸,其餘指標也就失去了意義!
其實真正有過mysql調優經驗的同窗,深刻理解過mysql,上面這些問題天然明白。而不明白的同窗,則要多多實踐才行!
一句話總結:紙上得來終覺淺,絕知此事要躬行!