<ruby id="h6500"><table id="h6500"></table></ruby>
    1. <ruby id="h6500"><video id="h6500"></video></ruby>
          1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>

            記一次性能調優(yōu)

            發(fā)表于:2020-09-21來(lái)源:火丁筆記作者:火丁筆記點(diǎn)擊數: 標簽:性能調優(yōu)
            面對性能調優(yōu)問(wèn)題,很多人往往只是單純的套用既往的經(jīng)驗:先試試一個(gè),不行再試試另一個(gè)。面對簡(jiǎn)單的問(wèn)題,如此通常能事半功倍;但是當面對復雜問(wèn)題的時(shí)候,單憑經(jīng)驗往往并不

            面對性能調優(yōu)問(wèn)題,很多人往往只是單純的套用既往的經(jīng)驗:先試試一個(gè),不行再試試另一個(gè)。面對簡(jiǎn)單的問(wèn)題,如此通常能事半功倍;但是當面對復雜問(wèn)題的時(shí)候,單憑經(jīng)驗往往并不能達到立竿見(jiàn)影的效果,此時(shí)我們需要更精準的判斷性能短板在哪里。

            一個(gè) openresty 項目,不了解 openresty 的可以參考我以前的文章,從 top 運行結果看,軟中斷 si 分配不均,絕大部分壓在了 CPU5 上,導致 CPU5 的空閑 id 接近于零,最終的結果是其它 CPU 雖然還有空閑 id,但是卻礙于 CPU5 的限制而使不上勁兒:

            top 顯示 si 不均衡

            既然知道了軟中斷是系統的性能短板,那么讓我們看看軟中斷都消耗在哪:

            shell> watch -d -n 1 'cat /proc/softirqs'

            watch 顯示軟中斷集中在 NET_RX

            通過(guò) watch 命令,我們可以確認 CPU5 的軟中斷接種在 NET_RX 上,也就是網(wǎng)卡上,除了 CPU5,其它 CPU 的 NET_RX 普遍低了一個(gè)數量級,由此可以判斷,此網(wǎng)卡工作在單隊列模式上,我們不妨通過(guò) ethtool 命令來(lái)確認一下:

            shell> ethtool -l eth0
            
            Channel parameters for eth0:
            Pre-set maximums:
            RX: 0
            TX: 0
            Other: 0
            Combined: 8
            Current hardware settings:
            RX: 0
            TX: 0
            Other: 0
            Combined: 1

            主要留意結果中的 Combined 即可,其中 Channel parameters 里的 Combined 表示硬件支持的最大隊列數,而 Current hardware settings 里的 Combined 表示當前值。如果硬件只支持單隊列,那么可以通過(guò) RPS 之類(lèi)的方式來(lái)模擬多隊列;如果硬件支持多隊列,那么激活它就行了。結果顯示:本例中的網(wǎng)卡支持 8 個(gè)隊列,當前開(kāi)啟了 1 個(gè)隊列,激活網(wǎng)卡的多隊列功能后再觀(guān)察 top 運行結果會(huì )發(fā)現 si 均衡了,其它 CPU 也能使上勁兒了:

            shell> ethtool -L eth0 combined 8

            top 顯示 si 均衡了

            至此我們搞定了網(wǎng)卡多隊列功能,其實(shí)說(shuō)白了這是一個(gè)資源分配不均衡的問(wèn)題,那么除了網(wǎng)卡多隊列以外,還有其它資源分配不均衡的問(wèn)題么,讓我們繼續看 top 運行結果:

            top 顯示 nginx 的 time 不均衡

            如上所示,會(huì )發(fā)現 nginx 多進(jìn)程間的 time 分配并不均衡(此 time 是 cpu time),有的干活多,有的干活少,相關(guān)問(wèn)題在「 Why does one NGINX worker take all the load? 」一文中有相關(guān)描述:在原本的nginx 模型中,一個(gè) socket 接收所有的請求,不同的 worker 按照accet_mutext 的設置來(lái)爭搶請求,不過(guò)因為 Linux 的 epoll-and-accept 負載均衡算法采取了類(lèi)似 LIFO 的行為,結果導致請求在不同進(jìn)程間的分配變得十分不均衡:

            使用 reuseport 前

            為了解決此類(lèi)問(wèn)題,nginx 實(shí)現了 reuseport 指令,每個(gè)進(jìn)程都有對應自己的 socket:

            使用 reuseport 后

            激活了 reuseport 指令后,我們通過(guò) top 命令觀(guān)察會(huì )發(fā)現 time 分配變得均衡了:

            http {
                server {
                    listen 80 reuseport;
                    ...
                }
            }

            top 顯示 nginx 的 time 均衡了

            雖然我們沒(méi)有改動(dòng)一行代碼,但是僅僅通過(guò)激活網(wǎng)卡多隊列和 nginx reuseport,就提升了性能,但是如果想更進(jìn)一步提升性能,必須深入代碼層面才行,下面讓我們看看如何發(fā)現代碼層面的短板在哪里,是時(shí)候請出火焰圖了,關(guān)于火焰圖的概念可以參考我以前的文章,如下是一個(gè) on-CPU ( sample-bt )的火焰圖,同時(shí)采樣用戶(hù)態(tài)和內核態(tài)數據:

            火焰圖顯示 cjson 吃掉了大量 cpu

            如圖所示,cjson 吃掉了大量 cpu,同時(shí)發(fā)現寬大的火苗基本都是用戶(hù)態(tài)行為,于是我們去掉采樣內核態(tài)數據,從而降低噪音,重新繪制用戶(hù)態(tài) on-CPU 火焰圖:

            火焰圖顯示 cjson 吃掉了大量 cpu

            說(shuō)明:不了解火焰圖用法的話(huà),可以參考 iresty 示例,另外,本例中因為服務(wù)器缺少 luajit debug symbol,采樣的是 C 語(yǔ)言數據,而不是 Lua 語(yǔ)言數據,結果可能有失精準。

            如圖所示,確實(shí) cjson 吃掉了大量 CPU。對照代碼,發(fā)現存在若干次解碼 json 數據的操作,于是我們可以判斷 CPU 是被 cjson.decode 吃掉的,這也正常,不管是什么語(yǔ)言,高效解碼 json 數據都是一個(gè)讓人頭疼的問(wèn)題,群里問(wèn)問(wèn)別人有什么銀彈可用,結果有人推薦了 lua-resty-json ,從官網(wǎng)說(shuō)明看,相對于 cjson,它把解碼 json 數據的性能提升了 10%~50%,實(shí)際具體大小取決于數據的復雜程度,使用上也很簡(jiǎn)單:

            shell> cd /path/to/lua-resty-json/
            shell> make
            shell> cp json_decoder.lua /usr/local/openresty/lualib/
            shell> cp libljson.so /usr/local/openresty/lualib/

            剩下的具體用法參考 測試用例 就可以了,需要說(shuō)明的是 lua-resty-json 只實(shí)現了解碼。

            不過(guò)我并沒(méi)有采用把 cjson 替換為 lua-resty-json 的方法來(lái)提升性能,這是因為通過(guò)數據分析,我發(fā)現在本例中,存在明顯的熱數據,如果把這些熱數據直接緩存在進(jìn)程中,那么對熱數據而言,就完全不需要解碼 json 數據了,可以利用 lua-resty-mlcache 來(lái)實(shí)現:

            mlcache 的多級緩存結構

            至此,本次性能調優(yōu)告一段落,實(shí)際上這并不是一次嚴謹的性能調優(yōu),我只是利用一些項目的間歇期偶爾搞一下,不過(guò)最終我們把服務(wù)器數量降低了一半以上。

            原文轉自:https://blog.huoding.com/2020/09/12/850

            ...
            老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
              <ruby id="h6500"><table id="h6500"></table></ruby>
              1. <ruby id="h6500"><video id="h6500"></video></ruby>
                    1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>