2

我正在运行一个简单的 Thrift 服务器(http://thrift.apache.org/)作为 Python(服务器)和 Haskell(客户端)之间的跨语言平台。唯一需要发送的数据结构是双精度的 3 元组,因此服务器/客户端实现也非常简单 - 只需遵循教程即可。

然而,它真的,真的很慢!当我需要大约 0.1 秒或更低的时间时,每个服务器响应的响应时间约为 0.5 秒。

有人对如何加快速度有任何想法吗?您可以在下面看到我的简单服务器实现:

  1 import sys
  2 
  3 from vision import Vision
  4 from vision.ttypes import *
  5 
  6 from thrift.transport import TSocket
  7 from thrift.transport import TTransport
  8 from thrift.protocol import TBinaryProtocol
  9 from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated
 10 from thrift.server import TServer
 11 
 12 class VisionHandler:
 13   def observe(self):
 14     ret = Position()
 15     ret.x,ret.y,ret.z = (1,2,3)
 16     return ret
 17     
 18 ret = Position()
 20 handler = VisionHandler()
 21 processor = Vision.Processor(handler)
 22 transport = TSocket.TServerSocket(port=9090)
 23 tfactory = TTransport.TBufferedTransportFactory()
 24 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
 25 
 26 server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
 27 
 28 print 'Starting the vision server...'
 29 server.serve()
 30 print 'done.'

客户端只需通过运行查询该服务器

36   client = do
37     handle <- hOpen ("localhost", PortNumber 9090)
38     let binProto = BinaryProtocol handle
39     return (binProto, binProto)

进而

res <- Client.observe =<< client

据我所知,这都是非常标准的!怎么这么慢??

谢谢!

4

2 回答 2

2

除了 Ellioh answer 中关于套接字选项的很好建议之外,问题之一是您的操作似乎有点小而且可以通过套接字处理,而且大部分时间都花在网络和类似的延迟上。通常,人们会尝试将您的呼叫分组以传输更多数据并在每次呼叫中完成更多工作。粒度在网络分布式应用程序中非常重要,您需要找到良好的性能衡量标准。

于 2013-02-12T11:16:12.087 回答
1

很可能是因为套接字选项。我不记得 Thrift 是否允许设置套接字选项,但设置TCP_NODELAY关闭拥塞控制有可能解决问题。

如果是您使用的相同代码,则可以轻松访问套接字。尝试继承 TSocket。

应该为服务器端(从 accept() 返回的套接字)和客户端(由客户端创建的套接字)端的套接字发送/接收数据设置该选项。Thrift 并不慢,所以问题不应该出在序列化上,除非你正在序列化一些非常可怕的东西。这意味着问题在于所有“连接、发送数据、获得答案”的东西。几乎可以肯定应该是因为 Nagle 算法被TCP_NODELAY.

于 2013-02-11T11:11:48.270 回答