在PinnedDispatcher上运行的Actor中使用ZMQ套接字是否安全?

时间:2018-04-11 11:42:40

标签: scala akka zeromq distributed-system jeromq

据我所知documentation,ZeroMQ套接字不应该被用于(例如从/写入)来自不同的线程。

这反过来阻止我在默认调度程序上运行的Akka Actor中使用ZMQ套接字(不保证哪个线程将执行我的receive方法)。

使用 PinnedDispatcher 允许我在Actor中安全地使用这样的套接字,前提是我注意不要阻止(至少不要过多的时间)?

  

这个调度程序为每个使用它的actor赋予一个唯一的线程;即每个actor都有自己的线程池,池中只有一个线程

via:https://doc.akka.io/docs/akka/2.5/dispatchers.html#types-of-dispatchers

我使用的是JeroMQ 0.4.0和Akka 2.5。我意识到Akka曾经有过ZeroMQ扩展,但似乎大多放弃了。

1 个答案:

答案 0 :(得分:-1)

嗯,线程安全性需要付出代价。

ZeroMQ,因为最早的版本(你指的是API版本2.1,虽然有API版本已经发布,并且已经发布,并且在2018 / Q2 +中可用),正在共享集合下构建价值又是一种 Zen-of-Zero ,它以资源友好的方式努力使事情尽可能有效地发生,并且只获得了合理的数量(最好没有)等待时间。

可能会看到最近在ZeroMQ 4.2+重新分解中添加线程安全的努力

然而,这并不意味着,这可以实现免费,是吗?

如果以适当的方式使用适当的工具,没有人会受到伤害吗?

然而,没有人可以忽略ZeroMQ API版本将出现在部署域中的主要不确定性,因此依赖于较新API版本中可用的功能无需证明其自身对于期间遇到的每个(远程)代理有效。寿命,所以要小心。

无论如何, Akka 注意警告说,as-is兼容性被冻结到API v.2级别:

  

目前使用的 zeromq-scala-bindings 版本仅与 zeromq 2 兼容; zeromq 3 支持。

那么,怎么样?

如果确实需要混合几个不同的事件循环(如上所述),我会选择将任务委派给一组独立运行(无论是共处还是分布式) Context() < / strong> -instances,而不是尝试共享any Socket()-AccessPoint-level instances或试图使用“固定” - 前提,只是由外部(并发共存)非ZeroMQ事件循环框架调解。

清洁“无共享”ZeroMQ设计比尝试越来越多的设计工具(如果您的域需要QA程序,如果设计验证和验证证明是在接受甚至可以安排之前获得交付 - 试着想象一下测试的成本,QA /验证证明对于野生混合玩具只是希望具有确定性,无阻塞,无差错和强大/弹性的现场操作)

注意:
ZeroMQ Socket() -instance 一个tcp-socket-as-you-know-it。最好阅读 ZeroMQ hierarchy in less than a five seconds other posts and discussions here中的主要概念差异。

Context() -instances在他们自己的控制域下拥有自己的I / O线程池,在相应的 Context Socket() - 实例允许与相应的 Context (组)I / O线程的亲缘关系因此,关于“固定”的全局视图可能不会影响预期的资源映射偏好。

最后但并非最不重要的 - 特定于Akka端口的配置,与ZeroMQ本机API默认值不匹配:

#####################################
# Akka ZeroMQ Reference Config File #
#####################################

# This is the reference config file that contains all the default settings.
# Make your edits/overrides in your application.conf.

akka {

  zeromq {

    # The default timeout for a poll on the actual zeromq socket.
    poll-timeout = 100ms

    # Timeout for creating a new socket
    new-socket-timeout = 5s

    socket-dispatcher {
      # A zeromq socket needs to be pinned to the thread that created it.
      # Changing this value results in weird errors and race conditions within
      # zeromq
      executor = thread-pool-executor
      type = "PinnedDispatcher"
      thread-pool-executor.allow-core-timeout = off
    }
  }
}