首页 文章

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

提问于
浏览
15

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

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

Akka支持事件驱动的轻量级线程的调度程序,允许在单个工作站上创建数百万个线程,以及基于线程的Actors,其中每个调度程序都绑定到专用的OS线程 . 基于事件的Actors目前每个Actor消耗约600个字节,这意味着您可以在4 G RAM上创建超过650万个Actors .

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

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

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

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

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

2 回答

  • 15

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

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

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

    • 如果你有1000个Actors都试图“同时”访问数据库,那么它们中的大多数实际上都在等待数据库本身或线程调度程序 . 这相当于产生1000个顺序请求(即严格序列化)将取决于数据库和参与者正在进行的查询/更新 .

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


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

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

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

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


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

  • 8

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

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

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

相关问题