Nginx的accept_mutex配置分析
通常多數(shù)人不會注意Nginx的accept_mutex配置,不過實際上它對系統(tǒng)的吞吐量有一定的影響,今天生物鐘紊亂睡不著覺,索性閑扯一下Nginx的accept_mutex配置。
讓我們看看accept_mutex的意義:當(dāng)一個新連接到達時,如果激活了accept_mutex,那么多個Worker將以串行方式來處理,其中有一個Worker會被喚醒,其他的Worker繼續(xù)保持休眠狀態(tài);如果沒有激活accept_mutex,那么所有的Worker都會被喚醒,不過只有一個Worker能獲取新連接,其它的Worker會重新進入休眠狀態(tài),這就是「驚群問題」。
Nginx缺省激活了accept_mutex,也就是說不會有驚群問題,但真的有那么嚴(yán)重么?實際上Nginx作者Igor Sysoev曾經(jīng)給過相關(guān)的解釋:
OS may wake all processes waiting on accept() and select(), this is called thundering herd problem. This is a problem if you have a lot of workers as in Apache (hundreds and more), but this insensible if you have just several workers as nginx usually has. Therefore turning accept_mutex off is as scheduling incoming connection by OS via select/kqueue/epoll/etc (but not accept()).
簡單點說:Apache動輒就會啟動成百上千的進程,如果發(fā)生驚群問題的話,影響相對較大;但是對Nginx而言,一般來說,worker_processes會設(shè)置成CPU個數(shù),所以最多也就幾十個,即便發(fā)生驚群問題的話,影響相對也較小。
…
假設(shè)你養(yǎng)了一百只小雞,現(xiàn)在你有一粒糧食,那么有兩種喂食方法:
- 你把這粒糧食直接扔到小雞中間,一百只小雞一起上來搶,最終只有一只小雞能得手,其它九十九只小雞只能鎩羽而歸。這就相當(dāng)于關(guān)閉了accept_mutex。
- 你主動抓一只小雞過來,把這粒糧食塞到它嘴里,其它九十九只小雞對此渾然不知,該睡覺睡覺。這就相當(dāng)于激活了accept_mutex。
可以看到此場景下,激活accept_mutex相對更好一些,讓我們修改一下問題的場景,我不再只有一粒糧食,而是一盆糧食,怎么辦?
此時如果仍然采用主動抓小雞過來塞糧食的做法就太低效了,一盆糧食不知何年何月才能喂完,大家可以設(shè)想一下幾十只小雞排隊等著喂食時那種翹首以盼的情景。此時更好的方法是把這盆糧食直接撒到小雞中間,讓它們自己去搶,雖然這可能會造成一定程度的混亂,但是整體的效率無疑大大增強了。
…
Nginx缺省激活了accept_mutex,是一種保守的選擇。如果關(guān)閉了它,可能會引起一定程度的驚群問題,表現(xiàn)為上下文切換增多(sar -w)或者負(fù)載上升,但是如果你的網(wǎng)站訪問量比較大,為了系統(tǒng)的吞吐量,我還是建議大家關(guān)閉它。