From 445b8f8ae9e1d7bc4d2482b31c4b54b78ae29753 Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Tue, 14 Dec 2021 14:45:22 +0100 Subject: Rename max_buffers_ratio to active_buffers_ratio. Add comment before calculation of max buffers to compact at once. --- .../compact_buffer_candidates_test.cpp | 12 ++++++------ .../vespalib/datastore/compact_buffer_candidates.cpp | 18 +++++++++++++++--- .../vespalib/datastore/compact_buffer_candidates.h | 4 ++-- .../src/vespa/vespalib/datastore/compaction_strategy.h | 14 +++++++------- .../src/vespa/vespalib/datastore/datastorebase.cpp | 4 ++-- 5 files changed, 32 insertions(+), 20 deletions(-) (limited to 'vespalib') diff --git a/vespalib/src/tests/datastore/compact_buffer_candidates/compact_buffer_candidates_test.cpp b/vespalib/src/tests/datastore/compact_buffer_candidates/compact_buffer_candidates_test.cpp index 6ab4d68b7a6..1ba9a993ee6 100644 --- a/vespalib/src/tests/datastore/compact_buffer_candidates/compact_buffer_candidates_test.cpp +++ b/vespalib/src/tests/datastore/compact_buffer_candidates/compact_buffer_candidates_test.cpp @@ -10,7 +10,7 @@ namespace { constexpr uint32_t num_buffers = 1024; constexpr double default_ratio = 0.2 / 2; constexpr size_t default_slack = 1000; -constexpr double default_max_buffers_ratio = 1.0; +constexpr double default_active_buffers_ratio = 1.0; }; @@ -21,7 +21,7 @@ public: CompactBufferCandidates candidates; CompactBufferCandidatesTest(); ~CompactBufferCandidatesTest() override; - void reset_candidates(uint32_t max_buffers, double max_buffers_ratio = default_max_buffers_ratio); + void reset_candidates(uint32_t max_buffers, double active_buffers_ratio = default_active_buffers_ratio); CompactBufferCandidatesTest& add(uint32_t buffer_id, size_t used, size_t dead); void assert_select(const std::vector& exp); void set_free_buffers(uint32_t free_buffers = 100); @@ -29,16 +29,16 @@ public: CompactBufferCandidatesTest::CompactBufferCandidatesTest() : ::testing::Test(), - candidates(num_buffers, 1, default_max_buffers_ratio, default_ratio, default_slack) + candidates(num_buffers, 1, default_active_buffers_ratio, default_ratio, default_slack) { } CompactBufferCandidatesTest::~CompactBufferCandidatesTest() = default; void -CompactBufferCandidatesTest::reset_candidates(uint32_t max_buffers, double max_buffers_ratio) +CompactBufferCandidatesTest::reset_candidates(uint32_t max_buffers, double active_buffers_ratio) { - candidates = CompactBufferCandidates(num_buffers, max_buffers, max_buffers_ratio, default_ratio, default_slack); + candidates = CompactBufferCandidates(num_buffers, max_buffers, active_buffers_ratio, default_ratio, default_slack); } CompactBufferCandidatesTest& @@ -96,7 +96,7 @@ TEST_F(CompactBufferCandidatesTest, select_cutoff_by_slack) assert_select({9, 3}); } -TEST_F(CompactBufferCandidatesTest, select_cutoff_by_max_buffers_ratio) +TEST_F(CompactBufferCandidatesTest, select_cutoff_by_active_buffers_ratio) { reset_candidates(4, 0.5); add(1, 10000, 2000).add(3, 10000, 4000).add(8, 10000, 3000).set_free_buffers(); diff --git a/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.cpp b/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.cpp index dd90f226302..41c216a9684 100644 --- a/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.cpp +++ b/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.cpp @@ -6,12 +6,12 @@ namespace vespalib::datastore { -CompactBufferCandidates::CompactBufferCandidates(uint32_t num_buffers, uint32_t max_buffers, double max_buffers_ratio, double ratio, size_t slack) +CompactBufferCandidates::CompactBufferCandidates(uint32_t num_buffers, uint32_t max_buffers, double active_buffers_ratio, double ratio, size_t slack) : _candidates(), _used(0), _dead(0), _max_buffers(std::max(max_buffers, 1u)), - _max_buffers_ratio(std::min(1.0, std::max(0.0001, max_buffers_ratio))), + _active_buffers_ratio(std::min(1.0, std::max(0.0001, active_buffers_ratio))), _ratio(ratio), _slack(slack), _free_buffers(0) @@ -41,7 +41,19 @@ CompactBufferCandidates::select(std::vector& buffers) if (_candidates.empty()) { return; } - uint32_t max_buffers = ceil(std::min(_candidates.size() * _max_buffers_ratio, _free_buffers * 0.2)); + /* + * Calculate a limit of how many buffers to compact at once. Throughput, + * latency, transient resource usage (memory and address space used for + * held buffers) and stability must all be considered. + * + * We want to compact up to a portion of the active buffers (hence + * _active_buffers_ratio) but do not want to use up all remaining free + * buffers during compaction (hence free_buffers_ratio). Cap the limit by + * [1, _max_buffers] to ensure some but not too much progress. + */ + constexpr double free_buffers_ratio = 0.2; + uint32_t active_buffers = _candidates.size(); + uint32_t max_buffers = ceil(std::min(active_buffers * _active_buffers_ratio, _free_buffers * free_buffers_ratio)); max_buffers = std::max(1u, std::min(max_buffers, _max_buffers)); if (_candidates.size() > max_buffers) { std::nth_element(_candidates.begin(), _candidates.begin() + (max_buffers - 1), _candidates.end()); diff --git a/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.h b/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.h index d85f5880371..db82ebd4eae 100644 --- a/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.h +++ b/vespalib/src/vespa/vespalib/datastore/compact_buffer_candidates.h @@ -15,12 +15,12 @@ class CompactBufferCandidates { size_t _used; size_t _dead; uint32_t _max_buffers; - double _max_buffers_ratio; + double _active_buffers_ratio; double _ratio; size_t _slack; uint32_t _free_buffers; public: - CompactBufferCandidates(uint32_t num_buffers, uint32_t max_buffers, double max_buffers_ratio, double ratio, size_t slack); + CompactBufferCandidates(uint32_t num_buffers, uint32_t max_buffers, double active_buffers_ratio, double ratio, size_t slack); ~CompactBufferCandidates(); void add(uint32_t buffer_id, size_t used, size_t dead); void set_free_buffers(uint32_t free_buffers); diff --git a/vespalib/src/vespa/vespalib/datastore/compaction_strategy.h b/vespalib/src/vespa/vespalib/datastore/compaction_strategy.h index be4dfe1d983..2bcf30fc6fc 100644 --- a/vespalib/src/vespa/vespalib/datastore/compaction_strategy.h +++ b/vespalib/src/vespa/vespalib/datastore/compaction_strategy.h @@ -28,7 +28,7 @@ private: double _maxDeadBytesRatio; // Max ratio of dead bytes before compaction double _maxDeadAddressSpaceRatio; // Max ratio of dead address space before compaction uint32_t _max_buffers; // Max number of buffers to compact for each reason (memory usage, address space usage) - double _max_buffers_ratio; // Ratio of active buffers to compact for each reason (memory usage, address space usage) + double _active_buffers_ratio; // Ratio of active buffers to compact for each reason (memory usage, address space usage) bool should_compact_memory(size_t used_bytes, size_t dead_bytes) const { return ((dead_bytes >= DEAD_BYTES_SLACK) && (dead_bytes > used_bytes * getMaxDeadBytesRatio())); @@ -42,32 +42,32 @@ public: : _maxDeadBytesRatio(0.05), _maxDeadAddressSpaceRatio(0.2), _max_buffers(1), - _max_buffers_ratio(0.1) + _active_buffers_ratio(0.1) { } CompactionStrategy(double maxDeadBytesRatio, double maxDeadAddressSpaceRatio) noexcept : _maxDeadBytesRatio(maxDeadBytesRatio), _maxDeadAddressSpaceRatio(maxDeadAddressSpaceRatio), _max_buffers(1), - _max_buffers_ratio(0.1) + _active_buffers_ratio(0.1) { } - CompactionStrategy(double maxDeadBytesRatio, double maxDeadAddressSpaceRatio, uint32_t max_buffers, double max_buffers_ratio) noexcept + CompactionStrategy(double maxDeadBytesRatio, double maxDeadAddressSpaceRatio, uint32_t max_buffers, double active_buffers_ratio) noexcept : _maxDeadBytesRatio(maxDeadBytesRatio), _maxDeadAddressSpaceRatio(maxDeadAddressSpaceRatio), _max_buffers(max_buffers), - _max_buffers_ratio(max_buffers_ratio) + _active_buffers_ratio(active_buffers_ratio) { } double getMaxDeadBytesRatio() const { return _maxDeadBytesRatio; } double getMaxDeadAddressSpaceRatio() const { return _maxDeadAddressSpaceRatio; } uint32_t get_max_buffers() const noexcept { return _max_buffers; } - double get_max_buffers_ratio() const noexcept { return _max_buffers_ratio; } + double get_active_buffers_ratio() const noexcept { return _active_buffers_ratio; } bool operator==(const CompactionStrategy & rhs) const { return (_maxDeadBytesRatio == rhs._maxDeadBytesRatio) && (_maxDeadAddressSpaceRatio == rhs._maxDeadAddressSpaceRatio) && (_max_buffers == rhs._max_buffers) && - (_max_buffers_ratio == rhs._max_buffers_ratio); + (_active_buffers_ratio == rhs._active_buffers_ratio); } bool operator!=(const CompactionStrategy & rhs) const { return !(operator==(rhs)); } diff --git a/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp b/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp index e99c635a0e9..d2b23a1a5cf 100644 --- a/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp +++ b/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp @@ -533,9 +533,9 @@ std::vector DataStoreBase::startCompactWorstBuffers(CompactionSpec compaction_spec, const CompactionStrategy& compaction_strategy) { // compact memory usage - CompactBufferCandidates elem_buffers(_numBuffers, compaction_strategy.get_max_buffers(), compaction_strategy.get_max_buffers_ratio(), compaction_strategy.getMaxDeadBytesRatio() / 2, CompactionStrategy::DEAD_BYTES_SLACK); + CompactBufferCandidates elem_buffers(_numBuffers, compaction_strategy.get_max_buffers(), compaction_strategy.get_active_buffers_ratio(), compaction_strategy.getMaxDeadBytesRatio() / 2, CompactionStrategy::DEAD_BYTES_SLACK); // compact address space - CompactBufferCandidates array_buffers(_numBuffers, compaction_strategy.get_max_buffers(), compaction_strategy.get_max_buffers_ratio(), compaction_strategy.getMaxDeadAddressSpaceRatio() / 2, CompactionStrategy::DEAD_ADDRESS_SPACE_SLACK); + CompactBufferCandidates array_buffers(_numBuffers, compaction_strategy.get_max_buffers(), compaction_strategy.get_active_buffers_ratio(), compaction_strategy.getMaxDeadAddressSpaceRatio() / 2, CompactionStrategy::DEAD_ADDRESS_SPACE_SLACK); uint32_t free_buffers = 0; for (uint32_t bufferId = 0; bufferId < _numBuffers; ++bufferId) { const auto &state = getBufferState(bufferId); -- cgit v1.2.3