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