better tuning of arena block size

Summary: Currently, if users didn't set options.arena_block_size, we set "result.arena_block_size = result.write_buffer_size / 10". It makes result.arena_block_size not a multiplier of 4KB, even if options.write_buffer_size is a multiplier of MBs. When calling malloc to arena_block_size, we may waste a small amount of memory for it. We now make the default to be /8 or /16 and align it to 4KB.

Test Plan: unit tests

Reviewers: sdong

Reviewed By: sdong

Subscribers: dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D46467
main
agiardullo 9 years ago
parent 342ba80895
commit b5b2b75e52
  1. 7
      db/column_family.cc
  2. 13
      db/column_family_test.cc
  3. 2
      db/db_compaction_test.cc
  4. 2
      db/db_test.cc
  5. 4
      include/rocksdb/options.h

@ -125,7 +125,12 @@ ColumnFamilyOptions SanitizeOptions(const DBOptions& db_options,
// if user sets arena_block_size, we trust user to use this value. Otherwise, // if user sets arena_block_size, we trust user to use this value. Otherwise,
// calculate a proper value from writer_buffer_size; // calculate a proper value from writer_buffer_size;
if (result.arena_block_size <= 0) { if (result.arena_block_size <= 0) {
result.arena_block_size = result.write_buffer_size / 10; result.arena_block_size = result.write_buffer_size / 8;
// Align up to 4k
const size_t align = 4 * 1024;
result.arena_block_size =
((result.arena_block_size + align - 1) / align) * align;
} }
result.min_write_buffer_number_to_merge = result.min_write_buffer_number_to_merge =
std::min(result.min_write_buffer_number_to_merge, std::min(result.min_write_buffer_number_to_merge,

@ -1102,6 +1102,9 @@ TEST_F(ColumnFamilyTest, SanitizeOptions) {
original.level0_stop_writes_trigger = i; original.level0_stop_writes_trigger = i;
original.level0_slowdown_writes_trigger = j; original.level0_slowdown_writes_trigger = j;
original.level0_file_num_compaction_trigger = k; original.level0_file_num_compaction_trigger = k;
original.write_buffer_size =
l * 4 * 1024 * 1024 + i * 1024 * 1024 + j * 1024 + k;
ColumnFamilyOptions result = ColumnFamilyOptions result =
SanitizeOptions(db_options, nullptr, original); SanitizeOptions(db_options, nullptr, original);
ASSERT_TRUE(result.level0_stop_writes_trigger >= ASSERT_TRUE(result.level0_stop_writes_trigger >=
@ -1118,6 +1121,16 @@ TEST_F(ColumnFamilyTest, SanitizeOptions) {
ASSERT_EQ(result.num_levels, original.num_levels); ASSERT_EQ(result.num_levels, original.num_levels);
} }
} }
// Make sure Sanitize options sets arena_block_size to 1/8 of
// the write_buffer_size, rounded up to a multiple of 4k.
size_t expected_arena_block_size =
l * 4 * 1024 * 1024 / 8 + i * 1024 * 1024 / 8;
if (j + k != 0) {
// not a multiple of 4k, round up 4k
expected_arena_block_size += 4 * 1024;
}
ASSERT_EQ(expected_arena_block_size, result.arena_block_size);
} }
} }
} }

@ -234,7 +234,7 @@ TEST_P(DBCompactionTestWithParam, CompactionDeletionTrigger) {
DestroyAndReopen(options); DestroyAndReopen(options);
Random rnd(301); Random rnd(301);
const int kTestSize = kCDTKeysPerBuffer * 512; const int kTestSize = kCDTKeysPerBuffer * 1024;
std::vector<std::string> values; std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) { for (int k = 0; k < kTestSize; ++k) {
values.push_back(RandomString(&rnd, kCDTValueSize)); values.push_back(RandomString(&rnd, kCDTValueSize));

@ -2692,7 +2692,7 @@ TEST_F(DBTest, FlushSchedule) {
Random rnd(a); Random rnd(a);
WriteOptions wo; WriteOptions wo;
// this should fill up 2 memtables // this should fill up 2 memtables
for (int k = 0; k < 6144; ++k) { for (int k = 0; k < 5000; ++k) {
ASSERT_OK(db_->Put(wo, handles_[a & 1], RandomString(&rnd, 13), "")); ASSERT_OK(db_->Put(wo, handles_[a & 1], RandomString(&rnd, 13), ""));
} }
}; };

@ -515,8 +515,8 @@ struct ColumnFamilyOptions {
unsigned int rate_limit_delay_max_milliseconds; unsigned int rate_limit_delay_max_milliseconds;
// size of one block in arena memory allocation. // size of one block in arena memory allocation.
// If <= 0, a proper value is automatically calculated (usually 1/10 of // If <= 0, a proper value is automatically calculated (usually 1/8 of
// writer_buffer_size). // writer_buffer_size, rounded up to a multiple of 4KB).
// //
// There are two additonal restriction of the The specified size: // There are two additonal restriction of the The specified size:
// (1) size should be in the range of [4096, 2 << 30] and // (1) size should be in the range of [4096, 2 << 30] and

Loading…
Cancel
Save