Large buffers in boost::asio SSL

Hello, We're working on a server which will provide service to a large number of mostly idle, low-bandwidth clients. we've use boost::asio as the basis for this, and so far it's working very well. We recently added SSL support, which was very straightforward and seamless. We're starting to look at the scalability of our SSL server, and are seeing some bottlenecks with memory usage. We're seeing about 50KB allocated for each SSL session, even when they are idle. That limits us to somewhat less than 40K users on our box with 2GB of RAM. Our non-SSL version takes about 10KB per user, and we can handle somewhat less than 200K users. Of this 50KB, it looks like 16KB of this is for the OpenSSL BIO object, possibly a bit more with OpenSSL's internal buffers. There is another 16KB buffer stored in the "impl" field of openssl_stream_service. The server is always waiting for data from the clients with an async_read_until, and that also creates a 16KB buffer in its openssl_operation buffer. That gets us up to 48KB of storage for the buffers of each idle connection. So, a few questions. First, does this seem about right? Am I reading the code correctly? Second, it looks like it's harmless to just make these buffers smaller, maybe 1KB, including the BIO buffer. Does that seem reasonable? Can anybody think of a problem with that approach I'm overlooking? I'm certainly no OpenSSL expert, so it's fairly likely... Third, is there a better way to do this? Most of boost::asio uses memory very efficiently, and I wonder if I'm doing something wrong to cause it to allocate all of this memory? Thanks for any thoughts or help! ----Scott.

The server is always waiting for data from the clients with an async_read_until
Can't you re-engineer the system to wait for an incoming connection with boost::asio::ip::tcp::acceptor. AFAIK that way you should only need the incoming buffers when a connection is active (there being no connection the rest of the time). ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________

"Patrick Loney"
The server is always waiting for data from the clients with an async_read_until
Can't you re-engineer the system to wait for an incoming connection with boost::asio::ip::tcp::acceptor. AFAIK that way you should only need the incoming buffers when a connection is active (there being no connection the rest of the time).
Hi Patrick, I'm using a boost::asio::ip::tcp::acceptor now to accept the connections. The problem is once the connections are accepted and I start waiting for data on them, several large buffers are allocated for each connection. I was hoping somebody might have a suggestion for working around this, or could let me know if they can think of any problems with making the various buffers smaller. Thanks! ----Scott.

I'm using a boost::asio::ip::tcp::acceptor now to accept the connections. The problem is once the connections are accepted and I start waiting for data on them, several large buffers are allocated for each connection.
You said, "We're working on a server which will provide service to a large number of mostly idle, low-bandwidth clients". My intent was that you drop the connection when data is not being passed meaning that although each connection will still have the large buffers the number of connections will fluctuate, keeping memory usage at any one time manageable, rather than keeping a connection to each client open at all times leading to the problems your having. Of course there may be some reason you need an idle connection to a client at all times but you don't say what purpose this serves. Hth, Patrick ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________

"Patrick Loney"
I'm using a boost::asio::ip::tcp::acceptor now to accept the connections. The problem is once the connections are accepted and I start waiting for data on them, several large buffers are allocated for each connection.
You said, "We're working on a server which will provide service to a large number of mostly idle, low-bandwidth clients".
My intent was that you drop the connection when data is not being passed meaning that although each connection will still have the large buffers the number of connections will fluctuate, keeping memory usage at any one time manageable, rather than keeping a connection to each client open at all times leading to the problems your having.
Ah, sorry, I didn't understand your suggestion correctly.
Of course there may be some reason you need an idle connection to a client at all times but you don't say what purpose this serves.
The server often sends notifications to the clients, and so needs a way to reach them at any time; the clients also often send messages to the server. Messages are typically sent or received about every 30 seconds. The clients are on mobile devices connected via cellphone networks, and these networks use NAT and similar techniques, which require that the client initiate connections. So the only reliable way I know of to allow the server to contact these clients immediately when a notification is available is to have the clients keep a TCP connection open to the server. Therefore, lots of mostly idle connections. Hope that explains our situation better, thanks for your response! -----Scott.
participants (2)
-
Patrick Loney
-
Scott Gifford