-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
HBASE-28535: Add a region-server wide key to enable data-tiering. #5856
Conversation
0ecde23
to
6029543
Compare
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
Data-tiering feature should not be enabled by default, since this feature has specific use-cases. Hence, introduce a system-wide configuration to enable the feature. Avoid the code data-tiering code paths when this system-wide configuration is not enabled. Change-Id: I308119884c42173cfef3b23c360a842c7f516977
🎊 +1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
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.
I think we need to add a unit test to test things when global data tiering configuration is disabled, don't we?
// Initialize the metadata only if the data-tiering is enabled. | ||
// If not, the metadata will be initialized later. | ||
fileInfo.initMetaAndIndex(this); | ||
} |
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.
I don't think this part is needed. We decided not to use Data Tiering logic here and restrict it to Bucket Cache, which I will take care of in the refactoring JIRA. Additionally, if the concern is to avoid executing initMetaAndIndex twice, then I have modified initMetaAndIndex to only execute once.
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 check is to avoid any changes to the old functionality. We had observed that this line does introduce some performance regression leading to a unit test failure. We keep the old behaviour to initialise the metadata at the original location when data-tiering is not enabled.
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.
Let us please avoid spaghetti code and keep components cohesive. We shall not pollute the reader with data tiering logic. As @vinayakphegde mentioned, initiMetaAndIndex already knows it should perform init logic only once in the flow, so this call here won't add extra execution.
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.
ok, I will remove the check here. The intention was to keep the old behaviour when the feature is disabled.
@@ -45,6 +45,8 @@ | |||
@InterfaceAudience.Private | |||
public class DataTieringManager { | |||
private static final Logger LOG = LoggerFactory.getLogger(DataTieringManager.class); | |||
public static final String DATA_TIERING_ENABLED_KEY = "hbase.hstore.datatiering.enable"; |
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.
Since it is a cluster-wide (or region server-level) configuration, I think the format should be something like hbase.regionserver.*
, although I'm not entirely sure. Additionally, could we use a better name for the variable to indicate that this is a cluster-wide configuration? like, GLOBAL_DATA_TIERING_ENABLED_KEY
?
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.
ack!
if (instance == null) { | ||
instance = new DataTieringManager(onlineRegions); | ||
LOG.info("DataTieringManager instantiated successfully."); | ||
public static synchronized void instantiate(Configuration conf, |
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.
Why do we need this Configuration parameter? We only enter here when isDataTieringFeatureEnabled(conf) is true, so why do we need to check it again?
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 is an additional check to avoid an unintentional use if someone makes a call to this function.
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.
If you are enforcing the check here, than there's no point in exposing isDataTieringFeatureEnabled
as a public method, as you are not giving any flexibility to clients on what to do upon the return of isDataTieringFeatureEnabled
.
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.
I have made the function isDataTieringFeatureEnabled private function of the class. We do not want to give the undue flexiblity to the user to instantiate the DataTieringManager even when the feature key is disabled.
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.
Also, would it make sense to return True if instantiated successfully and false otherwise?
DataTieringManager.instantiate(onlineRegions); | ||
if (DataTieringManager.isDataTieringFeatureEnabled(conf)) { | ||
DataTieringManager.instantiate(conf, onlineRegions); | ||
} |
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.
Since we are not instantiating the DataTieringManager itself when global configuration is not enabled, do we need to restart every time we change that global parameter?
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.
Yes, we will require server restart since we are initialising the DataTieringManager during server restart.
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.
I don't understand why this change has required to disable PREFETCH_BLOCKS_ON_OPEN_KEY
configuration on all UTs. Can you explain why? And since you are doing for all tests, why not leave it disabled?
Additionally, can we add test for the modified behaviour itself? I don't see any tests for the modified behaviour.
// Initialize the metadata only if the data-tiering is enabled. | ||
// If not, the metadata will be initialized later. | ||
fileInfo.initMetaAndIndex(this); | ||
} |
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.
Let us please avoid spaghetti code and keep components cohesive. We shall not pollute the reader with data tiering logic. As @vinayakphegde mentioned, initiMetaAndIndex already knows it should perform init logic only once in the flow, so this call here won't add extra execution.
} else { | ||
LOG.debug("Data tiering is enabled for file: '{}' and it is hot data", fileName); |
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.
Nit: no need for this extra else block, just do the logging.
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.
ack!
} else { | ||
LOG.debug("Data tiering feature is not enabled. " | ||
+ " The file: '{}' will be loaded if not already loaded", fileName); |
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.
Nit: no need for this extra else block, just do the logging.
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.
ack!
} | ||
|
||
// if we don't have the file in fullyCachedFiles, we should cache it | ||
// if we don't have the file in fullyCachedFiles, we should cache it. |
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.
Nit: avoid useless line changes in the PR.
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.
ack!
if (instance == null) { | ||
instance = new DataTieringManager(onlineRegions); | ||
LOG.info("DataTieringManager instantiated successfully."); | ||
public static synchronized void instantiate(Configuration conf, |
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.
If you are enforcing the check here, than there's no point in exposing isDataTieringFeatureEnabled
as a public method, as you are not giving any flexibility to clients on what to do upon the return of isDataTieringFeatureEnabled
.
if (DataTieringManager.isDataTieringFeatureEnabled(conf)) { | ||
DataTieringManager.instantiate(conf, onlineRegions); | ||
} |
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.
No need for this if check, since you do it internally on DataTieringManager.instantiate
. If you want to keep the check inside DataTieringManager.instantiate
, then no need for this check here.
Waiter.waitFor(defaultConf, 10000, 100, () -> (bucketCache.getBackingMap().containsKey(key))); | ||
} | ||
// disable any prefetch in parallel to test execution | ||
defaultConf.setBoolean(CacheConfig.PREFETCH_BLOCKS_ON_OPEN_KEY, false); |
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.
Is this necessary because of the modified functionality? Otherwise, can you explain why this is needed now?
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.
There have been intermittent failures in these tests where the block counts different than expected at different points. I did observe the prefetch kicking in during those failures. Hence, I tried to fix these failures. But I realise, it is better to keep these test fixes different from this original change. I will remove these changes in the new patch set.
💔 -1 overall
This message was automatically generated. |
ab8de8e
to
825e026
Compare
🎊 +1 overall
This message was automatically generated. |
Waiter.waitFor(defaultConf, 10000, 100, | ||
() -> (bucketCache.getBackingMap().containsKey(newKey))); | ||
|
||
// Verify that the bucket still contains the 2 cold blocks and one newly added hot block. |
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.
Currently, in this test, which blocks stay is not deterministic. Any block may get evicted leading to test failure.
@wchevreuil, @vinayakphegde, any idea to enforce the eviction of hot blocks and retain the cold blocks in cache to validate that data-tiering is not effective? If not, we may have to rely on the absence of DataTieringManager instance only.
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
f076005
to
363a071
Compare
💔 -1 overall
This message was automatically generated. |
Change-Id: I95ec8691f5d511a8bd452c1492de7ff1222980b6
|
||
int blocksIter = 0; | ||
for (BlockCacheKey key : cacheKeys) { | ||
LOG.info("Adding {}", key); |
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 test seems to work with the latest fixes. However, I am keeping these logs handy until the flakyness is fixed.
🎊 +1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
…ache#5856) Signed-off-by: Wellington Chevreuil <wchevreuil@apache.org>
…ache#5856) Signed-off-by: Wellington Chevreuil <wchevreuil@apache.org> Change-Id: If9851a2a748bf24674ee1819487ce6ee8e75e7a0
Data-tiering feature should not be enabled by default, since this feature has specific use-cases. Hence, introduce a system-wide configuration to enable the feature.
Avoid the code data-tiering code paths when this system-wide configuration is not enabled.
Change-Id: I308119884c42173cfef3b23c360a842c7f516977