Re: JERI vs. JRMP performance penalties

"Cornelius, Martin (DWBI)" <[email protected]> Fri, 7 Dec 2007 03:26:10 -0700
Newsgroups gmane.comp.java.sun.jini
Message-ID <531F9EE7AD1E874595D59997FD3EAEED03A7F16B@COSSMGMBX05.EMAIL.CORP.TLD>
Hi again, Mark

> Could you tell a bit more about the kind of invocations you are
> making and whether these took place concurrently, etc. 

Essentially, i send a large buffer of data from a single client, no
concurrency at all. This scenario may be somewhat unusual, but it is
realistic in our application.

> Another thing not
> 100% clear to me is whether you were doing the tests with your own
> socket factories or not? In case you were not using socket factories
did
> you set the system property "com.sun.jini.jeri.tcp.useNIO" to true.
One
> reason to use socket factories is to force usage of NIO.

Of course i tested with and without my self-rolled socket factories, and
i also tested with and without "com.sun.jini.jeri.tcp.useNIO". The
results were *roughly* equal in all scenarios tested. With my own socket
factories performance of JERI was a little worse, but not very much.

> Also I'm curious whether you had GC logging enabled to see whether
there
> are some anomalies between the 2 tests and whether you monitored the
> load of your systems for both tests.

Actually, being still a java newbie, i don't even now how to enable GC
logging. I monitored the load of my system by looking at the output of
my graphical KDE system monitor, it was about 100% in both tests. To
have my results not influenced by DGC, i disabled DGC in the JERI case
(unfortunately not possible for RMI)

> Another thing that might be handy
> to know is how many cores the systems had.- 

The tests i reported in my last posting were done on my HP laptop, where
linux is running in a vmware. To be sure, i just repeated the tests on
another 1 core server machine running linux natively. This box has about
the double cpu speed as my laptop, and as expected the throughput rates
measured in the tests were also roughly doubled, here are the results:

Throughput with JRMP was 140 Mbyte/sec, and with JERI (without useNIO)
it was 20 Mbyte/sec. Altough not factor 10 but 7, still alarming IMHO.
If i run JERI with useNIO, throughput increases to 24Mbyte/sec, what
means factor 6. The total system load caused by the test (viewed with
top) was 100% in all cases, *roughly* 60%user and 40%system.

> One last question is what would the typical usage be in the field you
want > to utilize it?

The primary task of the system i have to design is distribution of
high-res images (Size of one image from 2 up to 100 Mbyte) in a large,
partly fragile network. For this reason, it is really crucial that the
throughput of the transport for large data chunks (and the system load
caused by this) is in the order of using TCP sockets directly (factor 2
would be acceptable).

To make my observations retraceable, here is the test i used: The client
and the implementation is the same for both tests, just the exporting
server is different. (The setting of useNIO is commented out below for
server and client)

------------------ snip -------------------------------

// the interface

package perfcompare;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface DataSink extends Remote 
{
    void transferChunk(byte[] data) throws RemoteException;
}

------------------ snip -------------------------------

// the implementation

package perfcompare;

import java.rmi.RemoteException;

public class DataSinkImpl implements DataSink
{
  public void transferChunk(byte[] data) throws RemoteException
  {
    System.out.println("received: " + data.length);
  }
}

------------------ snip -------------------------------

// the client, usable for both servers

package perfcompare;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Date;

public class Client
{
  public final static String PROXYFILE = "/tmp/HelloProxy";
  final static int chunkSize = 10 * 1000 * 1000;
  final static int count = 100;

  public static void main(String[] args)
  {   
    // System.setProperty("com.sun.jini.jeri.tcp.useNIO", "true");
    
    try
    {
      ObjectInputStream istream = new ObjectInputStream( new
FileInputStream(PROXYFILE));
      DataSink proxy = (DataSink) istream.readObject();
      
      byte[] payload = new byte[chunkSize];
      System.out.println("Starting...");
      
      Date startTime = new Date();
      for (int i = 0; i < count; ++i)
      {
        System.out.println("chunk " + i);
        proxy.transferChunk(payload);
      }
      
      Date endTime = new Date();

      long elapsed = endTime.getTime() - startTime.getTime();
      long rate = chunkSize * count / elapsed ;
      System.out.println("Finished after " + elapsed + " msecs, " + rate
+ " KByte/sec");
    }
    catch (Exception e)
    {
      System.err.println("Client failed: " + e);
    }
  }
}
------------------ snip -------------------------------

// the rmi server

package perfcompare;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.rmi.server.UnicastRemoteObject;

public class RmiServer
{
  final static int SERVER_PORT = 8888;

  public static void main(String args[])
  {    
    try
    {
      DataSink impl = new DataSinkImpl();
      DataSink proxy = (DataSink) UnicastRemoteObject.exportObject(impl,
SERVER_PORT);

      ObjectOutputStream ostream = new ObjectOutputStream(new
FileOutputStream(Client.PROXYFILE));
      ostream.writeObject(proxy);
      System.out.println("proxy written to file " + Client.PROXYFILE);
            
      Thread.sleep(10 * 3600 * 1000); // make sure we don't terminate
    }
    catch (Exception e)
    {
      System.out.println("RmiServer falied: " + e.getMessage());
    }
  }
}

------------------ snip -------------------------------

// the JERI server

package perfcompare;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.rmi.Remote;

import net.jini.export.Exporter;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;

public class JeriServer
{
  final static int SERVER_PORT = 8888;

  public static void main(String[] args)
  {
    // System.setProperty("com.sun.jini.jeri.tcp.useNIO", "true");

    DataSink impl = new DataSinkImpl();
    try
    {
      Exporter exporter = new BasicJeriExporter(
 
TcpServerEndpoint.getInstance(InetAddress.getLocalHost().getHostAddress(
), SERVER_PORT ),
          new BasicILFactory(),
          false, // no DGC
          true   // keep this thread alive
      );
      Remote proxy = exporter.export(impl);

      ObjectOutputStream ostream = new ObjectOutputStream(new
FileOutputStream(Client.PROXYFILE));
      ostream.writeObject(proxy);
      System.out.println("proxy written to file " + Client.PROXYFILE);
      
    }
    catch (Exception e)
    {
      System.err.println("JeriServer failed: " + e);
    }
  }
}

------------------ snip -------------------------------


 
************************************************
The information contained in, or attached to, this e-mail, may contain confidential information and is intended solely for the use of the individual or entity to whom they are addressed and may be subject to legal privilege.  If you have received this e-mail in error you should notify the sender immediately by reply e-mail, delete the message from your system and notify your system manager.  Please do not copy it for any purpose, or disclose its contents to any other person.  The views or opinions presented in this e-mail are solely those of the author and do not necessarily represent those of the company.  The recipient should check this e-mail and any attachments for the presence of viruses.  The company accepts no liability for any damage caused, directly or indirectly, by any virus transmitted in this email.
************************************************

--------------------------------------------------------------------------
Getting Started:     http://www.jini.org/wiki/Category:Getting_Started
Community Web Site:  http://jini.org
jini-users Archive:  http://archives.java.sun.com/archives/jini-users.html
Unsubscribing:       email "signoff JINI-USERS"  to [email protected]