Skip to content

Separate internal and user key comparators in BlockIter#6944

Closed
ajkr wants to merge 13 commits intofacebook:masterfrom
ajkr:refactor-block-iter-internal-vs-user-key
Closed

Separate internal and user key comparators in BlockIter#6944
ajkr wants to merge 13 commits intofacebook:masterfrom
ajkr:refactor-block-iter-internal-vs-user-key

Conversation

@ajkr
Copy link
Copy Markdown
Contributor

@ajkr ajkr commented Jun 5, 2020

Replace BlockIter::comparator_ and IndexBlockIter::user_comparator_wrapper_ with a concrete UserComparatorWrapper and InternalKeyComparator. The motivation for this change was the inconvenience of not knowing the concrete type of BlockIter::comparator_, which prevented calling specialized internal key comparison functions to optimize comparison of keys with global seqno applied.

Test Plan:

benchmark setup -- single file DBs, in-memory, no compression. "normal_db"
created by regular flush; "ingestion_db" created by ingesting a file. Both
DBs have same contents.

$ TEST_TMPDIR=/dev/shm/normal_db/ ./db_bench -benchmarks=fillrandom,compact -write_buffer_size=10485760000 -disable_auto_compactions=true -compression_type=none -num=1000000
$ ./ldb write_extern_sst ./tmp.sst --db=/dev/shm/ingestion_db/dbbench/ --compression_type=no --hex --create_if_missing < <(./sst_dump --command=scan --output_hex --file=/dev/shm/normal_db/dbbench/000007.sst | awk 'began {print "0x" substr($1, 2, length($1) - 2), "==>", "0x" $5} ; /^Sst file format: block-based/ {began=1}')
$ ./ldb ingest_extern_sst ./tmp.sst --db=/dev/shm/ingestion_db/dbbench/

benchmark run command:

$ TEST_TMPDIR=/dev/shm/$DB/ ./db_bench -benchmarks=seekrandom -seek_nexts=$SEEK_NEXT -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=0 -threads=1 -reads=200000000 -mmap_read=1 -verify_checksum=false

results: perf increased significantly for ingestion_db (enough to cover the losses in #6843) and changed negligibly for normal_db:

SEEK_NEXT DB code ops/sec % change
0 normal_db master 378879  
0 normal_db PR6944 376974 -0.5
0 ingestion_db master 357010  
0 ingestion_db PR6944 394068 10.4
10 normal_db master 235596  
10 normal_db PR6944 237640 0.9
10 ingestion_db master 216041  
10 ingestion_db PR6944 234371 8.5

@ajkr ajkr force-pushed the refactor-block-iter-internal-vs-user-key branch 3 times, most recently from fd10a11 to 2212f0b Compare June 7, 2020 23:55
Copy link
Copy Markdown
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ajkr has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@ajkr ajkr force-pushed the refactor-block-iter-internal-vs-user-key branch from 2212f0b to d3cdfd2 Compare June 27, 2020 00:52
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

@ajkr ajkr force-pushed the refactor-block-iter-internal-vs-user-key branch from d3cdfd2 to 4a01817 Compare June 30, 2020 02:52
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

1 similar comment
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

Copy link
Copy Markdown
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ajkr has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@pdillinger pdillinger assigned pdillinger and unassigned pdillinger Jun 30, 2020
@pdillinger pdillinger self-requested a review June 30, 2020 19:18
Copy link
Copy Markdown
Contributor

@pdillinger pdillinger left a comment

Choose a reason for hiding this comment

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

More review to come

@ajkr ajkr force-pushed the refactor-block-iter-internal-vs-user-key branch from 1667475 to c87dd92 Compare July 1, 2020 23:15
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

1 similar comment
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

Copy link
Copy Markdown
Contributor

@pdillinger pdillinger left a comment

Choose a reason for hiding this comment

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

LGTM! :)

I would request before landing: 'make check' under valgrind, and preemptively run stress test for a little while.

@pdillinger
Copy link
Copy Markdown
Contributor

Perf note in HISTORY.md also might be warranted. Up to you.

@ajkr ajkr force-pushed the refactor-block-iter-internal-vs-user-key branch from 76b413c to bdf25f3 Compare July 7, 2020 19:58
@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr has updated the pull request. Re-import the pull request

Copy link
Copy Markdown
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ajkr has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@ajkr
Copy link
Copy Markdown
Contributor Author

ajkr commented Jul 7, 2020

LGTM! :)

Thanks for the review!

I would request before landing: 'make check' under valgrind, and preemptively run stress test for a little while.

Done, ran:

$ make -j48 valgrind_test
$ python tools/db_crashtest.py blackbox --simple -write_buffer_size=1048576 -target_file_size_base=1048576 -max_bytes_for_level_base=4194304 -value_size_mult=33 -max_key=1000000 --duration=1200 --interval=20

Perf note in HISTORY.md also might be warranted. Up to you.

Done.

The test failure (e.g., ./librocksdb_stress_debug.so: undefined reference to alternative_rocksdb_ns::test::SetupSyncPointsToMockDirectIO()'`) looks unrelated.

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr merged this pull request in dd29ad4.

ajkr added a commit to ajkr/rocksdb that referenced this pull request Jul 20, 2020
PR facebook#6944 transitioned `BlockIter` from using `Comparator*` to using
concrete `UserComparatorWrapper` and `InternalKeyComparator`. However,
adding them as instance variables to `BlockIter` was not optimal.
Bloating `BlockIter` caused the `ArenaWrappedDBIter`'s arena allocator
to do more heap
allocations which harmed performance of `DB::NewIterator()`. This PR
pushes down the concrete comparator objects to the point of usage, which
forces them to be on the stack. As a result, the `BlockIter` is back to
its original size prior to facebook#6944 (actually a bit smaller since there
were two `Comparator*` before).

Test Plan: verified our internal `DB::NewIterator()`-heavy regression
test no longer reports regression.
facebook-github-bot pushed a commit that referenced this pull request Jul 20, 2020
Summary:
PR #6944 transitioned `BlockIter` from using `Comparator*` to using
concrete `UserComparatorWrapper` and `InternalKeyComparator`. However,
adding them as instance variables to `BlockIter` was not optimal.
Bloating `BlockIter` caused the `ArenaWrappedDBIter`'s arena allocator to do more heap
allocations (in certain cases) which harmed performance of `DB::NewIterator()`. This PR
pushes down the concrete comparator objects to the point of usage, which
forces them to be on the stack. As a result, the `BlockIter` is back to
its original size prior to #6944 (actually a bit smaller since there
were two `Comparator*` before).

Pull Request resolved: #7149

Test Plan:
verified our internal `DB::NewIterator()`-heavy regression
test no longer reports regression.

Reviewed By: riversand963

Differential Revision: D22623189

Pulled By: ajkr

fbshipit-source-id: f6d69accfe5de51e0bd9874a480b32b29909bab6
codingrhythm pushed a commit to SafetyCulture/rocksdb that referenced this pull request Mar 5, 2021
Summary:
PR facebook#6944 transitioned `BlockIter` from using `Comparator*` to using
concrete `UserComparatorWrapper` and `InternalKeyComparator`. However,
adding them as instance variables to `BlockIter` was not optimal.
Bloating `BlockIter` caused the `ArenaWrappedDBIter`'s arena allocator to do more heap
allocations (in certain cases) which harmed performance of `DB::NewIterator()`. This PR
pushes down the concrete comparator objects to the point of usage, which
forces them to be on the stack. As a result, the `BlockIter` is back to
its original size prior to facebook#6944 (actually a bit smaller since there
were two `Comparator*` before).

Pull Request resolved: facebook#7149

Test Plan:
verified our internal `DB::NewIterator()`-heavy regression
test no longer reports regression.

Reviewed By: riversand963

Differential Revision: D22623189

Pulled By: ajkr

fbshipit-source-id: f6d69accfe5de51e0bd9874a480b32b29909bab6
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.

3 participants