【问题标题】:Does Akka.IO Tcp has a bottleneck in bidirectional communication?Akka.IO Tcp 是否存在双向通信瓶颈?
【发布时间】:2015-07-16 12:25:34
【问题描述】:

编辑:这是 Does Akka Tcp support full-duplex communication? 的重复(请不要多次问同一个问题,在邮件列表中重复也是如此,这浪费了那些自愿提供帮助,减少您将来获得答案的机会)


我已经从https://github.com/akka/akka/blob/master/akka-docs/rst/scala/code/docs/io/EchoServer.scala#L96修改了 Echo 服务器

case Received(data) =>
  connection ! Write(data, Ack(currentOffset))
  log.debug("same {}", sender.eq(connection)) // true
  buffer(data)

这意味着传入和传出消息由同一个参与者处理。因此,单个工作线程(从邮箱中获取消息)将处理读写操作。看起来像一个潜在的瓶颈。

在“经典”世界中,我可以创建一个线程从套接字读取,另一个线程用于写入并获得同时通信。

更新 google群内讨论https://groups.google.com/forum/#!topic/akka-dev/mcs5eLKiAVQ

【问题讨论】:

  • 是什么让你认为只有一个线程处理实际的低级连接?
  • 一个线程处理来自actor邮箱的消息(如果你愿意,我会给你一个文档链接)。可能线程不会消耗很多周期来处理消息,但无论如何,与读写线程方法相比,它是一个潜在的瓶颈。
  • 没有瓶颈,如果缓冲区在 TCP 级别已满/空,它将在发送或接收时阻塞。如果您不希望这样,您需要使用 select 来检查套接字是否可写或可读。

标签: multithreading scala sockets tcp akka


【解决方案1】:

虽然有一个 Actor 在任何给定时间点读取或写入,但这些操作中的每一个都只需要很少的周期,因为它仅在有要读取的数据或可写入的缓冲区空间时才会发生。大约 1µs 的系统调用开销意味着使用 128kiB 的默认缓冲区大小,您应该能够总共传输高达 100GiB/s,这肯定是一个瓶颈,但在今天和实践中可能不是(这与典型的 CPU 内存大致相符带宽,因此目前无论如何都不可能获得更高的数据速率)。一旦发生这种变化,我们就可以在不同的选择器之间拆分读写职责并唤醒不同的 Actor,但在此之前,我们需要验证是否确实存在可测量的效果。

另一个需要回答的问题是,哪些操作系统内核实际上允许多个线程在单个套接字上进行并发操作。我还没有对此进行研究,但我不会惊讶地发现完全独立的锁定很难做到,而且可能(还)没有理由付出这种努力。

【讨论】:

  • google 群里还有另一个讨论几乎相同的论点。我更愿意继续在那里。额外的 2 美分,你说的都是真的(我还没有在 akka 中看到消息处理开销的测量值,但无论如何大约 1µs 就足够了),但问题可能出在延迟上。如果邮箱包含 1k 条写入消息,它将额外增加 1 毫秒用于读取操作。对于 ping
猜你喜欢
  • 2015-07-15
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 2010-10-26
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
相关资源
最近更新 更多