<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MySQL的MaxIdleConns不合理,會變成短連接

          共 408字,需瀏覽 1分鐘

           ·

          2021-01-26 21:43

          1 背景

          最近石墨文檔線上業(yè)務(wù)出現(xiàn)了一些性能問題,在突發(fā)流量情況下,有個業(yè)務(wù)性能急劇下降。該服務(wù)是依賴于數(shù)據(jù)庫的業(yè)務(wù),會批量獲取數(shù)據(jù)庫里的數(shù)據(jù)。在經(jīng)過一系列的排查過程后,發(fā)現(xiàn)該服務(wù)到數(shù)據(jù)庫的連接數(shù)經(jīng)常超過MaxIdleConns,因此懷疑是數(shù)據(jù)庫的配置導(dǎo)致的性能問題,所以以下針對數(shù)據(jù)庫的代碼進行了剖析,并做了相關(guān)實驗。


          2 配置解讀

          maxIdleCount??????int????????????????????//?zero?means?defaultMaxIdleConns;?negative?means?0maxOpen           int                    // <= 0 means unlimitedmaxLifetime       time.Duration          // maximum amount of time a connection may be reusedmaxIdleTime???????time.Duration??????????//?maximum?amount?of?time?a?connection?may?be?idle?before?being?closed

          可以看到以上四個配置,是我們Go MySQL客戶端最重要的配置。

          • maxIdleCount 最大空閑連接數(shù),默認不配置,是2個最大空閑連接

          • maxOpen 最大連接數(shù),默認不配置,是不限制最大連接數(shù)

          • maxLifetime 連接最大存活時間

          • maxIdleTime 空閑連接最大存活時間


          3 源碼解析

          我們的場景是客戶端與MySQL建立的連接數(shù)經(jīng)常大于最大空閑連接數(shù),這會導(dǎo)致什么問題?我們看下下圖中的源碼。

          我們可以看到,當最大空閑連接數(shù)小于客戶端與數(shù)據(jù)庫建立的連接數(shù)的時候,那么就會返回false,并且最大連接數(shù)關(guān)閉計數(shù)器加1。

          然后上圖中,我們就可以看到,連接被關(guān)閉了(MySQL源碼里也不留點緩沖時間再關(guān)閉)。Go的MySQL客戶端這個操作,就會導(dǎo)致當突發(fā)流量情況下,由于請求量級過大,超過了最大空閑連接數(shù)的負載,那么新的連接在放入連接池的時候,會被無情的關(guān)閉,變成短連接,導(dǎo)致你的服務(wù)性能進一步惡化。


          4 實驗

          4.1 模擬線上并發(fā)數(shù)大于MaxIdConns情況

          測試代碼 , 為了檢測以上邏輯,假設(shè)了以下場景,設(shè)置最大連接數(shù)為100,最大空閑連接數(shù)為1,并發(fā)數(shù)為10的goroutine來請求數(shù)據(jù)庫。我們通過MySQL的stats的maxIdleClosed的統(tǒng)計,可以看到下圖,我們的連接不停的被關(guān)閉。


          4.2 模擬線上并發(fā)數(shù)小于MaxIdConns情況

          測試代碼 ,假設(shè)了以下場景,設(shè)置最大連接數(shù)為100,最大空閑連接數(shù)為20,并發(fā)數(shù)為10的goroutine來請求數(shù)據(jù)庫,可以看到下圖中,無MaxIdleClosed的關(guān)閉統(tǒng)計。


          4.3 抓包驗證線上并發(fā)數(shù)大于MaxIdConns情況

          測試代碼 ,為了驗證沒有理解錯代碼,抓個包最穩(wěn)妥。我們將main函數(shù)里放個select{},程序執(zhí)行完mysql的語句后,看下tcp狀態(tài)和抓包數(shù)據(jù)。

          可以發(fā)現(xiàn)確實是tcp的狀態(tài)統(tǒng)計與MySQL客戶端的統(tǒng)計是一致的,并且存在fin包。


          5 總結(jié)

          當突發(fā)流量情況下,由于請求量級過大,超過了最大空閑連接數(shù)的負載,那么新的連接在放入連接池的時候,會被關(guān)閉,將連接變成短連接,導(dǎo)致服務(wù)性能進一步惡化。為了避免這種情況,下面列舉了,可以優(yōu)化的措施。

          • 提前將maxIdleConns設(shè)大,避免出現(xiàn)短連接

          • 做好mysql讀寫分離

          • 提升mysql的吞吐量:精簡返回字段,沒必要的字段不要返回,能夠夠快復(fù)用連接

          • 吞吐量的包盡量不要太大,避免分包

          • 優(yōu)化連接池,當客戶端到MySQL的連接數(shù)大于最大空閑連接的時候,關(guān)閉能夠做一下延遲(官方不支持,估計只能自己實現(xiàn))

          • 讀請求的最好不要放MySQL里,盡量放redis里


          6 測試代碼

          • https://github.com/gotomicro/test/tree/main/gorm



          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲AV无码成人精品国产网站 | 操逼操逼操逼操逼操逼操逼视频 | 9热在线视频 | 激情 小说 图片 亚洲 伦 | 黄色成人一级视频 |