Skip to content

Commit e222abd

Browse files
authored
chore(tiering): Make disk storage initial size configurable and add grow policy (#7715)
* chore(tiering): Make disk storage initial size configurable and add grow policy Replace hardcoded kInitialSize with FLAGS_tiering_disk_storage_initial_size (default 256MB), allowing configuration of initial disk storage size. Introduce ComputeGrowSize in RequestGrow to replace fixed grow size logic. Growth is now computed as 5% of current capacity, rounded up to 256MB alignment. This makes disk storage sizing fully policy-driven instead of constant-based. --------- Signed-off-by: mkaruza <mario@dragonflydb.io>
1 parent 8e54ad0 commit e222abd

2 files changed

Lines changed: 41 additions & 9 deletions

File tree

src/server/tiering/disk_storage.cc

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "server/error.h"
1515
#include "server/tiering/common.h"
1616
#include "server/tiering/external_alloc.h"
17+
#include "strings/human_readable.h"
1718
#include "util/fibers/uring_file.h"
1819
#include "util/fibers/uring_proactor.h"
1920

@@ -24,6 +25,9 @@ ABSL_FLAG(bool, backing_file_direct, true, "If true uses O_DIRECT to open backin
2425
ABSL_FLAG(uint64_t, registered_buffer_size, 512_KB,
2526
"Size of registered buffer for IoUring fixed read/writes");
2627

28+
ABSL_FLAG(strings::MemoryBytesFlag, tiering_disk_storage_initial_size, 256_MB,
29+
"Initial disk storage size.");
30+
2731
namespace dfly::tiering {
2832

2933
std::ostream& operator<<(std::ostream& os, const DiskSegment& ds) {
@@ -37,6 +41,10 @@ namespace {
3741

3842
constexpr unsigned kHeapSliceId = UINT_MAX;
3943

44+
size_t AlignUp(size_t value, size_t alignment) {
45+
return (value + alignment - 1) & ~(alignment - 1);
46+
}
47+
4048
RegisteredSlice AllocateTmpBuf(size_t size) {
4149
size = (size + kPageSize - 1) / kPageSize * kPageSize;
4250
VLOG(2) << "Fallback to temporary allocation: " << size;
@@ -60,8 +68,6 @@ void ReturnBuf(RegisteredSlice buf) {
6068
DestroyTmpBuf(buf);
6169
}
6270

63-
constexpr off_t kInitialSize = 1UL << 28; // 256MB
64-
6571
template <typename... Ts> error_code DoFiberCall(void (SubmitEntry::*c)(Ts...), Ts... args) {
6672
auto* proactor = static_cast<UringProactor*>(ProactorBase::me());
6773
FiberCall fc(proactor);
@@ -94,12 +100,24 @@ error_code DiskStorage::Open(string_view path) {
94100

95101
int fd = backing_file_->fd();
96102

97-
auto ec = DoFiberCall(&SubmitEntry::PrepFallocate, fd, 0, 0L, kInitialSize);
103+
off_t disk_initial_size = absl::GetFlag(FLAGS_tiering_disk_storage_initial_size);
104+
105+
if (!disk_initial_size || (disk_initial_size % ExternalAllocator::kExtAlignment) != 0) {
106+
disk_initial_size = !disk_initial_size
107+
? ExternalAllocator::kExtAlignment
108+
: AlignUp(disk_initial_size, ExternalAllocator::kExtAlignment);
109+
LOG(WARNING) << "Flag tiering_disk_storage_initial_size is not aligned to "
110+
<< strings::HumanReadableNumBytes(ExternalAllocator::kExtAlignment)
111+
<< " bytes; rounded up to " << strings::HumanReadableNumBytes(disk_initial_size);
112+
}
113+
114+
auto ec =
115+
DoFiberCall(&SubmitEntry::PrepFallocate, fd, 0, 0L, static_cast<off_t>(disk_initial_size));
98116
VLOG_IF(1, ec) << "Fallocate not supported";
99117

100118
RETURN_ON_ERR(DoFiberCall(&SubmitEntry::PrepFadvise, fd, 0L, 0L, POSIX_FADV_RANDOM));
101119

102-
alloc_.AddStorage(0, kInitialSize);
120+
alloc_.AddStorage(0, disk_initial_size);
103121

104122
// TODO(vlad): Even though this is called only once for regular use,
105123
// the testing code runs this initializer every time, never unregistering previous buffers
@@ -204,8 +222,9 @@ void DiskStorage::Stash(DiskSegment segment, RegisteredSlice buf, StashCb cb) {
204222
// Grow in advance if needed and possible
205223
size_t capacity = alloc_.capacity();
206224
size_t available = capacity - alloc_.allocated_bytes();
207-
if ((available < 256_MB) && (available < capacity * 0.15) && !grow_.pending) {
208-
auto ec = RequestGrow(256_MB);
225+
if ((available < ExternalAllocator::kExtAlignment) && (available < capacity * 0.15) &&
226+
!grow_.pending) {
227+
auto ec = RequestGrow(ExternalAllocator::kExtAlignment);
209228
LOG_IF(ERROR, ec && ec != errc::file_too_large) << "Could not call grow :" << ec.message();
210229
}
211230
}
@@ -216,7 +235,20 @@ DiskStorage::Stats DiskStorage::GetStats() const {
216235
static_cast<size_t>(max_size_), pending_ops_, pending_stash_bytes_};
217236
}
218237

219-
error_code DiskStorage::RequestGrow(off_t grow_size) {
238+
error_code DiskStorage::RequestGrow(off_t min_size) {
239+
// Request the file to grow by (default ExternalAllocator::kExtAlignment = 256_MB):
240+
// - take 5% of capacity
241+
// - round up to 256 MB boundary
242+
// - ensure result is at least min_size
243+
auto ComputeGrowSize = [](size_t capacity, size_t min_size) -> size_t {
244+
const size_t kGrowPercent = 5;
245+
const size_t kAlign = ExternalAllocator::kExtAlignment;
246+
size_t grow = AlignUp((capacity * kGrowPercent) / 100, kAlign);
247+
return std::max(grow, min_size);
248+
};
249+
250+
size_t grow_size = ComputeGrowSize(alloc_.capacity(), static_cast<size_t>(min_size));
251+
220252
VLOG(1) << "Requesting grow by " << grow_size << " current capacity: " << alloc_.capacity();
221253

222254
DCHECK_EQ(grow_size % ExternalAllocator::kExtAlignment, 0u);

src/server/tiering/disk_storage.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ class DiskStorage {
5959
Stats GetStats() const;
6060

6161
private:
62-
// Try asynchronously growing backing file by requested size
63-
std::error_code RequestGrow(off_t grow_size);
62+
// Try asynchronously growing backing file by at least min requested size
63+
std::error_code RequestGrow(off_t min_size);
6464

6565
// Returns a buffer with size greater or equal to len.
6666
util::fb2::RegisteredSlice PrepareBuf(size_t len);

0 commit comments

Comments
 (0)