LinuxのLVS(IPVS)でMySQLをロードバランスするときはtimeoutに注意
問題の現象
DBサーバ上ではmysqldへのコネクションが存在するのに、appサーバ上ではコネクションが存在しない。(netstat調べ)
→無用なコネクションが残留するせいで、MySQLのmax_connectionsに達してしまう。
原因
MySQLの世界の無通信時のコネクションのタイムアウトはデフォルトで 28800秒 (8時間)。一方、IPVSの世界の無通信時のタイムアウトはESTABLISHEDなコネクションで900秒 (15分)。
# ipvsadm -Ln --timeout Timeout (tcp tcpfin udp): 900 120 300
なので、DBコネクションの永続化等でコネクションを張りっぱなし、かつ、SQLのやりとりがない(無通信状態)場合、IPVS的にタイムアウトを迎えてコネクションが切れるが、MySQL的にはまだタイムアウトになっていないのでコネクションが残ってしまう、というのが原因。
対応
いかのいずれかで。
当時自分は最後の「D. MySQLの世界のタイムアウトを短くする」を採りました。最近はAの都度接続してます。
A. コネクションのプーリング、永続化をやめて、都度接続にする
B. 定期的に通信する
C. IPVSの世界のタイムアウトを長くする
--set tcp tcpfin udp Change the timeout values used for IPVS connections. This com- mand always takes 3 parameters, representing the timeout values (in seconds) for TCP sessions, TCP sessions after receiv- ing a FIN packet, and UDP packets, respectively. A timeout value 0 means that the current timeout value of the correspond- ing entry is preserved.
で設定可能。
謝辞
某IRCチャンネルのゆかいで頼れる仲間たち。