【问题标题】:Load testing a multi-threaded system vs one using separate processes - why is the threaded version so much faster?负载测试多线程系统与使用单独进程的系统 - 为什么线程版本要快得多?
【发布时间】:2011-07-05 14:01:29
【问题描述】:

我正在开发一个由三个高级组件交互的系统

Client(PHP) -- Logger (Java) -- MainBackend (Java)

PHP 客户端为收到的每个请求创建一个新的 Linux Logger 进程。 Logger 然后通过 TCP 向 MainBackend 发送一条消息,并开始记录它从 MainBackend 接收到的消息。请注意,Logger 非常轻量级并且使用的内存非常少。

我通过增加访问系统的用户数 N 对这个系统进行了负载测试。然后我写了一个 Logger 是多线程的版本,这样每 N 个并发用户只使用一个进程,并对线程版本进行负载测试。

结果是多线程版本要快得多,因为超过某个 N 时要快 很多 倍。我的问题是为什么?

如果启动每个 Linux 进程需要一定的时间 T,为什么我没有看到两个图表之间的恒定差异 (T2 - T1)?

Linux 在调度进程方面的效率是否远低于 Java 在调度线程方面的效率?

编辑:我没有提到的重要一点是,时间都是在 Logger 内部完成的,所以启动进程/虚拟机的时间不会影响结果——我这样做是为了让尽可能少的变量。

【问题讨论】:

  • 是的,创建OS进程比创建Java线程慢。
  • 这里没有考虑启动 Java 虚拟机所需的时间
  • 我知道这一点 - 但这也应该是一个恒定的时间。我测得这大约是 145 毫秒。我们在这里谈论的是一个巨大的差异,因为 T 值相当大,在几秒钟内。问题是为什么 T2 - T1 不是一个常数,或者至少是合理的常数。
  • 我假设您的客户端也等待进程关闭?它也可能需要一些时间。
  • 附带说明:保持线程工作者池,不要为多个线程创建方式。

标签: java linux multithreading process


【解决方案1】:

JVM 会进行运行时优化,尤其是对于重复执行的代码。这将需要一些时间,一个热身期。结果可能会快得多。您可以在同一个虚拟机中重复执行您的任务,您会发现它一开始很慢,但最终变得更快。

如果您为每个小任务启动一个新的 JVM 进程,则在 JVM 终止之前不会启动任何优化。

【讨论】:

    【解决方案2】:

    进程比线程更重。使用现有的进程或现有的 TCP 连接比每次都创建一个新的要快得多。这适用于所有操作系统。如果性能对您来说不是问题,您只会按需创建流程或连接。

    您会看到完成大多数任务所需的时间有所不同,因为机器试图同时执行几件事。您应该总是期望看到一些变化。

    【讨论】:

    • 重点是a)我们在这里讨论几个测试的结果,b)我使用的时间是平均的,c)相对于非线程版本,线程版本变得越来越高效随着 N 增加的版本 - 没有恒定的差异。您所说的差异应该在很大程度上平均化,因为在 80 个用户的情况下,我平均 80 个数字。虽然图上有有噪声,但还是有明显的趋势。
    • 随着 JVM 的升温,它会变得更快。它的速度可以提高 10 倍。
    【解决方案3】:

    这不仅关乎创建进程或线程的时间,还关乎上下文切换。你可以在这里找到一些数字: http://wiki.osdev.org/Context_Switching, http://en.wikipedia.org/wiki/Context_switch.

    简而言之,包含进程信息的结构大于包含线程数据的结构。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2011-05-24
      相关资源
      最近更新 更多