我希望了解多线程如何解决可扩展性问题。我基本的理解是当请求到来时,会分配一个新线程来处理请求。但是背后究竟发生了什么呢?
我目前正在启动一个项目,需要构建一个存储云来处理成千上万个GET、PUT和DELETE操作。多线程能够解决可扩展性问题吗?还是应该考虑事件驱动服务器?
我目前正在启动一个项目,需要构建一个存储云来处理成千上万个GET、PUT和DELETE操作。多线程能够解决可扩展性问题吗?还是应该考虑事件驱动服务器?
多线程可以帮助,因为通常正常的HTTP执行包含许多I/O。而且你知道IO操作很重,需要很长时间。所以在实践中,当你有一个请求需要获取类A的实例和类B的实例时,如果你创建2个线程,一个用于访问A实例,另一个用于从数据库访问B类实例,你可以将每个实例加载到单独的线程上,这样你将更有可能在线程A执行其代码时,线程B被IO阻塞,反之亦然。因此,使用多线程可以节省IO处理时间。
这是第一个好处。另一个好处是,使用多线程,你不必为传入的连接保留整个线程,而是使用异步事件处理模型。有一个很好的实现使用这种技术,称为netty,可以处理每秒50,000多个请求。
线程是任务的最小单元。当一个任务/线程正在等待I/O或其他操作时,它将被脱机并开始执行其他线程。这发生在微秒级别上。此外,如果我们有多个处理器,我们可以同时运行许多线程。
我们需要谨慎考虑哪些内容可以作为线程。一个线程不应该依赖于另一个线程的输出。在这种情况下,多线程的概念会带来快速的结果。有时我们需要依赖其他线程。这时候我们使用同步。
如果所有操作都可以采取并行路径,则多线程可以提高性能。如果操作彼此依赖,则可以考虑事件驱动服务器。
多线程唯一擅长的是多核计算。
通常事件模型更轻量级,因为您可以完全控制代码执行。例如,如果您当前正在获取和处理HTTP标头,并且某个其他线程需要唤醒,则意味着:
在事件模型中,您将完全有权结束整个周期,保存数据,然后进行另一个事件。第二个事件将等待您完成工作。但是,通过劫持工作代码浪费的时间通常要大得多。
内存管理也要考虑:在线程模型中,您需要锁定以同步对关键数据的访问,但事件模型不需要锁定,也不需要每个线程特定数据的额外内存。
这也是Web服务器的重点所在:这样nginx就可以处理数千个连接而不会使机器崩溃。