执行io时akka jvm线程vs os线程

我已经搜索了一些网站,以帮助理解这一点,但没有发现任何超级明确的东西,所以我想我会发布我的用例,看看是否有人可以解决一些问题。

我有一个关于在akka中用于io操作时jvm线程vs os线程的扩展的问题。 来自akka网站:

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

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

在这种情况下,您是否可以帮助我了解在只有1个处理器的工作站上的重要性(为简单起见)。 因此,对于我的示例用例,我想要列出1000个“用户”,然后查询数据库(或多个)以获取有关每个用户的各种信息。 因此,如果我要将每个“获取”任务分配给一个actor,并且该actor将要执行IO,那么该actor是否会基于工作站的os线程限制阻塞?

在这样的场景中,akka演员模型如何让我解脱? 我知道我可能遗漏了一些东西,因为我对vm线程与os线程的交互作用并不是很了解,所以如果这里有一个聪明的人可以为我拼出来,那就太好了。

如果我使用Futures,我是否需要使用await()或get()来阻止并等待回复?

在我的使用案例中,无论演员如何,它最终只是’感觉’就像我正在制作1000个顺序数据库请求一样?

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

很难弄清楚你在这里问的是什么,但这里有一些指示:

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

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

  • 如果你有1000个Actors都试图“同时”访问数据库,那么它们中的大多数实际上将等待数据库本身或线程调度程序。 这相当于制作1000个连续请求(即严格序列化)将取决于数据库以及演员正在进行的查询/更新。

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


在阅读你引用的文字时,在我看来,它正在讨论两种不同的演员

基于线程的actor与线程有1对1的关系。 你无法在4Gb内存中拥有数百万这样的演员。

基于事件的演员工作方式不同。 它们不是一直都有线程,而是主要坐在队列中等待事件发生。 当发生这种情况时,事件处理线程将从队列中获取actor并执行与该事件相关联的“动作”。 当动作结束时,线程移动到另一个actor /事件对。

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


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

我想那里可能会有拼写错误。 我想他们的意思是说:

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

事件驱动的actor使用线程池 – 所有(可能数百万)actor都共享相同的线程池。 我对Akka演员并不熟悉,但通常你不想用事件驱动的演员阻止I / O,否则你可能会导致饥饿。