-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Documented redis consumer group relation #11869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -623,6 +623,32 @@ config and start your workers: | |
|
||
See the `Supervisor docs`_ for more details. | ||
|
||
|
||
.. tip:: | ||
|
||
To get a deterministic worker name like for e.g. the Redis transport, you may pass the process number as an | ||
environment variable. | ||
|
||
.. code-block:: ini | ||
|
||
;/etc/supervisor/conf.d/messenger-worker.conf | ||
[program:messenger-consume] | ||
[…] | ||
environment = REDIS_CONSUMER=consumer-%(process_num)d | ||
|
||
You can then use it in your messenger configuration: | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: yaml | ||
|
||
# config/packages/messenger.yaml | ||
framework: | ||
messenger: | ||
transports: | ||
redis: 'redis://localhost:6379/messages/symfony/%env(REDIS_CONSUMER)%' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wound use a transport value like this. I would have that in an environment variable, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I don't understand your question here, can you elaborate maybe? 😊 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @Nyholm meant that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is in the code block just before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Nyholm What I did is: I added the line |
||
|
||
|
||
.. _messenger-retries-failures: | ||
|
||
Retries & Failures | ||
|
@@ -900,6 +926,40 @@ serializer How to serialize the final payload ``Redis::SERIALIZER_PHP` | |
``Redis::OPT_SERIALIZER`` option) | ||
================== =================================== ======= | ||
|
||
.. tip:: | ||
|
||
At some point you'll likely want to scale the number of workers working on your queue. | ||
Make sure you assign the correct ``consumer`` and ``group`` values in that case. | ||
The more likely case is that you want every worker to work on the queue independently, reducing | ||
Toflar marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it likely?
I just googled about redis stream and their consumer groups. Maybe a link to redis docs should be added here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I was hesitant getting too much into how Redis streams work because that's already documented in the Redis docs (e.g. https://redis.io/topics/streams-intro). Actually that's the first link you get when you google for
Why scaling is likely? If one worker was enough, a simple database queue would probably be enough. I don't think one would choose Redis if the load wasn't bigger :) |
||
the time needed to process the pending messages. In that case, every single worker | ||
must have a different ``consumer`` option value so Redis can identify the different workers. | ||
Your workers should thus be configured e.g. as follows: | ||
|
||
* Worker 1: redis://localhost:6379/messages/symfony/consumer-1 | ||
* Worker 2: redis://localhost:6379/messages/symfony/consumer-2 | ||
* Worker 3: redis://localhost:6379/messages/symfony/consumer-3 | ||
* […] | ||
|
||
The less likely case would be if you wanted to have every single worker to process every single message. | ||
That means messages would be processed multiple times. In that case, you must have different ``group`` | ||
configurations: | ||
|
||
* Worker 1: redis://localhost:6379/messages/symfony-1/consumer | ||
* Worker 2: redis://localhost:6379/messages/symfony-2/consumer | ||
* Worker 3: redis://localhost:6379/messages/symfony-3/consumer | ||
* […] | ||
|
||
.. caution:: | ||
|
||
Be careful about the ``consumer`` and ``group`` names you choose. It might be tempting to use e.g. the ``HOSTNAME`` | ||
environment variable in orchestrated, containerized environments (Docker Swarm, Kubernetes, etc.) to get a unique | ||
host name. However, they usually contain a random unique identifier which means if you destroy a container while it was | ||
working on a message, this message will remain in pending state forever as it is very unlikely there's ever going | ||
to be another worker with exactly the same ``HOSTNAME`` as the one you destroyed. In other words, you have to | ||
make sure you're using deterministic values such as ``worker-1``, ``worker-2`` etc. | ||
In case you are using Kubernetes to orchestrate your containers, consider using a ``StatefulSet`` rather than | ||
a ``Deployment`` for example. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let’s shorten this :). These cautions are great for the few people who have this case, but they tend to “weigh down” the docs over time. I think adding a comment in the code blocks above might be enough:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This caution block can be removed since abandoned messages are now claimed: symfony/symfony#35384 |
||
|
||
In Memory Transport | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I miss information why I would like to do this.
We do this to leverage the Redis stream "consumer group" feature, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. To me the why doesn't really matter here. It's just a tip and as we're in the Subervisor section here I don't want to get specific about Redis. I'm sure there are other use cases where you may want to set an environment variable.