ZeroMQ多线程:按需创建套接字还是使用套接字对象池? [英] ZeroMQ multithreading: create sockets on-demand or use sockets object pool?

查看:107
本文介绍了ZeroMQ多线程:按需创建套接字还是使用套接字对象池?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在利用ZeroMQ N对N的发布/订阅模型构建POC。从我们的应用服务器,当响应http请求时,如果线程从数据库中提取数据,它将使用该数据更新本地内存缓存实例。为了同步应用服务器集群中的其他Memcache实例,请求线程使用ZMQ发布者将消息与数据一起发送...因此问题是:关于最小化套接字,哪种策略最有效当应用程序具有许多依赖套接字发送消息的线程时,是否会创建/存储开销?我们是否共享一个套接字池,是否为每个线程创建/销毁套接字,等等?

I'm building a POC leveraging ZeroMQ N-to-N pub/sub model. From our app server, when a http request is serviced, if the thread pulls data from the database, it updates a local memcache instance with that data. To synchronize other memcache instances in the app server cluster, the request thread sends a message with the data using a ZMQ publisher...so the question is: What strategy is the most effective with respect to minimizing socket create/destory overhead when the application has many threads that depend on sockets for sending messages? Do we share a pool of sockets, do we create/destroy sockets per thread, etc?

策略1-线程管理的发布者套接字 < br>
在这种方法中,每个线程 T1 T2 T3 ,通过创建套接字对象(发布者),建立连接,发送消息并最终关闭套接字来管理其生命周期。基于,它当然是最安全的方法,但是我们担心创建,连接和创建套接字时的开销屡遭破坏;如果开销对性能有负面影响,我们希望避免。

Strategy 1 - Thread-managed Publisher Socket
In this approach, each thread, T1, T2, and T3, manages the lifecycle of a socket object (publisher) by creating it, making the connection, sending a message, and finally closing the socket. Based on this, it's certainly the safest approach, but we have concerns with respect to overhead when sockets are created, connected, and destroyed repeatedly; if the overhead negatively impacts performance, we'd like to avoid it.

策略2-发布者套接字对象池

父进程(应用服务器)在启动时初始化ZMQ发布者池。当线程需要发布者时,它从对象池中获取一个,然后发送其消息,然后将发布者返回到该池中。与使用发布者的线程相比,创建,连接和销毁套接字的过程被省去了,但是对池的访问被同步,以避免任何两个线程同时使用同一发布者对象,并且

Strategy 2 - Publisher Sockets Object Pool
In this approach, the parent process (app server) initializes a pool of ZMQ publishers on startup. When a thread needs a publisher, it gets one from the object pool, sends its message, then returns the publisher to the pool; the process of creating, connecting and destroying sockets is eliminated with respect to the thread using the publisher, but access to the pool is synchronized to avoid any two threads using the same publisher object at the same time, and this is where deadlocks and concurrency issues may arise.

我们没有介绍这两种方法,因为想先对SO测试进行测试。关于数量,我们的应用程序不会大量发布,但是可能同时有100-150个线程(每个应用程序服务器)之间,需要发布消息。

We have not profiled either approach because wanted to do a litmus on SO test first. With respect to volume, our application in not publish "heavy", but there could be between 100-150 threads (per app server) at the same time with the need to publish a message.

因此,重申一下:在应用程序具有许多依赖发布者来发送消息的线程的情况下,在最大程度地减少开销,同时强调性能方面,哪种策略最有效

推荐答案

如果不提供估计吞吐量的真实数字,您就无法真正提出有关性能的问题。我们在谈论每秒10个请求,100、1,000、10K吗?

You can't really ask a question about performance without providing real figures for your estimated throughput. Are we talking about 10 requests per second, 100, 1,000, 10K?

如果HTTP服务器确实为每个请求创建和销毁线程,那么反复创建0MQ套接字将强调操作系统,并取决于请求的数量和您的流程限制,它会起作用,或者会用完所有句柄。您可以对此进行简单的测试,这就是第一步。

If the HTTP server is really creating and destroying threads for each request, then creating 0MQ sockets repeatedly will stress the OS and depending on the volume of requests and your process limits, it'll work, or it'll run out of handles. You can test this trivially and thats a first step.

然后,共享一个套接字池(您指的是 ZMQ发布者)很讨厌。人们这样做,但是套接字不是 线程安全的,因此在将套接字切换到另一个线程时,要非常小心。

Then, sharing a pool of sockets (what you mean by "ZMQ publisher") is nasty. People do this but sockets are not threadsafe so it means being very careful when you switch a socket to another thread.

如果有办法为了保持线程的持久性,那么每个人都可以根据需要创建其PUB套接字,并在存在时一直保持下去。如果没有,那么我的第一个设计无论如何都会创建/销毁套接字,但是使用inproc://将消息发送到单个永久转发器线程(SUB-PUB代理)。我会测试一下,然后如果它崩溃了,那就去做更多奇特的设计。

If there is a way to keep the threads persistent then each one can create its PUB socket if it needs to, and hold onto it as long as it exists. If not, then my first design would create/destroy sockets anyhow, but use inproc:// to send messages to a single permanent forwarder thread (a SUB-PUB proxy). I'd test this and then if it breaks, go for more exotic designs.

总的来说,最好是制作最简单的设计并打破它,而不是过度考虑设计过程(尤其是刚开始时)。

In general it's better to make the simplest design and break it, than to over-think the design process (especially when starting out).

这篇关于ZeroMQ多线程:按需创建套接字还是使用套接字对象池?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆