Skip to content

Conversation

@baohe-zhang
Copy link

What changes were proposed in this pull request?

The idea is to improve the performance of HybridStore by adding batch write support to LevelDB. #28412 introduces HybridStore. HybridStore will write data to InMemoryStore at first and use a background thread to dump data to LevelDB once the writing to InMemoryStore is completed. In the comments section of #28412 , @mridulm mentioned using batch writing can improve the performance of this dumping process and he wrote the code of writeAll().

Why are the changes needed?

I did the comparison of the HybridStore switching time between one-by-one write and batch write on an HDD disk. When the disk is free, the batch-write has around 25% improvement, and when the disk is 100% busy, the batch-write has 7x - 10x improvement.

when the disk is at 0% utilization:

log size, jobs and tasks per job original switching time, with write() switching time with writeAll()
133m, 400 jobs, 100 tasks per job 16s 13s
265m, 400 jobs, 200 tasks per job 30s 23s
1.3g, 1000 jobs, 400 tasks per job 136s 108s

when the disk is at 100% utilization:

log size, jobs and tasks per job original switching time, with write() switching time with writeAll()
133m, 400 jobs, 100 tasks per job 116s 17s
265m, 400 jobs, 200 tasks per job 251s 26s

I also ran some write related benchmarking tests on LevelDBBenchmark.java and measured the total time of writing 1024 objects. The tests were conducted when the disk is at 0% utilization.

Benchmark test with write(), ms with writeAll(), ms
randomUpdatesIndexed 213.06 157.356
randomUpdatesNoIndex 57.869 35.439
randomWritesIndexed 298.854 229.274
randomWritesNoIndex 66.764 38.361
sequentialUpdatesIndexed 87.019 56.219
sequentialUpdatesNoIndex 61.851 41.942
sequentialWritesIndexed 94.044 56.534
sequentialWritesNoIndex 118.345 66.483

Does this PR introduce any user-facing change?

No

How was this patch tested?

Manually tested.

@baohe-zhang
Copy link
Author

cc @HeartSaVioR @mridulm @tgravescs ^^

@baohe-zhang baohe-zhang changed the title [SPARK-32350] Add batch-write on LevelDB to improve performance of HybridStore [SPARK-32350][CORE] Add batch-write on LevelDB to improve performance of HybridStore Jul 17, 2020

try (WriteBatch batch = db().createWriteBatch()) {
while (valueIter.hasNext()) {
final Object value = valueIter.next();
Copy link
Contributor

Choose a reason for hiding this comment

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

Adding one value (L204-L219) looks to be same with write() - let's extract and deduplicate.

Copy link
Author

Choose a reason for hiding this comment

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

Done

while (it.hasNext()) {
levelDB.write(it.next())
}
val values = Lists.newArrayList(
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be OK, given all entries are from inMemoryStore which are already materialized into memory.

Copy link
Contributor

@HeartSaVioR HeartSaVioR left a comment

Choose a reason for hiding this comment

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

Looks OK in general. Just a minor comment. I'd like to wait for others to review as well if it doesn't hold too long.

@HeartSaVioR
Copy link
Contributor

ok to test

@HeartSaVioR
Copy link
Contributor

add to whitelist

@SparkQA
Copy link

SparkQA commented Jul 19, 2020

Test build #126130 has finished for PR 29149 at commit a12e178.

  • This patch fails PySpark pip packaging tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Jul 19, 2020

Test build #126129 has finished for PR 29149 at commit a12e178.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@HeartSaVioR
Copy link
Contributor

@mridulm @tgravescs
I'm planning to merge this in tomorrow. Please comment if you'd like to have time to review. Thanks!

@tgravescs
Copy link
Contributor

I likely won't have time for a review so go ahead without mine

@HeartSaVioR
Copy link
Contributor

OK I'll go ahead merging. To be sure I'll trigger test once again.

@HeartSaVioR
Copy link
Contributor

retest this, please

@SparkQA
Copy link

SparkQA commented Jul 21, 2020

Test build #126278 has finished for PR 29149 at commit a12e178.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@HeartSaVioR
Copy link
Contributor

retest this, please

@SparkQA
Copy link

SparkQA commented Jul 22, 2020

Test build #126284 has finished for PR 29149 at commit a12e178.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@HeartSaVioR
Copy link
Contributor

retest this, please

@SparkQA
Copy link

SparkQA commented Jul 22, 2020

Test build #126290 has finished for PR 29149 at commit a12e178.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@HeartSaVioR
Copy link
Contributor

Thanks! Merging to master.

@baohe-zhang
Copy link
Author

Thanks for the review!

@mridulm
Copy link
Contributor

mridulm commented Aug 10, 2020

Sorry for the delay in getting to this.
The only additional change I had made in my version was to "batch the batch update".
For example, if the list is very large, the write will block all other threads for a very long time - which has fairness issues; in addition to the serialization consuming too much memory, etc.
Instead, I batched updates to some K values (In my case K was 128).

This can be trivially done with an inner loop doing for (List<?> batchList : Iterables.partition(entry.getValue(), batchSize)) { ... }

The performance actually improves for larger list sizes (due to memory pressure reducing - particularly in SHS), while the smaller lists suffer from minimal impact

@baohe-zhang
Copy link
Author

This seems an important improvement. Should I put up a followup PR to include this change?

@mridulm
Copy link
Contributor

mridulm commented Aug 11, 2020

That would be great, thanks @baohe-zhang !

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants