TNonblockingServer、TThreadedServer 和 TThreadPoolServer,哪一个最适合我的情况?
Posted
技术标签:
【中文标题】TNonblockingServer、TThreadedServer 和 TThreadPoolServer,哪一个最适合我的情况?【英文标题】:TNonblockingServer, TThreadedServer and TThreadPoolServer, which one fits best for my case? 【发布时间】:2010-08-22 23:05:14 【问题描述】:我们的分析服务器是用 C++ 编写的。它基本上查询底层存储引擎并通过thrift返回相当大的结构化数据。一个典型的请求大约需要 0.05 到 0.6 秒才能完成,具体取决于请求的大小。
我注意到我们可以在 c++ 代码中使用的 Thrift 服务器有几个选项,特别是 TNonblockingServer、TThreadedServer 和 TThreadPoolServer。似乎 TNonblockingServer 是要走的路,因为它可以支持更多的并发请求,并且仍然在后台使用线程池来处理任务。它还避免了构建/销毁线程的成本。
Facebook 关于 Thrift 的更新:http://www.facebook.com/note.php?note_id=16787213919
在 Facebook,我们正在为 C++ 开发一个完全异步的客户端和服务器。这 服务器使用事件驱动的 I/O,就像当前的 TNonblockingServer,但它的接口 应用程序代码全部基于异步回调。这将允许我们写 可以同时处理数千个请求的服务器(每个请求都需要 只用几个线程调用其他 Thrift 或 Memcache 服务器)。
stackover 上的相关帖子:Large number of simulteneous connections in thrift
话虽如此,您不一定能够真正更快地完成工作(处理程序 仍然在线程池中执行),但更多的客户端将能够一次连接到您。
只是想知道我在这里是否缺少其他因素?我该如何决定哪一个最适合我的需求?
【问题讨论】:
我看到了这篇文章。 blog.51cto.com/luckybins/1344189。我很清楚。 【参考方案1】:需要 50-600 毫秒才能完成的请求相当长。创建或销毁线程所需的时间远少于此,因此此时不要让该因素影响您的决定。我会选择最容易支持且最不容易出错的那个。您希望最大限度地减少细微并发错误的可能性。
这就是为什么编写单线程事务处理代码在需要的地方阻塞并让其中许多并行运行的代码通常比编写更复杂的非阻塞模型更容易的原因。阻塞的线程可能会减慢单个事务,但它不会阻止服务器在等待时执行其他工作。
如果您的事务负载增加(即更多的客户端事务)或请求的处理速度变得更快(每个事务接近 1 毫秒),那么事务开销就会成为一个更大的因素。要注意的指标是吞吐量:每单位时间完成多少事务。单个事务的绝对持续时间不如它们完成的速率重要,至少如果它保持在 1 秒以下。
【讨论】:
【参考方案2】:Github 上的一个人做了一个很好的比较
TThreadedServer
TThreadedServer 为每个客户端连接生成一个新线程,并且每个线程保持活动状态,直到客户端连接关闭。这意味着如果有 1000 个并发客户端连接,TThreadedServer 需要同时运行 1000 个线程。
TNonblockingServer
TNonblockingServer 有一个专门用于网络 I/O 的线程。同一个线程也可以处理请求,或者您可以创建一个单独的工作线程池来处理请求。服务器可以用少量线程处理许多并发连接,因为它不需要为每个连接生成一个新线程。
TThreadPoolServer(此处未进行基准测试)
TThreadPoolServer 类似于 TThreadedServer;每个客户端连接都有自己的专用服务器线程。它在两个方面与 TThreadedServer 不同:
客户端关闭连接后,服务器线程返回线程池以供重用。 线程数有限制。线程池的增长不会超过限制。 如果线程池中没有更多可用线程,客户端将挂起。与其他 2 台服务器相比,它更难使用。
【讨论】:
以上是关于TNonblockingServer、TThreadedServer 和 TThreadPoolServer,哪一个最适合我的情况?的主要内容,如果未能解决你的问题,请参考以下文章