We have a couple of production systems that were recently converted into virtual machines. There is an application of ours that frequently accesses a MySQL database, and for each query it creates a connection, queries, and disconnects that connection.
It is not the appropriate way to query (I know), but we have constraints that we can't seem to get around. Anyway, the issue is this: while the machine was a physical host, the program ran fine. Once converted to a virtual machine, we noticed intermittent connection issues to the database. There were, at one point, 24000+ socket connections in TIME_WAIT (on the physical host, the most I saw was 17000 - not good, but not causing problems).
I would like these connections to be reused, so that we don't see that connection problem, and so:
Questions:
Is it ok to set the value of tcp_tw_reuse to 1? What are the obvious dangers? Is there any reason I should never do it?
Also, is there any other way to get the system (RHEL/CentOS) to prevent so many connections from going into TIME_WAIT, or getting them to be reused?
Lastly, what would changing tcp_tw_recycle do, and would that help me?
In advance, thanks!
You can safely reduce the time down, but you may run into issues with inproperly closed connections on networks with packet loss or jitter. I wouldn't start tuning at 1 second, start at 15-30 and work your way down.
Also, you really need to fix your application.
RFC 1185 has a good explanation in section 3.2:
I think it is fine to change this value to 1. A more appropriate way might be to use the command:
There are no obvious dangers that I know of, but a quick Google search produces this link which affirms that
tcp_tw_reuse
is the better alternative thantcp_tw_recycle
, but should be used with caution regardless.This doesn't answer your question (and it's 18 months late), but suggests another way of making your legacy app reuse ports:
A useful alternative to setting
tcp_tw_reuse
(ortcp_tw_recycle
) on the system is to insert a shared library (usingLD_PRELOAD
) into your app; that library can then allow reuse of the port. This makes your legacy app allow port reuse without forcing this on all apps on your system (no modification of your app is required), thus limiting the impact of your tweak. For example,This shared library should intercept the
socket()
call, call the real socket(), and set SO_REUSEADDR and/or SO_REUSEPORT on the returned socket. Look at http://libkeepalive.sourceforge.net for an example of how to do this (this turns on keepalives, but turning on SO_REUSEPORT is very similar). If your ill-behaved legacy app uses IPv6, remember to change line 55 oflibkeepalive.c
fromto
If you're stuck, send me email and I'll write the code and send it to you.
The connection can not be reused if they are in TIME WAIT. If you do not have packet loss on the network between application and MySQL, you can lower the timeout.
However the best solution is to use persistent connections towards the database and a connection pool.