[Monetdb-developers] Mapi slowdown with Java + Linux (4.6.2!)

Agustin Schapira schapira at cs.umass.edu
Fri Mar 23 21:25:50 CET 2007

I have been struggling with this problem for a couple of weeks. We  
are using Monet 4.6.2 (I know, I know!) to power a web service  
written in Java. When Monet is running on OS X, I can handle 200+  
requests per second, but when I install it on a (much faster) Linux  
machine, the app only gives me 20 requests per second.

The difference happens on the TCP/IP connection. I have the simplest  

var a:=bat(int,int).insert(1,1);

This takes 4ms on OS X, but 40ms on Linux. I've traced down the  
system calls, and what happens is that when the server is running on  
OS X my client reads back the results in one or two calls to recv,  
whereas when the server is on Linux the client only gets a couple of  
bytes back from the server and then blocks until the rest arrives.  
The following is a section of strace's output on the Java application:

$ strace -f -ttt java -cp test.java test

Monet running on OS X:

send(5, "a.print();\n", 12, 0) = 12
recv(5, "#------------\n# h ....", 8192, 0) = 50
ioctl(5, FIONREAD, [45]) =
recv(5, " # type ....", 8192, 0) = 45

Monet running on Linux:

send(5, "a.print();\n", 12, 0) = 12
recv(5, "#-", 8192, 0)
ioctl(5, FIONREAD, [0]) =
recv(5, <unfinished...>  ==> blocks
[... 40ms...]
<recv resumed "----------#\n# h ...", 8192, 0) = 93

The sockets are opened in the same way in both cases, just like the  
MapiClient opens them:

connect(5, {sa_family=AF_INET, sin_port=htons(45678),  
sin_addr=inet_addr("")}, 16) = 0
setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
setsockopt(5, SOL_IP, IP_TOS, [8], 4) = 0
setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0

This problem does not happen when I use Monet's MapiClient: the  
response times on OS X and Linux are similar.

While inspecting the calls between the server and the MapiClient,  
then, I realized that the handshake is different from the one used by  
the Mapi.java class that comes with 4.6.2: the C client sets the  
'blocked' flag on.

Turning the 'blocked' flag to true in the MapiClient.java class  
doesn't work. Switching the C client's default mode to be non-blocked  
(in src/mapi/clients/C/Mapi.mx) does indeed make the connection much  
slower, as every single character is sent to the client in its own  
packet (due to TCP_NODELAY?):

write(3, "print(a);\n", 10) = 10
read(3, "#", 1)       = 1
read(3, "-", 1)       = 1
read(3, "-", 1)       = 1
read(3, "]", 1)       = 1
read(3, "\n", 1)      = 1

My question is then: is it possible to write a Java client that  
communicates with the server using the blocked protocol? Do you think  
that would solve my performance issues? If so, is there any  
documentation/example code I can follow (since the actual protocol  
seems to be different in both cases). I've looked at the latest CVS  
checkins for the the Mapi protocol, and I see that the only option  
now is the 'blocked' mode, so I guess it's possible to use it from  

FYI, I am using
	- Monet 4.6.2
	- Java 5
	- OS X 10.4.9
	- Linux 2.6.9, 2.6.15, 2.6.17

Thank you very much,

-- Agustin

More information about the developers-list mailing list