Skip to content
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

optimize migrator's executeWriteFuncs #1124

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

debug-LiXiwen
Copy link

A Pull Request should be associated with an Issue.

Description

  • Migrator's executeWriteFuncs will have a infinite loop when applyEventsQueue and copyRowsQueue is empty.
  • So I Optimize the priority logic to avoid the infinite loop

Change-Id: I54619b17d43ae4b26dad0977b78c611976a06de0
Copy link
Collaborator

@timvaillancourt timvaillancourt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting idea. I left a few review comments, thanks @debug-LiXiwen! 🙏

go/logic/migrator.go Outdated Show resolved Hide resolved
go/logic/migrator.go Outdated Show resolved Hide resolved
go/logic/migrator.go Outdated Show resolved Hide resolved
Change-Id: I89c4ec04fc28efcca6fc911eca51bfbcbff924b3
@timvaillancourt
Copy link
Collaborator

timvaillancourt commented Aug 21, 2022

@debug-LiXiwen thanks for the PR changes, it is passing CI now 👍

Now that the code looks good, I'm curious if you could explain what situations this optimizes?

If I understand correctly, this is the scenario this optimizes:

  1. case eventStruct := <-this.applyEventsQueue() returns empty (no events)
  2. Immediately after, events are added to the applier queue that were not seen by case in the last step
  3. The select moves on to case copyRowsFunc := <-this.copyRowsQueue(), which is NOT empty
  4. The new func this.drainApplierEventQueue() drains the events that appeared at step 2 (above)
    • On master today, the for loop would need to iterate again to catch the new applier events

Did I get this right and are there more scenarios?

The "window" for these events to appear above is extremely small. How likely is it that this scenario happens? Shouldn't the applier queue be empty by the time this.drainApplierEventQueue() is called? 🤔

Copy link
Collaborator

@timvaillancourt timvaillancourt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more requested change I noticed now

@debug-LiXiwen
Copy link
Author

  1. When the copyRowsQueue is not ready, you don't need to sleep manually, the select of the go language will be handled automatically
  2. When the copyRowsQueue is ready, logically analyze the new way of processing to achieve better prioritization, but I did not verify the effect in the actual scene

@timvaillancourt
Copy link
Collaborator

  1. you don't need to sleep manually, the select of the go language will be handled automatically

That's a good point, the time.Sleep() is a bit inefficient. Thanks for explaining 👍

Change-Id: Ic1c90803c4fe8a43d1192a65ca2d331364a50eab
Copy link
Collaborator

@timvaillancourt timvaillancourt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @dm-2 / @rashiq for more 👀

go/logic/migrator.go Show resolved Hide resolved
@dm-2
Copy link
Contributor

dm-2 commented Sep 6, 2022

Thanks for your contribution @debug-LiXiwen! 🙇

  1. When the copyRowsQueue is not ready, you don't need to sleep manually, the select of the go language will be handled automatically

I think relying on select to wait instead of using time.Sleep is a good idea as it makes the code easier to read. I don't think the performance difference will be significant, but I like that it makes the code flow better.

  1. When the copyRowsQueue is ready, logically analyze the new way of processing to achieve better prioritization, but I did not verify the effect in the actual scene

I think drainApplierEventQueue() is unnecessary and we should remove it. I understand the reason for this optimisation, but the benefit will be very small and it makes the code more complicated than necessary. I prefer that we keep the code as simple as possible, and only optimise when there's a demonstrated need.

@timvaillancourt
Copy link
Collaborator

I don't think the performance difference will be significant, but I like that it makes the code flow better.

Agreed, I think it's very unlikely this would improve performance for most workloads

I think drainApplierEventQueue() is unnecessary and we should remove it

I would be on board with this 👍. It's is incredibly unlikely there are new events to apply immediately after the select already checked the apply queue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants