Thrift服务器在简单操作时非常慢

2 投票
2 回答
2848 浏览
提问于 2025-04-17 15:29

我正在运行一个简单的Thrift服务器(http://thrift.apache.org/),它是一个跨语言的平台,服务器用的是Python,客户端用的是Haskell。需要传输的数据结构很简单,就是一个包含三个双精度浮点数的元组,所以服务器和客户端的实现也很简单——只需按照教程操作就可以了。

但是,速度真的非常慢!每次服务器响应的时间大约是0.5秒,而我希望的响应时间是0.1秒或更短。

有没有人有什么想法可以加快这个速度?你可以在下面看到我简单的服务器实现:

  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

就可以了。就我所知,这一切都很标准!为什么这么慢呢??

谢谢!

2 个回答

1

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

如果这个是你使用的代码,套接字是很容易访问的。你可以尝试创建一个TSocket的子类。

这个选项应该在服务器(从accept()返回的套接字)和客户端(客户端创建的套接字)两边都设置,用于发送和接收数据。Thrift本身并不慢,所以问题不应该出在序列化上,除非你序列化的东西特别庞大。这意味着问题出在“连接、发送数据、获取回复”这些操作上。几乎可以肯定是因为Nagle算法被TCP_NODELAY关闭了。

2

除了Ellioh提到的关于套接字选项的好建议之外,问题之一是你的操作似乎太小、太细了,不适合通过套接字来处理,而且大部分时间都花在网络延迟和类似的延迟上。通常,人们会尝试把你的请求合并起来,这样可以在每次调用中传输更多数据,做更多的工作。在网络分布式应用中,操作的粒度非常重要,你需要找到一个合适的标准来提高性能。

撰写回答