简体   繁体   English

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

[英]Is it safe to use a ZMQ socket in an Actor running on a PinnedDispatcher?

As far as I can tell from documentation , ZeroMQ sockets are not supposed to be used (eg read from/written to) from different threads. 据我从文档中了解到,不应从不同线程使用(例如读/写)ZeroMQ套接字。

That in turn prevents me from using a ZMQ socket in an Akka Actor running on the default dispatcher (no guarantee about which thread will be executing my receive method). 反过来,这又使我无法在默认调度程序上运行的Akka Actor中使用ZMQ套接字(无法保证哪个线程将执行我的receive方法)。

Would using a PinnedDispatcher allow me to use such socket safely inside an Actor, provided that I take care not to block (at least not for excessive amounts of time)? 如果我注意不要阻塞(至少不要花费过多的时间),使用PinnedDispatcher是否可以让我在Actor中安全地使用此类套接字?

This dispatcher dedicates a unique thread for each actor using it; 该调度程序为使用它的每个参与者分配一个唯一的线程。 ie each actor will have its own thread pool with only one thread in the pool 也就是说,每个actor都有自己的线程池,池中只有一个线程

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

I am using JeroMQ 0.4.0 and Akka 2.5. 我正在使用JeroMQ 0.4.0和Akka 2.5。 I realize that Akka used to have a ZeroMQ extension but that seems mostly abandoned. 我意识到Akka曾经有一个ZeroMQ扩展名,但是似乎大部分都被放弃了。

Well, a thread-safeness comes at cost . 好吧, 线程安全是有代价的。

ZeroMQ, since the very earliest version ( you refer to API ver. 2.1, while there are API versions past 4.2+ released and available in 2018/Q2+ ) , was being built under a shared set of values aka a Zen-of-Zero , which strives to make things happen as-efficient-as-possible, in a resource-friendly manner and having acquired only a reasonable amount ( best none at all ) latency. ZeroMQ是最早的版本(您可以参考API版本2.1,尽管有超过4.2+的API版本已发布,并且在2018 / Q2 +中可用)是根据一组共享的值(即Zen-of-Zero 构建的,它努力以一种资源友好的方式使事情尽可能高效地发生,并且仅获得了合理的延迟(最好没有延迟)。


May see recent efforts to add thread-safety in ZeroMQ 4.2+ re-factoring 可能会看到最近在ZeroMQ 4.2+重构中增加线程安全性的努力

yet, this does not mean, this could be achieved cost-free, does it? 但是,这并不意味着可以免费实现,不是吗?

No one would be harmed, if using proper tools in a proper manner, would he? 如果以适当的方式使用适当的工具,没有人会受到伤害吗?

Yet, no one may ignore a principal uncertainty of which ZeroMQ API version will appear in the domain of deployment, so relying on a feature available in newer API versions need not prove itself to be valid for each ( remote ) agents met during the life-span, so be cautious. 但是,没有人会忽略主要的不确定性,即哪个ZeroMQ API版本将出现在部署领域中,因此,依靠较新API版本中可用的功能,无需证明自己对于生命中遇到的每个(远程)代理都是有效的,跨度,所以要谨慎。

Anyway, the Akka note warns, that as-is compatibility was frozen onto API v.2 level: 无论如何, Akka注释警告说,原样的兼容性已冻结到API v.2级别:

The currently used version of zeromq-scala-bindings is only compatible with zeromq 2 ; 当前使用的zeromq-scala-bindings版本仅与zeromq 2兼容; zeromq 3 is not supported. 支持zeromq 3。


So, how ? 又怎样 ?

If indeed in a need to mix several different event-loops ( as indicated above ), I would opt for delegating the task to a set of independently operating ( be it colocated or distributed ) Context() -instances, rather than trying to share any Socket() -AccessPoint-level instances or trying to use a "pinned"-promise, just-mediated by an external ( concurrently co-existent ) non-ZeroMQ event-loop framework. 如果确实需要混合几个不同的事件循环(如上所述),我将选择将任务委派给一组独立运行的(无论是共置还是分布式) Context()实例,而不是尝试共享任何实例Socket() AccessPoint级别的实例,或尝试使用由外部(同时存在)非ZeroMQ事件循环框架介导的“固定”承诺。

Clean "share-nothing" ZeroMQ designs are way safer and way faster, than trying an art of juggling more and more design-artifacts ( and if your domain requires QA-procedures, the more if design validation and verification proofs are to get delivered before an acceptance may even get scheduled -- try to just imagine the costs of testing, QA / verification proofs for a wild mix of toys just wished to have a deterministic, non-blocking, error-free and robust/resilient field operations ) 干净的“无共享” ZeroMQ设计比尝试处理越来越多的设计工件的艺术方法更安全,更快捷(并且,如果您的领域需要QA程序,那么在设计验证和验证证明要事先获得的情况下,这一点就更多了)甚至可能会安排一次验收-尝试想象一下玩具的各种成本,质量保证/验证证明,这些玩具只是希望具有确定性,无阻塞,无差错和可靠/有弹性的现场操作)

Beware : 谨防 :
ZeroMQ Socket() -instance is not a tcp-socket-as-you-know-it. ZeroMQ Socket()实例不是您所知道的tcp套接字。 Best read about the main conceptual differences in ZeroMQ hierarchy in less than a five seconds or other posts and discussions here . 最好在不到五秒钟的时间内阅读ZeroMQ层次结构中的主要概念差异,或在此处找到其他帖子和讨论

Context() -instances have their own I/O-thread-pools under their own domain-of-control, also having a "DMA"-alike mapper between a respective Context 's Socket() -instance permitted affinity to the respective Context 's (groups of) I/O-thread(s), so a global view on "pinning" may not affect the intended resource-mapping preferences. Context()实例在其自己的控制域下具有自己的I / O线程池,并且在相应ContextSocket() instance允许与各自的Context相似性之间也具有类似于“ DMA”的映射器的I / O线程(组),因此对“固定”的全局视图可能不会影响预期的资源映射首选项。


Last, but not least - Akka-port specific configurations , 最后但并非最不重要的-Akka端口特定的配置,
that do not match the ZeroMQ native API defaults : 与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
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM