Skip to content

Commit cd995c0

Browse files
byahn0996facebook-github-bot
authored andcommitted
Refactor APIs to enable async IO
Summary: APIs to enable async IO were not properly written and organized. For example, by giving non-zero maxNumReads and maxNumWrites to setReaderAndWriterThreads(), async IO will be just silently enabled even without enableAsyncIo() call. Also, just calling enableAsyncIo() doesn't really enable async Io. Adding new APIs which will do what it's supposed to do. After this change, - I will change existing codes that are using old API - then old API will be removed Reviewed By: AlnisM Differential Revision: D81206199 fbshipit-source-id: 26a06aa98431320306946fed1f8c3cdae69e5af9
1 parent 2bf8ea0 commit cd995c0

File tree

2 files changed

+93
-14
lines changed

2 files changed

+93
-14
lines changed

cachelib/allocator/nvmcache/NavyConfig.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,44 @@ void NavyConfig::enableAsyncIo(unsigned int qDepth, bool enableIoUring) {
7474
}
7575
}
7676

77+
void NavyConfig::enableAsyncIo(uint32_t maxNumReads,
78+
uint32_t maxNumWrites,
79+
bool useIoUring,
80+
uint32_t stackSizeKB) {
81+
if (maxNumReads == 0 || maxNumWrites == 0) {
82+
throw std::invalid_argument(
83+
"maxNumReads and maxNumWrites should be both > 0");
84+
}
85+
86+
if (readerThreads_ == 0 || writerThreads_ == 0) {
87+
throw std::runtime_error(
88+
"number of read/write threads should be set first as non-zero value");
89+
}
90+
91+
if ((maxNumReads % readerThreads_) || (maxNumWrites % writerThreads_)) {
92+
throw std::invalid_argument(folly::sformat(
93+
"reader threads ({}) and writer threads ({}) should divide evenly "
94+
"into maxNumReads ({}) or maxNumWrites ({})",
95+
readerThreads_, writerThreads_, maxNumReads, maxNumWrites));
96+
}
97+
98+
// Limit the fiber stack size to 1MB to prevent any misconfiguration;
99+
// The 1MB is already too large for most use cases and there will be lots of
100+
// memory wasted
101+
if (stackSizeKB >= 1024) {
102+
throw std::invalid_argument(
103+
"Maximum fiber stack size for each thread should be less than 1024 KB");
104+
}
105+
106+
maxNumReads_ = maxNumReads;
107+
maxNumWrites_ = maxNumWrites;
108+
stackSize_ = stackSizeKB * 1024;
109+
qDepth_ =
110+
std::max(maxNumReads_ / readerThreads_, maxNumWrites_ / writerThreads_);
111+
112+
ioEngine_ = (useIoUring) ? IoEngine::IoUring : IoEngine::LibAio;
113+
}
114+
77115
void NavyConfig::setSimpleFile(const std::string& fileName,
78116
uint64_t fileSize,
79117
bool truncateFile) {
@@ -227,6 +265,17 @@ void NavyConfig::setReaderAndWriterThreads(unsigned int readerThreads,
227265
}
228266
}
229267

268+
void NavyConfig::setReaderAndWriterThreads(uint32_t readerThreads,
269+
uint32_t writerThreads) {
270+
if (readerThreads == 0 || writerThreads == 0) {
271+
throw std::invalid_argument(
272+
"The number of reader threads and writer threads should be both > 0");
273+
}
274+
275+
readerThreads_ = readerThreads;
276+
writerThreads_ = writerThreads;
277+
}
278+
230279
void NavyConfig::setNavyReqOrderingShards(uint64_t navyReqOrderingShards) {
231280
if (navyReqOrderingShards == 0) {
232281
throw std::invalid_argument(

cachelib/allocator/nvmcache/NavyConfig.h

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ class NavyConfig {
681681

682682
static constexpr folly::StringPiece kAdmPolicyRandom{"random"};
683683
static constexpr folly::StringPiece kAdmPolicyDynamicRandom{"dynamic_random"};
684+
static constexpr uint32_t kDefaultNumReaderThreads{32};
685+
static constexpr uint32_t kDefaultNumWriterThreads{32};
684686

685687
bool usesSimpleFile() const noexcept { return !fileName_.empty(); }
686688
bool usesRaidFiles() const noexcept { return raidPaths_.size() > 0; }
@@ -714,7 +716,7 @@ class NavyConfig {
714716
bool getTruncateFile() const { return truncateFile_; }
715717
uint32_t getDeviceMaxWriteSize() const { return deviceMaxWriteSize_; }
716718
IoEngine getIoEngine() const { return ioEngine_; }
717-
unsigned int getQDepth() const { return qDepth_; }
719+
uint32_t getQDepth() const { return qDepth_; }
718720
BadDeviceStatus hasBadDeviceForTesting() const { return testingBadDevice_; }
719721

720722
// Return a const BigHashConfig to read values of its parameters.
@@ -730,13 +732,19 @@ class NavyConfig {
730732
}
731733

732734
// ============ Job scheduler settings =============
733-
unsigned int getReaderThreads() const { return readerThreads_; }
734-
unsigned int getWriterThreads() const { return writerThreads_; }
735+
uint32_t getReaderThreads() const {
736+
// return default value if it's not explicitly set
737+
return (readerThreads_ == 0) ? kDefaultNumReaderThreads : readerThreads_;
738+
}
739+
uint32_t getWriterThreads() const {
740+
// return default value if it's not explicitly set
741+
return (writerThreads_ == 0) ? kDefaultNumWriterThreads : writerThreads_;
742+
}
735743
uint64_t getNavyReqOrderingShards() const { return navyReqOrderingShards_; }
736744

737-
unsigned int getMaxNumReads() const { return maxNumReads_; }
738-
unsigned int getMaxNumWrites() const { return maxNumWrites_; }
739-
unsigned int getStackSize() const { return stackSize_; }
745+
uint32_t getMaxNumReads() const { return maxNumReads_; }
746+
uint32_t getMaxNumWrites() const { return maxNumWrites_; }
747+
uint32_t getStackSize() const { return stackSize_; }
740748
// ============ other settings =============
741749
uint32_t getMaxConcurrentInserts() const { return maxConcurrentInserts_; }
742750
uint64_t getMaxParcelMemoryMB() const { return maxParcelMemoryMB_; }
@@ -806,8 +814,23 @@ class NavyConfig {
806814
// If enabled already via job config settings, this will override
807815
// the qDepth_ or enableIoUring_.
808816
// If qDepth is 0, existing qDepth_ will be used
817+
// * CAUTION: This version of enableAsyncIo() is DEPRECATED.
818+
// Please use the version with four arguments below
809819
void enableAsyncIo(unsigned int qDepth, bool enableIoUring);
810820

821+
// Enable async IO (IO to the device) - either libaio or io_uring
822+
// - maxNumReads : the number of concurrent reads issued to the queues and in
823+
// process
824+
// - maxNumWrites: the number of concurrent writes issued to the queues
825+
// and in process
826+
// - useIoUring : true to use io_uring
827+
// - stackSizeKB : size of the stack for each fibers with the async job
828+
// scheduler. 0 for default stack size
829+
void enableAsyncIo(uint32_t maxNumReads,
830+
uint32_t maxNumWrites,
831+
bool useIoUring,
832+
uint32_t stackSizeKB = 0);
833+
811834
// ============ BlockCache settings =============
812835
// Return BlockCacheConfig for configuration.
813836
BlockCacheConfig& blockCache() noexcept {
@@ -828,12 +851,19 @@ class NavyConfig {
828851
// ============ Job scheduler settings =============
829852
// Set the number of reader threads and writer threads.
830853
// If maxNumReads and maxNumWrites are all 0, sync IO will be used
854+
// * CAUTION: This version of setReaderAndWriterThreads() is DEPRECATED.
855+
// Please use the version with two arguments below.
831856
void setReaderAndWriterThreads(unsigned int readerThreads,
832857
unsigned int writerThreads,
833-
unsigned int maxNumReads = 0,
834-
unsigned int maxNumWrites = 0,
858+
unsigned int maxNumReads,
859+
unsigned int maxNumWrites,
835860
unsigned int stackSizeKB = 0);
836861

862+
// ============ Job scheduler settings =============
863+
// Set the number of reader threads and writer threads.
864+
void setReaderAndWriterThreads(uint32_t readerThreads,
865+
uint32_t writerThreads);
866+
837867
// Set Navy request ordering shards (expressed as power of two).
838868
// @throw std::invalid_argument if the input value is 0.
839869
void setNavyReqOrderingShards(uint64_t navyReqOrderingShards);
@@ -893,7 +923,7 @@ class NavyConfig {
893923

894924
// Number of queue depth per thread for async IO.
895925
// 0 for Sync io engine and >1 for libaio and io_uring
896-
unsigned int qDepth_{0};
926+
uint32_t qDepth_{0};
897927

898928
// ============ Engines settings =============
899929
// Currently we support one pair of engines.
@@ -903,9 +933,9 @@ class NavyConfig {
903933

904934
// ============ Job scheduler settings =============
905935
// Number of asynchronous worker thread for read operation.
906-
unsigned int readerThreads_{32};
936+
uint32_t readerThreads_{0};
907937
// Number of asynchronous worker thread for write operation.
908-
unsigned int writerThreads_{32};
938+
uint32_t writerThreads_{0};
909939
// Number of shards expressed as power of two for native request ordering in
910940
// Navy.
911941
// This value needs to be non-zero.
@@ -915,11 +945,11 @@ class NavyConfig {
915945
// This needs to be a multiple of the number of readers and writers.
916946
// Setting this to non-0 will enable async IO where fibers are used
917947
// for Navy operations including device IO
918-
unsigned int maxNumReads_{0};
919-
unsigned int maxNumWrites_{0};
948+
uint32_t maxNumReads_{0};
949+
uint32_t maxNumWrites_{0};
920950

921951
// Stack size of fibers when async-io is enabled. 0 for default
922-
unsigned int stackSize_{0};
952+
uint32_t stackSize_{0};
923953

924954
// ============ Other settings =============
925955
// Maximum number of concurrent inserts we allow globally for Navy.

0 commit comments

Comments
 (0)