Haproxy作爲MySQL中間層如何避免TCP端口耗盡

Haproxy作爲MySQL中間層是很成熟的方案,特別是解決從庫的負載均衡和故障切換,在生產環境中有着廣泛的應用。

在實際使用過程中,有兩個問題比較容易發生:
1. TCP端口耗盡
2. 網卡帶寬跑滿
本文重點講講如何優化問題1,問題2暫不討論。

優化一: 使用儘可能多的端口
Linux系統默認提供了65K個端口,每當Haproxy建立了一個到MySQL的連接,就會消耗一個端口;當Haproxy斷開和MySQL的連接時,該端口並不會立即釋放,而是會處於TIME_WAIT狀態(2*MSL),超時後纔會釋放此端口供新的連接使用。

我的環境中,tcp_fin_timeout爲15秒,也就是說如果我環境中的haproxy可以承載的最大併發連接數爲64K/(15*2)=2.1K,可實際上達不到這個上限,原因如下:

$ sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 15000    65000


linux會保留一段端口,實際能參與分配的端口數只有50K,爲了獲得儘可能多的可分配端口,做如下調整:

# sysctl net.ipv4.ip_local_port_range="1025 65000"

   


記得修改/etc/sysctl.conf中對應的內容

優化二: 複用處於TIME_WAIT的端口
調整兩個參數:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1


第一個參數很安全,可以不用過多關注。需要注意的是第二個參數,某些情況下會導致數據包被丟棄。

例如:client通過NAT連接haproxy,並且haproxy端打開了tcp_tw_recycle,同時saw_tstamp也沒有關閉,當第一個連接建立並關閉後,此端口(句柄)處於TIME_WAIT狀態,在2*MSL時間內又一個client(相同IP,如果打開了xfrm還要相同PORT)發一個syn包,此時linux內核就會認爲這個數據包異常,從而丟掉這個包,併發送rst包.

不過通常情況下,client都是通過內網直接連接haproxy,所以可以認爲tcp_tw_recycle是安全的,只是需要記住此坑。

優化三: 縮短TIME_WAIT時間
Linux系統默認MSL爲60秒,也就是正常情況下,120秒後處於TIME_WAIT的端口(句柄)纔會釋放,可以將MSL的時間縮小,縮短端口的釋放週期。

# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
# echo 15 > /proc/sys/net/ipv4/tcp_fin_timeout

   

這是一個折中的數值,太小也會導致其它問題

優化四: 使用多IP
如優化一中所說,我們已經儘可能多的使用了系統提供的端口範圍。但最多依然不超過65K。
Haproxy提供了內建的端口管理方法,可以充分利用以擴大我們的端口範圍。

server mysql0     10.0.3.1:3306 check source 10.0.3.100:1025-65000
server mysql1     10.0.3.1:3306 check source 10.0.3.101:1025-65000


如果使用兩個ip,我們可用的端口數就接近130K。擴展多個IP,就可以不斷增加端口數。

優化五: 使用長連接
服務最好使用長連接,一是避免頻繁的申請連接,導致端口耗盡;二是避免創建連接帶來的時間消耗。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章