You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@thrift.apache.org by Deepak Muley <de...@gmail.com> on 2012/10/14 08:13:24 UTC

TNonblockingServer Vs THttpServer Performance

Hello All,

One query:

I want to use THttpServer in my python project but from initial performance
review for a single client single request (No ThreadingMixIn required at
this point),
it shows that HttpServer is always 2 to 4 times slower than NonBlocking
server in tutorial Calculator client server app and same was observed in my
product testing as well.
Is there a way to make the performance equal for THTTPServer as compared to
NonBlocking?

Heres the code for NonBlocking client and server in python and its
performance on ubuntu. single machine.
------------------
client:
def non_blocking_server_client():

   try:

      # Make socket
      transport = TSocket.TSocket('localhost', 9090)

      # Buffering is critical. Raw sockets are very slow
      transport = TTransport.TFramedTransport(transport)

      # Wrap in a protocol
      protocol = TBinaryProtocol.TBinaryProtocol(transport)

      # Create a client to use the protocol encoder
      client = Calculator.Client(protocol)

      # Connect!
      transport.open()

      perform_ops(client)

      # Close!
      transport.close()

   except Thrift.TException, tx:
      print '%s' % (tx.message)


server:
def non_blocking_server():
   handler = CalculatorHandler()
   processor = Calculator.Processor(handler)
   transport = TSocket.TServerSocket(port=9090)

   server = TNonblockingServer.TNonblockingServer(processor, transport)

   print 'Starting the server...'
   server.serve()
   print 'done.'


performance timings:

$ ./PythonClient.py
ping took 0.633 ms <==================
ping()
add took 0.395 ms
1+1=2
InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
calculate took 0.399 ms
15-10=5
getStruct took 0.361 ms
Check log: 5

$ ./PythonClient.py
ping took 0.536 ms <==================
ping()
add took 0.362 ms
1+1=2
InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
calculate took 0.403 ms
15-10=5
getStruct took 0.364 ms
Check log: 5

------------------

Heres the code for HttpServer client and server in python and its
performance
------------------
client:
def http_server_client():
   try:

      path = "http://%s:%s/" % ('127.0.0.1', 9090)

      transport = THttpClient.THttpClient(uri_or_host=path)

      # Wrap in a protocol
      protocol = TBinaryProtocol.TBinaryProtocol(transport)

      # Create a client to use the protocol encoder
      client = Calculator.Client(protocol)

      # Connect!
      transport.open()

      perform_ops(client)

      # Close!
      transport.close()

   except Thrift.TException, tx:
      print '%s' % (tx.message)


server:
def http_server():
   handler = CalculatorHandler()
   processor = Calculator.Processor(handler)
   pfactory = TBinaryProtocol.TBinaryProtocolFactory()

   server = THttpServer.THttpServer(processor, ('127.0.0.1', 9090),
pfactory)

   print 'Starting the server...'
   server.serve()
   print 'done.'


performance timings:

$ ./PythonClient.py
ping took 1.535 ms <==================
ping()
add took 0.972 ms
1+1=2
InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
calculate took 0.929 ms
15-10=5
getStruct took 0.943 ms
Check log: 5

$ ./PythonClient.py
ping took 1.243 ms <==================
ping()
add took 0.944 ms
1+1=2
InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
calculate took 0.930 ms
15-10=5
getStruct took 0.925 ms
Check log: 5

------------------

server side timings are pretty low.
In my project I observed that on client side, its the generated code
send_<api> takes most of the time. which internally calls httplib's
getresponse which probably is waiting for something to come on wire?

Will really appreciate if someone can shed some light on how to improve
performance for THttpServer in thrift 0.8.0.

RE: TNonblockingServer Vs THttpServer Performance

Posted by "Elswick, Richard" <el...@us.panasonic.com>.
Javascript isn't restricted to JSON, it is just natively easier to handle JSON formatted data in Javascript.  There is nothing to say you cannot write your own processor of data being received.  Of course this would be in a WebSocket world, which Thrift isn't setup yet to support and doesn't apply to the current Javascript generated code from Thrift.

Rich Elswick

-----Original Message-----
From: Juan Moreno [mailto:jwellington.moreno@gmail.com] 
Sent: Sunday, October 14, 2012 11:42 AM
To: user@thrift.apache.org
Subject: Re: TNonblockingServer Vs THttpServer Performance

As you seemed to have figured out, there is overhead to running an entire
http client framework entirely in process as opposed to using a webapp
container. There is also the fact that the JSON protocol which JavaScript
must use is less efficient than the Binary Protocol usually used in the raw
Socket protocols.

A better test would be if you increased the number of client requests and
tried to execute concurrent queries and measure response times that way.
Then take the average.
On Oct 14, 2012 2:14 AM, "Deepak Muley" <de...@gmail.com> wrote:

> Hello All,
>
> One query:
>
> I want to use THttpServer in my python project but from initial performance
> review for a single client single request (No ThreadingMixIn required at
> this point),
> it shows that HttpServer is always 2 to 4 times slower than NonBlocking
> server in tutorial Calculator client server app and same was observed in my
> product testing as well.
> Is there a way to make the performance equal for THTTPServer as compared to
> NonBlocking?
>
> Heres the code for NonBlocking client and server in python and its
> performance on ubuntu. single machine.
> ------------------
> client:
> def non_blocking_server_client():
>
>    try:
>
>       # Make socket
>       transport = TSocket.TSocket('localhost', 9090)
>
>       # Buffering is critical. Raw sockets are very slow
>       transport = TTransport.TFramedTransport(transport)
>
>       # Wrap in a protocol
>       protocol = TBinaryProtocol.TBinaryProtocol(transport)
>
>       # Create a client to use the protocol encoder
>       client = Calculator.Client(protocol)
>
>       # Connect!
>       transport.open()
>
>       perform_ops(client)
>
>       # Close!
>       transport.close()
>
>    except Thrift.TException, tx:
>       print '%s' % (tx.message)
>
>
> server:
> def non_blocking_server():
>    handler = CalculatorHandler()
>    processor = Calculator.Processor(handler)
>    transport = TSocket.TServerSocket(port=9090)
>
>    server = TNonblockingServer.TNonblockingServer(processor, transport)
>
>    print 'Starting the server...'
>    server.serve()
>    print 'done.'
>
>
> performance timings:
>
> $ ./PythonClient.py
> ping took 0.633 ms <==================
> ping()
> add took 0.395 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.399 ms
> 15-10=5
> getStruct took 0.361 ms
> Check log: 5
>
> $ ./PythonClient.py
> ping took 0.536 ms <==================
> ping()
> add took 0.362 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.403 ms
> 15-10=5
> getStruct took 0.364 ms
> Check log: 5
>
> ------------------
>
> Heres the code for HttpServer client and server in python and its
> performance
> ------------------
> client:
> def http_server_client():
>    try:
>
>       path = "http://%s:%s/" % ('127.0.0.1', 9090)
>
>       transport = THttpClient.THttpClient(uri_or_host=path)
>
>       # Wrap in a protocol
>       protocol = TBinaryProtocol.TBinaryProtocol(transport)
>
>       # Create a client to use the protocol encoder
>       client = Calculator.Client(protocol)
>
>       # Connect!
>       transport.open()
>
>       perform_ops(client)
>
>       # Close!
>       transport.close()
>
>    except Thrift.TException, tx:
>       print '%s' % (tx.message)
>
>
> server:
> def http_server():
>    handler = CalculatorHandler()
>    processor = Calculator.Processor(handler)
>    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
>
>    server = THttpServer.THttpServer(processor, ('127.0.0.1', 9090),
> pfactory)
>
>    print 'Starting the server...'
>    server.serve()
>    print 'done.'
>
>
> performance timings:
>
> $ ./PythonClient.py
> ping took 1.535 ms <==================
> ping()
> add took 0.972 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.929 ms
> 15-10=5
> getStruct took 0.943 ms
> Check log: 5
>
> $ ./PythonClient.py
> ping took 1.243 ms <==================
> ping()
> add took 0.944 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.930 ms
> 15-10=5
> getStruct took 0.925 ms
> Check log: 5
>
> ------------------
>
> server side timings are pretty low.
> In my project I observed that on client side, its the generated code
> send_<api> takes most of the time. which internally calls httplib's
> getresponse which probably is waiting for something to come on wire?
>
> Will really appreciate if someone can shed some light on how to improve
> performance for THttpServer in thrift 0.8.0.
>

Re: TNonblockingServer Vs THttpServer Performance

Posted by Juan Moreno <jw...@gmail.com>.
As you seemed to have figured out, there is overhead to running an entire
http client framework entirely in process as opposed to using a webapp
container. There is also the fact that the JSON protocol which JavaScript
must use is less efficient than the Binary Protocol usually used in the raw
Socket protocols.

A better test would be if you increased the number of client requests and
tried to execute concurrent queries and measure response times that way.
Then take the average.
On Oct 14, 2012 2:14 AM, "Deepak Muley" <de...@gmail.com> wrote:

> Hello All,
>
> One query:
>
> I want to use THttpServer in my python project but from initial performance
> review for a single client single request (No ThreadingMixIn required at
> this point),
> it shows that HttpServer is always 2 to 4 times slower than NonBlocking
> server in tutorial Calculator client server app and same was observed in my
> product testing as well.
> Is there a way to make the performance equal for THTTPServer as compared to
> NonBlocking?
>
> Heres the code for NonBlocking client and server in python and its
> performance on ubuntu. single machine.
> ------------------
> client:
> def non_blocking_server_client():
>
>    try:
>
>       # Make socket
>       transport = TSocket.TSocket('localhost', 9090)
>
>       # Buffering is critical. Raw sockets are very slow
>       transport = TTransport.TFramedTransport(transport)
>
>       # Wrap in a protocol
>       protocol = TBinaryProtocol.TBinaryProtocol(transport)
>
>       # Create a client to use the protocol encoder
>       client = Calculator.Client(protocol)
>
>       # Connect!
>       transport.open()
>
>       perform_ops(client)
>
>       # Close!
>       transport.close()
>
>    except Thrift.TException, tx:
>       print '%s' % (tx.message)
>
>
> server:
> def non_blocking_server():
>    handler = CalculatorHandler()
>    processor = Calculator.Processor(handler)
>    transport = TSocket.TServerSocket(port=9090)
>
>    server = TNonblockingServer.TNonblockingServer(processor, transport)
>
>    print 'Starting the server...'
>    server.serve()
>    print 'done.'
>
>
> performance timings:
>
> $ ./PythonClient.py
> ping took 0.633 ms <==================
> ping()
> add took 0.395 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.399 ms
> 15-10=5
> getStruct took 0.361 ms
> Check log: 5
>
> $ ./PythonClient.py
> ping took 0.536 ms <==================
> ping()
> add took 0.362 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.403 ms
> 15-10=5
> getStruct took 0.364 ms
> Check log: 5
>
> ------------------
>
> Heres the code for HttpServer client and server in python and its
> performance
> ------------------
> client:
> def http_server_client():
>    try:
>
>       path = "http://%s:%s/" % ('127.0.0.1', 9090)
>
>       transport = THttpClient.THttpClient(uri_or_host=path)
>
>       # Wrap in a protocol
>       protocol = TBinaryProtocol.TBinaryProtocol(transport)
>
>       # Create a client to use the protocol encoder
>       client = Calculator.Client(protocol)
>
>       # Connect!
>       transport.open()
>
>       perform_ops(client)
>
>       # Close!
>       transport.close()
>
>    except Thrift.TException, tx:
>       print '%s' % (tx.message)
>
>
> server:
> def http_server():
>    handler = CalculatorHandler()
>    processor = Calculator.Processor(handler)
>    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
>
>    server = THttpServer.THttpServer(processor, ('127.0.0.1', 9090),
> pfactory)
>
>    print 'Starting the server...'
>    server.serve()
>    print 'done.'
>
>
> performance timings:
>
> $ ./PythonClient.py
> ping took 1.535 ms <==================
> ping()
> add took 0.972 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.929 ms
> 15-10=5
> getStruct took 0.943 ms
> Check log: 5
>
> $ ./PythonClient.py
> ping took 1.243 ms <==================
> ping()
> add took 0.944 ms
> 1+1=2
> InvalidOperation: InvalidOperation(what=4, why='Cannot divide by 0')
> calculate took 0.930 ms
> 15-10=5
> getStruct took 0.925 ms
> Check log: 5
>
> ------------------
>
> server side timings are pretty low.
> In my project I observed that on client side, its the generated code
> send_<api> takes most of the time. which internally calls httplib's
> getresponse which probably is waiting for something to come on wire?
>
> Will really appreciate if someone can shed some light on how to improve
> performance for THttpServer in thrift 0.8.0.
>