Performance deterorates with memory heavy apps.
We have been running into severe performance issues with a particular server that initializes 3 GB of memory and keeps it for the life of the server. The performance drop happens when running ab test just on ping.
- First 10k requests (ping 6 ms) on same machine
- Second 10k requests (ping 11 ms) on same machine
- Third 10k requests (ping 20ms) on same machine
It then starts deteriorating. Sometimes hanging for 500ms for just pings.
I wrote a skeleton server to try and invistigate the issue. The app does not but ping back on request. I reserver large memory (2GB) and the issue is visible. if I do not reserver any memory, it works just fine with consistent ping time of 1ms.
void startServer() {
version(linux) {
import etc.linux.memoryerror;
static if (is(typeof(registerMemoryErrorHandler)))
registerMemoryErrorHandler();
}
auto serverSettings = new HTTPServerSettings;
serverSettings.hostName = "searcher.ebookingservices.com";
serverSettings.bindAddresses = options.bindip;
serverSettings.port = options.port;
serverSettings.errorPageHandler = toDelegate(&errorPage);
serverSettings.options = HTTPServerOption.defaults | HTTPServerOption.errorStackTraces;
serverSettings.accessLogFormat = "%h - %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %D";
serverSettings.accessLogFile = options.accessLog;
serverSettings.disableDistHost = true;
serverSettings.useCompressionIfPossible = false;
auto router = (new URLRouter)
.get("/ping", &pingHandler); // used only for monitoring
listenHTTP(serverSettings, router);
}
void pingHandler(HTTPServerRequest req, HTTPServerResponse res) {res.writeBody("pong");}
extern(C) __gshared string[] rt_options = [ "gcopt=profile:0 minPoolSize:512 initReserve:2048 heapSizeFactor:1 help" ];
version(VibeCustomMain) {
int main(string[] args) {
import vibe.core.args : finalizeCommandLineOptions;
import vibe.core.core : runEventLoop, lowerPrivileges;
import vibe.core.log;
import std.encoding : sanitize;
try {
if (!finalizeCommandLineOptions())
return 0;
} catch (Exception e) {
return 1;
}
startServer();
lowerPrivileges();
try {
return runEventLoop();
} catch (Throwable e) {
//logError("Unhandled exception in event loop: %s", e.msg);
//logDiagnostic("Full exception: %s", e.toString().sanitize());
return 1;
}
}
} else {
shared static this() {
startServer();
}
}
if you comment this line
extern(C) __gshared string[] rt_options = [ "gcopt=profile:0 minPoolSize:512 initReserve:2048 heapSizeFactor:1 help" ];
Then it wont allocate memory and the difference in performance is quite huge.
From running a profiler on the app, it looks like with large memorry allocated, vibe array utils is called on a lot inside libevent.
Any help or insights would be appreciated.