Closed mschneider82 closed 6 years ago
Using write_to_socket
directly in def pub
instead of write
solves this issue and has a good speed increase! The problem must be the queue
https://github.com/wistia/nsq-ruby/blob/master/lib/nsq/connection.rb#L113
Thanks for the report and for doing some sleuthing on this @mschneider82! I should have some time later this week to dig in. And if you beat me to it and figure out the leak, happy to merge a PR ;)
@bschwartz we should do a discussion here if we really need a queue between write
& write_to_socket
without a queue it seems to be ~10x faster, but i don't know how this will affect if a connection may gets broken
Just found this note:
# For indicating that the connection has died. # We use a Queue so we don't have to poll. Used to communicate across # threads (from write_loop and read_loop to connect_and_monitor).
https://github.com/wistia/nsq-ruby/blob/master/lib/nsq/connection.rb#L60-L62
After some more tests i figured out that the input thread is much more faster than the output thread to the socket. Thats why messages are increasing to the internal Queue (in memory). I can produce 3.000.000 msgs in about 30secs, only 50.000 are passed through to nsqd and the rest is Queued in memory (and transfered to nsqd later).
I recommend a synchron write without a queue
In my tests SizedQueue
works like a charm, the push operation gets blocked if the Queue is full, I hardcoded size of 10.000 (same as nsqd in-memory). The 3.000.000 msgs gets pushed to nsqd in ~180secs
running this simple producer code will show that the memory of the process will increase continuously
consumer:
./nsq_tail --topic test#ephemeral --nsqd-tcp-address localhost:4150