-
-
Notifications
You must be signed in to change notification settings - Fork 883
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
Hot rank update batching + deadlock avoidance #3175
Conversation
4b4b433
to
68eab28
Compare
Great! But I think you have an issue with your query performance because you're filtering by a different column than you're ordering by. In order for your selects to be performant you have to filter and order by the same column and that column must be indexed. To verify, try running
I know I said you have to do deterministic ordering to fix deadlocks. But you can still do that after selecting, they only have to be ordered by comment_id within each bach. (I don't have an instance to verify what i'm saying, just looking at the code) |
68eab28
to
fe0b913
Compare
I pushed a new version.
The main benefit of doing it with a fixed batch size is that this approach will scale linearly with amount of comments, which I believe might be critically important for Lemmy going forward. Caveat: I unfortunately had to use Btw, thanks again to @phiresky for additional help! |
b39727e
to
426095c
Compare
b2737cb
to
a0eac8a
Compare
WHERE a.published > $1 | ||
ORDER BY a.published | ||
LIMIT $2 | ||
FOR UPDATE SKIP LOCKED) |
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.
Nice, had no idea about that one. I wonder if diesel has this available so we can use it on other scheduled jobs.
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.
Diesel has .for_update()
and .skip_locked()
, but they have at least one significan't limitation: they can't be used together with .into_boxed()
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.
Gotcha. @Nutomic would these be potentially useful in any apub jobs?
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.
This seems to be useful when using a table as a kind of job queue? Might be useful for #2142 once we implement that.
a0eac8a
to
b926eb2
Compare
b926eb2
to
8ee0e12
Compare
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.
Thanks a ton for this, this is gonna work so much better than what's currently there for bigger instances.
Ok(updated_rows) => previous_batch_result = updated_rows.last().map(|row| row.published), | ||
Err(e) => { | ||
error!("Failed to update {} hot_ranks: {}", table_name, e); | ||
break; |
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.
Should it really stop processing new batches if any one batch threw an error? Seems unnecessary.
This PR contains the following changes:
hot_rank_updated
column - we can use this to ensure that we process every row only once per each scheduled task run.comment_aggregates
and ~28k rows inpost_aggregates
for the last week. Updating hot ranks for all of them with batches of 5000 takes <30 seconds total. For comparison, with batches of 100, it took about 4 minutes. (It could be that on different hardware, different batch sizes may work better)I have been running this code (cherry-picked onto 0.17.4) live on lemm.ee for the past hour (starting from 05:15 on the graph below), and I have not seen a single deadlock since deploying these changes:
This should fix #3076.
Thanks to @phiresky for your input about all this here