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

vttablet: Hot Row Protection: Make the transaction concurrency for a hot row configurable. #3123

Merged
merged 4 commits into from
Sep 5, 2017

Conversation

michael-berlin
Copy link
Contributor

@michael-berlin michael-berlin commented Aug 29, 2017

By default, we will allow up to 5 transactions through to the tx pool to have a better pipelining effect and ensure that MySQL is always busy.

Sugu, I recommend to review this change one commit at a time. Some guidance:

  • Commit 1 is the code which you already reviewed internally.
  • Commit 2 adds an integration test (new).
  • Commit 3 changes the channel semantics from pull to push as you suggested during the internal code review.
  • Commit 4 defers the channel creation as an optimization.

row configurable.

By default, we will allow up to 5 transactions through to the tx pool to
have a better pipelining effect and ensure that MySQL is always busy.
concurrent transactions from pull to push.

Instead of pre-filling the channel with tokens, we will occupy one slot
in the channel only while our transaction is pending.

This way, we avoid the costly prepopulation of the channel with tokens.
…is a second transaction and the row actually becomes hot.

This saves 22% execution time for the default case that there is no hot row.

before:

$ go test -bench BenchmarkTxSerializer_NoHotRow -benchtime 30s
goos: darwin
goarch: amd64
BenchmarkTxSerializer_NoHotRow-4
100000000	       330 ns/op

after:

$ go test -bench BenchmarkTxSerializer_NoHotRow -benchtime 30s
goos: darwin
goarch: amd64
BenchmarkTxSerializer_NoHotRow-4
200000000	       257 ns/op

memstats before:
64 B/op	       2 allocs/op

memstats after:
160 B/op	     3 allocs/op


Note that this optimization is important for two reasons:
- The code is on the critical serving path i.e. every single vttablet request has to go through it.
- This code path has to use a global mutex which effectively serializes all requests and reduces the parallelism.

Given that, I think this optimization is justified.
Copy link
Contributor

@sougou sougou left a comment

Choose a reason for hiding this comment

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

I would have ideally liked to see benchmarks that this actually makes a difference, but I'll trust your instincts on this one :).

@michael-berlin
Copy link
Contributor Author

I did some internal benchmarks on this: In case of 100 concurrent transactions hitting the same row, I saw a 4% performance regression which went away with this fix.

In general, this fix makes sense: If we allow only a concurrency of 1, all transactions are stuck at a mutex in the vttablet code and not a MySQL mutex. I.e. when we unblock the transaction in vttablet, it takes time until it goes through the stack and is ready in MySQL. By having several transactions always ready in MySQL (I randomly picked a default of 5 here), we avoid this problem and have a pipelining effect.

@michael-berlin
Copy link
Contributor Author

I'm merging this now. unit_race keeps failing due to unrelated, flaky errors.

@michael-berlin michael-berlin merged commit 7084913 into vitessio:master Sep 5, 2017
@michael-berlin michael-berlin deleted the hotrow_concurrency branch September 5, 2017 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants