在执行io时,Akka JVM线程vs OS线程



我在网站上搜索了一下,希望能帮助我理解这一点,但没有发现任何非常清楚的东西,所以我想把我的用例贴出来,看看是否有人能提供一些帮助。

我有一个关于在akka中使用io操作时jvm线程与os线程的缩放的问题。来自akka网站:

Akka支持事件驱动的轻量级线程的调度程序,允许在单个工作站上创建数百万个线程,以及基于线程的actor,其中每个调度程序绑定到一个专用的操作系统线程。

基于事件的Actor目前每个Actor消耗约600字节,这意味着您可以在4g RAM上创建超过650万个Actor。

在这种情况下,你们能帮我理解在只有1个处理器的工作站上这是如何重要的(为了简单)吗?因此,对于我的示例用例,我想要一个包含1000个"用户"的列表,然后去查询数据库(或几个)以获取关于每个用户的各种信息。因此,如果我要将这些'get'任务分配给一个actor,并且该actor将执行IO,那么该actor不会基于工作站的os线程限制而阻塞吗?

在这种情况下,akka演员模型如何帮助我?我知道我可能遗漏了一些东西,因为我对vm线程和os线程的相互作用不是很了解,所以如果这里有一个聪明的人可以为我解释清楚,那就太好了。

如果我使用期货,我不需要使用await()或get()来阻塞和等待回复吗?

在我的用例中,不管演员,它最终只是"感觉"就像我做1000个连续的数据库请求?

如果代码片段有助于我理解这一点,Java将是首选,因为我仍然在加快scala语法的速度-但是一个清晰的文本解释如何在单处理器机器上进行数据库IO时,这些数百万线程如何互操作也会很好。

很难弄清楚你到底在问什么,但这里有一些提示:

  • 如果在现代JVM上运行,Java线程和OS线程之间通常存在一对一的关系。(IIRC, Solaris允许您以不同的方式执行此操作……

  • 使用线程或任何构建在线程之上的东西获得的实际并行性的数量受到应用程序可用的处理器/内核数量的限制。除此之外,你会发现并不是所有的线程在任何给定的时刻都在执行。

  • 如果你有1000个actor都试图访问数据库"在同一时间",那么他们中的大多数实际上将等待数据库本身,或在线程调度程序。这是否相当于生成1000个顺序请求(即严格序列化)将取决于数据库和actor正在执行的查询/更新。

底线是计算机系统对可用的资源有严格的限制;例如处理器的数量,处理器的速度,内存带宽,磁盘访问时间,网络带宽等。你可以设计一个应用程序,让它明智地使用可用资源,但你不能让它使用比实际资源更多的资源。


在阅读你引用的文章时,我觉得它似乎在谈论两种不同类型的演员:

基于线程的actor与线程有1对1的关系。你不可能在4Gb内存中拥有数百万个这样的actor。

基于事件的actor的工作方式不同。它们不是一直都有线程,而是大部分都坐在队列中等待事件发生。当这种情况发生时,事件处理线程将从队列中获取参与者并执行与事件关联的"操作"。当动作完成时,线程移动到另一个参与者/事件对。

引用的文本是说基于事件的 actor的内存开销是~600字节。它们不包括事件线程……因为事件线程是由多个参与者共享的。


我不是Scala/Actors方面的专家,但很明显,在使用基于事件的actor时,有一些事情是你应该避免的。例如,您可能应该避免直接与外部数据库通信,因为这可能会阻塞事件处理线程。

我想这里可能有打字错误。我想他们的意思是:

Akka支持事件驱动的轻量级actor 分派器,允许在单个工作站上创建数百万actor,以及基于线程的actor,其中每个actor绑定到一个专用的OS线程。

事件驱动的参与者使用线程池——所有(可能有数百万)参与者共享同一个线程池。我对Akka actor不太熟悉,但通常你不会想用事件驱动的actor阻塞I/O,否则你可能会导致饥饿。

最新更新