0

I am working on a project where in I am using single zmq_push socket in multiple threads where each thread continuously send packets. On the other side I have single Zmq_Pull socket which keeps on receiving....I want this process to be faster, my application that is sending the packets thru zmq push is fast, but I doubt that my reception is faster or not....And one more thing each thread sending data is unique one, based in each thread data, I process in different thread on receiver side....how to make this process faster. I believe instead of looping on each packet on recv end I need this to done separately for each thread...Any answers on how to do this?

2 Answers2

0

To give your receiver side more throughput add multiple PULL sockets each with its own thread or own process

Then create a zmq_proxy process with PULL and PUSH sockets. This is very simple and just a few lines of code http://api.zeromq.org/4-3:zmq-proxy

  • Senders will connect to the PULL socket of the proxy
  • Receiver will connect to the PUSH socket of the proxy
  • The load will be balanced in a very simple round robin scheme.
+----------+     +----------+        +----------+      +----------+
|          |     |          |        |          |      |          |
| PUSH     |     | PUSH     |        | PUSH     |      | PUSH     |
|          |     |          |        |          |      |          |
+------+---+     +---------++        +-+--------+      +--+-------+
       |                   |           |                  |
       |                   |           |                  |
       |                   |           |                  |
       |                   |           |                  |
       |                   |           |                  |
       |                   |           |                  |
       |                   v           v                  |
       |                                                  |
       |                   +------------+                 |
       |                   |            |                 |
       +-----------------> |   PULL     | <---------------+
                           |            |
                           +------------+
                           |   zmq_proxy|
                           +------------+
                           |     PUSH   |
      +--------------------+            +----------------+
      |                    +-----+------+                |
      |                          |                       |
      |                          |                       |
      |                          |                       |
      |                          |                       |
      |                          |                       |
+-----v----+               +-----v----+              +---v------+
|          |               |          |              |          |
|  PULL    |               |  PULL    |              |  PULL    |
|          |               |          |              |          |
+----------+               +----------+              +----------+


NOTE: If you want more intellegent load balancing you will need to use sockets that provide feedback like ROUTER/DEALER. http://zguide.zeromq.org/page:all#The-Load-Balancing-Pattern

James Harvey
  • 912
  • 4
  • 6
  • I am doing that for my each thread...Here, the main problem I am facing is the speed..I am unable to cope up with the speed that my application is sending packets .. And I think single recv is not enough – Shailendra Patil Jul 01 '19 at 15:24
  • Here at a single point of time.. There are 100 thread with 100 zmq sockets connecting to a single zmq pull socket – Shailendra Patil Jul 01 '19 at 15:28
  • @ShailendraPatil I have updated my answer above based on your feedback of the receive side having a single socket/thread – James Harvey Jul 03 '19 at 08:57
  • With all due respect for the above views, **the PROXY-node**, both its PULL and PUSH sides, **represent an awful performance devastating singularity**, not speaking about processing resources, about memory resources, about adding any - if possible at all- failure-resilience strategy for making an intended service become somewhat more robust in real-world operations. If the OP's **primary goal was The Performance** ( and being that already indicated to be a problem ), adding similar "central-root-cause" of even more performance-related problems does not lead the OP towards a better solution. – user3666197 Jul 03 '19 at 18:16
  • The diagram is a simplistic view of a system that scales horizontally (more proxies, more nodes) for performance. – James Harvey Jul 04 '19 at 08:30
  • One more thing....On my application side each thread spawns a zmq_push socket with 100 as HWM....Now, as I can have 100 threads on my application side...What should be the HWM for pull socket on receiving side...Assuming I use only 1 pull socket....I have context threads set as 3 on my application side and each thread uses the same context to spawn a push socket...So what should be the context threads on my receiving side and HWM set on receiving side considering only 1 pull socket??? – Shailendra Patil Jul 04 '19 at 12:21
  • The HWM is just the number of messages that can be in the queue before loss (or blocking on send side) happens. I would set as high as you can on the recv side but keep an eye on memory usage. Try with one context thread on the recv side, that is more efficient. If you see the zmq context thread hitting 100% then you could increase but it should be good for at least 1Gb/s. – James Harvey Jul 04 '19 at 12:40
  • In case you don't mind...I am facing one more problem and this is related to RTP streams ...I have added question in the below link – Shailendra Patil Jul 04 '19 at 14:18
  • https://stackoverflow.com/questions/56873563/rtp-stream-synchronization – Shailendra Patil Jul 04 '19 at 14:18
  • If possible can you guide me on this? – Shailendra Patil Jul 04 '19 at 14:18
  • Sorry not sure about your RTP streams question, but if you think the answer I gave for this question is helpful the click the up arrow – James Harvey Jul 04 '19 at 15:28
  • Hi James, I am facing a problem, where in the last packet is not arriving on my recv socket. This happens very rarely , but I want to know as why this happens. In my program after sending the last message I call zmq_destroy and then zmq_close, I have send buff as 100 and recv buff as also 100. On the sender side there are many sockets( close to 150 - 200 sockets ) sending data to receiver. So, what can I improve in this so that I get all my messages, I am using PUSH PULL pattern. I feel that as I call destroy and close after sending last packet this is leading to the probelm....Any suggestion? – Shailendra Patil Jul 21 '19 at 07:10
  • try setting the socket option ZMQ_IMMEDIATE for the PUSH sockets to 1. You may have an issue with messages being sent to non incomplete connections on shutdown – James Harvey Aug 05 '19 at 09:49
0

Q: how to make this process faster?
A: We need both COMMUNICATIONs and PROCESSING faster

If you feel the ZeroMQ concept is new to you and might be a bit tricky to master for your future work, you may like to review the key concept features in this [ The principles of the ZeroMQ hierarchy in less than a five seconds ]

a) one can always improve the Communications-related processing capacities with instantiating the core-engine's Context( nIoTHREADs ) having nIoTHREADs >> 1

b) one may, upon a technically verified need, make each processing-thread off-loaded by a quite efficiently designed local inter-process messaging infrastructure ( to off-load communications from a thread-specific processing ) using a protocol-stack-less inproc:// communication channel from each processing-thread to the "central"-data-pumping Communicator ( Context-instance(s) may be shared among threads, while Socket-instances may not - this is the ZeroMQ Zen-of-Zero, by design ). This way each processing-thread does not block or isolate valuable resources thus made available for higher capacities of the "central"-data-pumping Communicator and may "delegate" communications related parts of the workload to the "central"-data-pump, using the lightmost send-and-forget philosophy in the processing-threads, while allowing the Communicator to handle and manage all potential smart-features, like app-level ACK/NACK signalling for dropped messages, on-the-fly service capacity scaling and many similar features each performance tuning engineer will love to have.

c) one may, upon technically indicated need, increase the performance of the receiving side ( the PULL-side ) by using a pool of PULL-receivers and make the PUSH-er side to simply .connect() to each of 'em. The internal mechanics of the PUSH-side Context-instance will need well oiled ( well parametrised ) configuration for multiple outgoing IO-channels, yet, if the remote-side PULL-ers' processing performance was the blocker, this increased and scalable pool-capacity is the way to go - sure, obviously not in the case when the PULL-side resources are already collocated on the same hardware-node with the senders, both being already at the ceiling of available processing powers ( The ZeroMQ way of thinking is always going rather distributed, than collocating processing agents on the single local hardware/OS - that is the freedom of the Zen-of-Zero evangelisation and the basis for almost linear performance scalability ).

user3666197
  • 1
  • 6
  • 50
  • 92