Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Doctrine][Messenger] Make the messenger doctrine transport scalable#50972

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
hgraca wants to merge11 commits intosymfony:6.4fromhgraca:scalable_doctrine_transport

Conversation

hgraca
Copy link

QA
Branch?6.4
Bug fix?no
New feature?yes
Deprecations?no
TicketsFix#47828
LicenseMIT
Doc PRsymfony/symfony-docs#18566

Relevant changes

This PR has a few commits with small improvements and two commits with relevant changes.

Here are the most significant changes:

Replacement and removal of the DoctrineReceivedStamp

It seems to be redundant because there is already another stamp there being used for the same purpose. Thus, in a commit I replace its usage and in the other commit I remove it. This might be considered a breaking change because the DoctrineReceivedStamp is not marked final, Im not sure, you tell me, these commits can be easily dropped without impact to the rest :)

Add "SKIP LOCKED" to the Mysql8 and Postgres query that retrieves messages

The currentSELECT ... FOR UPDATE retrieves rows, using the index to find
and lock the retrieved rows.
This means that when we have more than one consumer, while
one consumer is locking those rows, the whole index is locked thus
other queries (consumers) will be put on hold.
While with a small table this might not be noticeable, as the table
grows the meddling with the index becomes slower and the other
consumers have to wait more time, eventually making the MQ inoperable.

TheSKIP LOCKED addition will allow other consumers to query the
table and get messages immediately, ignoring the rows that other
consumers are locking.

Add batch delivery

Currently, the doctrine transport only delivers one message at a time,
resulting in low performance and a very high amount of hits to the DB.
(one hit per message)

With batch delivery, the transport will retrieve several messages in a single query.

Testing

I adjusted the tests, and added a few more cases.

I also tested this in a playground project, sending and receiving 400000 asynchronous messages, which were handled by 2 worker containers, each with 2 consumers.
All messages were processed and there were no duplicates.
These tests were done with mysql, postgres and mssql.

Maria DB was not updated with theSKIP LOCKED because the engine version that supports it, is not yet supported by Doctrine.

Oracle was not updated withSKIP LOCKED either because I could not even connect to the damn thing using my db client.

jamesisaac reacted with thumbs up emoji
Herberto Gracaand others added7 commitsJuly 9, 2023 23:13
This allows for projects to set up the messengerconfig using this constant, making it deterministic,and therefore less prone to errors.
We already have the TransportMessageIdStamp, so theDoctrineReceivedStamp is redundant, as it contains the same dataand its usage is semantically more correct by using theTransportMessageIdStamp.
The current `SELECT ... FOR UPDATE` retrieves rows, using the index tofind and lock the retrieved rows.This means that when we have more than one consumer, whileone consumer is locking those rows, the whole index is locked thusother queries (consumers) will be put on hold.While with a small table this might not be noticeable, as the tablegrows the meddling with the index becomes slower and the otherconsumers have to wait more time, eventually making the MQ inoperable.The `SKIP LOCKED` addition will allow other consumers to query thetable and get messages immediately, ignoring the rows that otherconsumers are locking.Co-authored-by: Alexander Malyk <shu.rick.ifmo@gmail.com>
Currently, the doctrine transport only delivers one message at a time,resulting in low performance and a very high amount of hits to the DB.(one hit per message)With batch delivery, the transport will retrieve several messagesin a single query.Co-authored-by: Alexander Malyk <shu.rick.ifmo@gmail.com>
@carsonbotcarsonbot changed the titleMake the messenger doctrine transport scalable[Doctrine][Messenger] Make the messenger doctrine transport scalableJul 14, 2023
@derrabus
Copy link
Member

Thank you very much for this PR.

This PR has a few commits with small improvements and two commits with relevant changes.

I think, this should've been three PRs. Because you've changed multiple aspects of the Doctrine transport, the review might take a while. Smaller isolated changes are usually easier to review.

Replacement and removal of the DoctrineReceivedStamp

It seems to be redundant because there is already another stamp there being used for the same purpose. Thus, in a commit I replace its usage and in the other commit I remove it. This might be considered a breaking change because the DoctrineReceivedStamp is not marked final, Im not sure, you tell me, these commits can be easily dropped without impact to the rest :)

Changing the stamps that the transport attaches to the message is a breaking change. If you can split this into a separate PR, please do that and we discuss the change there.

Add "SKIP LOCKED" to the Mysql8 and Postgres query that retrieves messages

Very nice. I wonder if it makes sense to contribute support forSKIP LOCKED to DBAL. This kind of query manipulation feels like it belongs there.

Add batch delivery

Do we have other transports that support batches? Would it makes sense to generalize this feature?

Maria DB was not updated with theSKIP LOCKED because the engine version that supports it, is not yet supported by Doctrine.

And what version would that be? DBAL supports all MariaDB versions since 10.0, up to 11.0 currently.

Oracle was not updated withSKIP LOCKED either because I could not even connect to the damn thing using my db client.

😄

@hgraca
Copy link
Author

Hi@derrabus tkx for the review.

I think, this should've been three PRs.

How would you separate the commits per PR?
Would this

1. Add DoctrineTransportFactory DSN_PREFIX constant Add type hint for $driverConnection in DoctrineTransportFactoryEnsure messages flagged for deletion have clear flag 2.Replace usage of DoctrineReceivedStampRemove the unused DoctrineReceivedStamp3.Add "SKIP LOCKED" to the query that retrieves messages4.Add batch delivery

make sense?

Changing the stamps that the transport attaches to the message is a breaking change. If you can split this into a separate PR, please do that and we discuss the change there.

Will do

I wonder if it makes sense to contribute support for SKIP LOCKED to DBAL.

Yes, I believe it makes sense, I was eager to get this functionality in the messenger though.
Do you want me to do that update in DBAL first?

Do we have other transports that support batches? Would it makes sense to generalize this feature?

The transport was already prepared for this, cozz theReceiverInterface::get(): iterable; returns an iterable (batch of messages), and it was in fact returning[Envelope] and then consumer is handling all envelopes in the array, so I guess it is already the case that it is generalised, just the doctrine transport was not making use of it.

And what version would that be? DBAL supports all MariaDB versions since 10.0, up to 11.0 currently.

The SKIP LOCKED clause was introduced in MariaDB 10.6.0, but DBAL supports from10.2.7 GA and there's no way to choose a higher version (AFAIK) so I assumed we needed to support the lowest version.
Let me know if that is not the case and I can add support for MariaDB.

@derrabus
Copy link
Member

I think, this should've been three PRs.

How would you separate the commits per PR? Would this

We usually squash PRs before merging. Since you deliver multiple features with this PR, multiple PRs would make it easier to discuss the implementation of one feature without blocking the merge of another feature.

I wonder if it makes sense to contribute support for SKIP LOCKED to DBAL.

Yes, I believe it makes sense, I was eager to get this functionality in the messenger though. Do you want me to do that update in DBAL first?

Since we're targeting 6.4 which is due in November, we're not in a hurry. If you have an idea how to contribute this to DBAL, please go ahead.

I guess it is already the case that it is generalised, just the doctrine transport was not making use of it.

I know, but unless I've missed something, this PR would be the first that makes the batch size configurable. But that was just an idea/observation from my side. We can go with your approach and think about generalizing that functionality later.

DBAL supports from10.2.7 GA and there's no way to choose a higher version (AFAIK)

DBAL does not introduce new platform classes unless they're needed. DBAL 3.7 will ship new ones for MariaDB, but still not the one you need. You can query the database version from the connection though. However, the fact that you'll need a new versioned platform class probably indicates that adding that feature to DBAL is a good idea.

@hgraca
Copy link
Author

@derrabus
Cool, I will break this up in separate PRs, open a PR in DBAL and when that's merged I will open the PR for theSKIP LOCKED commit here.

@hgracahgraca closed thisJul 19, 2023
@hgraca
Copy link
Author

Opened up this PR
#51034

The others will follow up after the DBAL PR is merged

@hgracahgraca deleted the scalable_doctrine_transport branchJuly 27, 2023 08:52
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Projects
None yet
Milestone
6.4
Development

Successfully merging this pull request may close these issues.

[Messenger] Bad performances with the Doctrine/MySQL transport
3 participants
@hgraca@derrabus@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp