-
Notifications
You must be signed in to change notification settings - Fork 275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactoring DiskSpaceAllocator to support dynamically add/remove store #1210
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1210 +/- ##
============================================
+ Coverage 69.49% 69.54% +0.05%
- Complexity 5516 5551 +35
============================================
Files 432 432
Lines 33844 33943 +99
Branches 4312 4342 +30
============================================
+ Hits 23520 23606 +86
- Misses 9137 9140 +3
- Partials 1187 1197 +10
Continue to review full report at Codecov.
|
25f0c83
to
f7ffab5
Compare
./gradlew build && ./gradlew test succeeded
|
@@ -256,6 +256,7 @@ A single compaction job could be performed across multiple compaction cycles (if | |||
* @return the number of temporary log segment files this compactor is currently using. | |||
*/ | |||
int getSwapSegmentsInUse() throws StoreException { | |||
// TODO: use this method to return swap segment to pool when removing store |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
address this TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TODO is just a reminder that future PR (dynamically remove store) could invoke this method to swap segment in use and return it to pool. For current PR, no extra changes are needed. I will remove this comment in "remove store" PR :)
private static final FileFilter RESERVE_FILE_FILTER = | ||
private static final String RESERVE_FILE_PREFIX = "reserve_"; | ||
static final String STORE_DIR_PREFIX = "reserve_store_"; | ||
static final FileFilter RESERVE_FILE_FILTER = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the two filters seem like they can be private
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
*/ | ||
DiskSpaceAllocator(boolean enablePooling, File reserveDir, long requiredSwapSegmentsPerSize, | ||
StorageManagerMetrics metrics) { | ||
this.enablePooling = enablePooling; | ||
this.reserveDir = reserveDir; | ||
swapReserveDir = new File(reserveDir, SWAP_DIR_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rollout strategy for this? Is it better to manually delete the old directories or have the code detect the old format and do it automatically. We could automatically delete any folders in reserveDir
that start with "reserve_size_". This could help to avoid a complicated deployment where we have to disable the diskspaceallocator, then delete the files, and then redeploy with the new version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. I will add some logic to correctly identify stale files/directories and delete them automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, after second look, my code will clean up the directories that are neither store reserve directory nor swap segment directory. (following piece of code is in inventoryExistingReserveFiles
method)
} else {
// if it is neither store reserved segment directory nor swap segment directory, then delete it.
if (!file.delete()) {
throw new IOException("Could not delete the following reserve file or directory: " + file.getAbsolutePath());
}
}
I will ensure there is a test to verify this.
// attempt to get segment from corresponding store reserve directory | ||
if (storeReserveFiles.containsKey(storeId)) { | ||
reserveFile = storeReserveFiles.get(storeId).remove(sizeInBytes); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add logging if storeId not found?
if (storeReserveFiles.containsKey(storeId)) { | ||
reserveFile = storeReserveFiles.get(storeId).remove(sizeInBytes); | ||
} | ||
} | ||
} | ||
if (reserveFile == null) { | ||
if (enablePooling) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or it might be good to edit all these log message to include info about storeID and isSwapSegment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, will do.
added unit test to verify inventory can delete invalid directories/files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PROD code looks good. I can merge it now since this change blocks @jsjtzyy .
This PR allows disk allocator to add or delete segments for a certain store without re-initializing entire reserve pool. The changes include: 1. Each store has its own reserve file directory. 2. All stores on the same disk share reserved swap segments. 3. Changed addRequiredSegments() and deleteExtraSegments() to support segments addition/removal.
} | ||
} finally { | ||
long elapsedTime = System.currentTimeMillis() - startTime; | ||
logger.debug("free took {} ms", elapsedTime); | ||
logger.debug("free took {} ms for {}", elapsedTime, "store[" + storeId + "]"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid the cost of string concat when debug logging is off:
logger.debug("free took {} ms for store[{}]", elapsedTime, storeId);
This PR allows disk allocator to add or delete segments for a certain
store without re-initializing entire reserve pool. The changes include:
segments addition/removal.