Skip to content

avoid IterKey::UpdateInternalKey() in BlockIter#6843

Closed
ajkr wants to merge 1 commit intofacebook:masterfrom
ajkr:refactor-data-block-global-seqno
Closed

avoid IterKey::UpdateInternalKey() in BlockIter#6843
ajkr wants to merge 1 commit intofacebook:masterfrom
ajkr:refactor-data-block-global-seqno

Conversation

@ajkr
Copy link
Copy Markdown
Contributor

@ajkr ajkr commented May 13, 2020

IterKey::UpdateInternalKey() is an error-prone API as it's
incompatible with IterKey::TrimAppend(), which is used for
decoding delta-encoded internal keys. This PR stops using it in
BlockIter. Instead, it assigns global seqno in a separate IterKey's
buffer when needed. The logic for safely getting a Slice with global
seqno properly assigned is encapsulated in GlobalSeqnoAppliedKey.
BinarySeek() is also migrated to use this API (previously it ignored
global seqno entirely).

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=10 -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=1048576000 -threads=1 -reads=40000000

results:

DB code throughput
normal_db master 267.9
normal_db PR6843 254.2 (-5.1%)
ingestion_db master 259.6
ingestion_db PR6843 250.5 (-3.5%)

@ajkr
Copy link
Copy Markdown
Contributor Author

ajkr commented May 13, 2020

There are a few next steps that were too hard to do all at once.

  1. migrate IndexBlockIter to use GlobalSeqnoAppliedKey for first_internal_key
  2. introduce a separate convenience class like IterKey for non-iterator keys. Currently IterKey is used in places unrelated to iteration/delta decoding (for example, GlobalSeqnoAppliedKey::scratch_).
  3. finish migrating everything away from IterKey::UpdateInternalKey() and then delete it.

But this PR should be enough to unblock #6646...

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 requested review from pdillinger and siying May 13, 2020 23:21
@ajkr ajkr force-pushed the refactor-data-block-global-seqno branch from 2a280ed to 50f8d5f Compare May 14, 2020 17:12
@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-data-block-global-seqno branch from 50f8d5f to 8f0dd79 Compare May 14, 2020 17:49
@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 ajkr force-pushed the refactor-data-block-global-seqno branch from 8f0dd79 to 9c3e78e Compare May 15, 2020 01:04
@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-data-block-global-seqno branch from 9c3e78e to cdd9c22 Compare May 15, 2020 15:37
@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 ajkr removed the request for review from siying May 20, 2020 17:35
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.

Still digging deeper in my understanding, but sharing this partial feedback

@ajkr ajkr force-pushed the refactor-data-block-global-seqno branch from cdd9c22 to 5cdb42d Compare May 21, 2020 16:12
@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.

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.

Maybe also run a seekrandom benchmark (without cache_index_and_filter_blocks) to see what kind of worst-case performance impact this has.

Copy link
Copy Markdown
Contributor Author

@ajkr ajkr left a comment

Choose a reason for hiding this comment

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

Thanks for the review!

Maybe also run a seekrandom benchmark (without cache_index_and_filter_blocks) to see what kind of worst-case performance impact this has.

Sure, will do.

@ajkr ajkr force-pushed the refactor-data-block-global-seqno branch from 5cdb42d to 82b2f26 Compare May 22, 2020 20:31
@facebook-github-bot
Copy link
Copy Markdown
Contributor

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

@ajkr
Copy link
Copy Markdown
Contributor Author

ajkr commented May 22, 2020

Maybe also run a seekrandom benchmark (without cache_index_and_filter_blocks) to see what kind of worst-case performance impact this has.

Sure, will do.

Added to the description. The results aren't that stable, but I do consistently see slowdown in both the "ingestion_db" and "normal_db" case. That is different from what I expected as I thought the main drawback of this PR was introducing a copy into GlobalSeqnoAppliedKey::scratch_ only in the "ingestion_db" case.

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.

I think we can accept minor perf regression to help bring some sanity to this part of the code.

@pdillinger
Copy link
Copy Markdown
Contributor

(I believe the CI failures are all unrelated. Do another rebase if you want.)

`IterKey::UpdateInternalKey()` is an error-prone API as it's
incompatible with `IterKey::TrimAppend()`, which is used for
decoding delta-encoded internal keys. This PR stops using it in
`BlockIter`. Instead, it assigns global seqno in a separate `IterKey`'s
buffer when needed. The logic for safely getting a Slice with global
seqno properly assigned is encapsulated in `GlobalSeqnoAppliedKey`.
`BinarySeek()` is also migrated to use this API (previously it ignored
global seqno entirely).

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=10 -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=1048576000 -threads=1 -reads=40000000
```

results:

DB	code	throughput
normal_db	master	267.9
normal_db	PR6843	254.2 (-5.1%)
ingestion_db	master	259.6
ingestion_db	PR6843	250.5 (-3.5%)
Copy link
Copy Markdown
Contributor

@yiwu-arbug yiwu-arbug left a comment

Choose a reason for hiding this comment

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

Thanks for the fix.

@ajkr ajkr force-pushed the refactor-data-block-global-seqno branch from 82b2f26 to 089f675 Compare May 28, 2020 02:03
@facebook-github-bot
Copy link
Copy Markdown
Contributor

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

@ajkr
Copy link
Copy Markdown
Contributor Author

ajkr commented May 28, 2020

Thanks for the review!

I think we can accept minor perf regression to help bring some sanity to this part of the code.

The "normal_db" regression can be avoided if we change UpdateAndGetKey() to assume it holds non-ingested keys (i.e., if (global_seqno_ == kDisableGlobalSequenceNumber) -> if (LIKELY(global_seqno_ == kDisableGlobalSequenceNumber))). It's not obvious to me we should do that so I'll leave it as is for now.

The "ingestion_db" regression is due to the extra copy into GlobalSeqnoAppliedKey::scratch_ that can only be avoided by comparing against ParsedInternalKey. More refactoring is necessary first.

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.

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ajkr merged this pull request in c5abf78.

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

@ajkr merged this pull request in c5abf78.

yiwu-arbug pushed a commit to tikv/rocksdb that referenced this pull request Jun 4, 2020
…175)

Summary:
`IterKey::UpdateInternalKey()` is an error-prone API as it's
incompatible with `IterKey::TrimAppend()`, which is used for
decoding delta-encoded internal keys. This PR stops using it in
`BlockIter`. Instead, it assigns global seqno in a separate `IterKey`'s
buffer when needed. The logic for safely getting a Slice with global
seqno properly assigned is encapsulated in `GlobalSeqnoAppliedKey`.
`BinarySeek()` is also migrated to use this API (previously it ignored
global seqno entirely).
Pull Request resolved: facebook#6843

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=10 -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=1048576000 -threads=1 -reads=40000000
```

results:

| DB | code | throughput |
|---|---|---|
| normal_db | master |  267.9 |
| normal_db   |    PR6843 | 254.2 (-5.1%) |
| ingestion_db |   master |  259.6 |
| ingestion_db |   PR6843 | 250.5 (-3.5%) |

Reviewed By: pdillinger

Differential Revision: D21562604

Pulled By: ajkr

fbshipit-source-id: 937596f836930515da8084d11755e1f247dcb264
Signed-off-by: Yi Wu <yiwu@pingcap.com>

Co-authored-by: Andrew Kryczka <andrewkr@fb.com>
yiwu-arbug pushed a commit to tikv/rocksdb that referenced this pull request Jun 4, 2020
…174)

Summary:
`IterKey::UpdateInternalKey()` is an error-prone API as it's
incompatible with `IterKey::TrimAppend()`, which is used for
decoding delta-encoded internal keys. This PR stops using it in
`BlockIter`. Instead, it assigns global seqno in a separate `IterKey`'s
buffer when needed. The logic for safely getting a Slice with global
seqno properly assigned is encapsulated in `GlobalSeqnoAppliedKey`.
`BinarySeek()` is also migrated to use this API (previously it ignored
global seqno entirely).
Pull Request resolved: facebook#6843

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=10 -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=1048576000 -threads=1 -reads=40000000
```

results:

| DB | code | throughput |
|---|---|---|
| normal_db | master |  267.9 |
| normal_db   |    PR6843 | 254.2 (-5.1%) |
| ingestion_db |   master |  259.6 |
| ingestion_db |   PR6843 | 250.5 (-3.5%) |

Reviewed By: pdillinger

Differential Revision: D21562604

Pulled By: ajkr

fbshipit-source-id: 937596f836930515da8084d11755e1f247dcb264
Signed-off-by: Yi Wu <yiwu@pingcap.com>

Co-authored-by: Andrew Kryczka <andrewkr@fb.com>
yiwu-arbug pushed a commit to tikv/rocksdb that referenced this pull request Jun 4, 2020
…173)

Summary:
`IterKey::UpdateInternalKey()` is an error-prone API as it's
incompatible with `IterKey::TrimAppend()`, which is used for
decoding delta-encoded internal keys. This PR stops using it in
`BlockIter`. Instead, it assigns global seqno in a separate `IterKey`'s
buffer when needed. The logic for safely getting a Slice with global
seqno properly assigned is encapsulated in `GlobalSeqnoAppliedKey`.
`BinarySeek()` is also migrated to use this API (previously it ignored
global seqno entirely).
Pull Request resolved: facebook#6843

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=10 -use_existing_db=true -cache_index_and_filter_blocks=false -num=1000000 -cache_size=1048576000 -threads=1 -reads=40000000
```

results:

| DB | code | throughput |
|---|---|---|
| normal_db | master |  267.9 |
| normal_db   |    PR6843 | 254.2 (-5.1%) |
| ingestion_db |   master |  259.6 |
| ingestion_db |   PR6843 | 250.5 (-3.5%) |

Reviewed By: pdillinger

Differential Revision: D21562604

Pulled By: ajkr

fbshipit-source-id: 937596f836930515da8084d11755e1f247dcb264
Signed-off-by: Yi Wu <yiwu@pingcap.com>

Co-authored-by: Andrew Kryczka <andrewkr@fb.com>
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.

4 participants