[
https://issues.apache.org/jira/browse/HDFS-9129?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mingliang Liu updated HDFS-9129:
--------------------------------
Attachment: HDFS-9129.007.patch
Thank you [~wheat9] for your detailed comments. The v7 patch addresses most of
them. See response inline.
{quote}
{code}
if (status == BMSafeModeStatus.OFF) {
return;
}
{code}
1. There are multiple cases like the above. They should be asserts.
{quote}
It is safe for these methods to be called multiple times. If safe mode is not
currently on, this is a no-op. Previously we check whether the {{safeMode}} is
null before calling the respective methods. E.g.
{code:title=previous volatile and null check to allow calling multiple times}
public void checkSafeMode() {
// safeMode is volatile, and may be set to null at any time
SafeModeInfo safeMode = this.safeMode;
if (safeMode != null) {
safeMode.checkMode();
}
}
{code}
As we moved the start up safe mode to {{BlockManager}} and maintain a state
machine for safe mode status, the volatile and null {{safeMode}} trick is not
needed. Meanwhile, we must allow {{BlockManagerSafeMode}}'s methods called
multiple times without side effect.
I will explicitly elaborate this in comments for these methods.
{quote}
2. namesystem.isHaEnabled() does not change in the lifecycle of the process.
{quote}
This is a very good point. I considered this but the {{blockManager}}, which
will create the {{blockManagerSafeMode}}, is constructed before the
{{namesystem#haEnabled}} is initialized. Per offline discussion with [~wheat9]
and [~jingzhao], we can initialize the {{namesystem#haEnabled}} before
constructing the {{blockManager}}. This way, the {{namesystem.isHaEnabled}} is
not called repeatedly in the critical path.
{quote}
3. It's better to document the conditions of state transition.
{quote}
Yes, it makes a lot of sense to document the state machine transition. In v7
patch, I add a diagram in the comment.
{quote}
{code}
+ needExtension = extension > 0 &&
+ (blockThreshold > 0 || datanodeThreshold > 0);
{code}
4. This can be moved under the THRESHOLD statement and become a local variable.
{quote}
Actually it's hard, if not impossible, largely because the {{needExtension}}
should be initialized in the start status, aka {{INITALIZED}}. There is a
regression test for this case
{{TestHASafeMode#testBlocksRemovedBeforeStandbyRestart}}, brought by
[HDFS-2692].
{quote}
5. initializeReplQueuesIfNecessary() should be called only once.
{quote}
Yes, we should initialize the replication queue only once. Once called for the
first time, {{BlockManager#initializeReplQueues}} will set a flag indicating
the replication queue is initialized. We'll check this flag in
{{isPopulatingReplQueues}} before calling {{initializeReplQueues}} again. As it
is of great importance to guarantee this, I'll double check this and fix this
in next patch.
{quote}
6. safeModeStatus = SafeModeStatus.OFF should be moved to BlockManagerSafeMode.
{quote}
The {{safeModeStatus}} was for the {{FSNamesystem}} and the *OFF* here
indicates both {{FSNamesystem}} and {{BlockManager}} leave the safe mode.
{{BlockManagerSafeMode}}'s internal {{status}} was maintained in its own
{{leaveSafeMode}} method.
Per offline discussion with [~wheat9] and [~jingzhao], the better design is to
simplify the {{Namesystem}} safe mode to two flags indicating _manually_ or
_resoure low_. In this way, the safe mode check is pretty straight-forward. The
side benefit is that when we extend the current safe mode status, one more flag
will work just fine, without breaking the existing code.
{code:title=new manual and resource low safe mode flag}
private volatile boolean isInManualSafeMode = false;
private volatile boolean isInResourceLowSafeMode = false;
...
@Override
public boolean isInSafeMode() {
return isInManualSafeMode ||
isInResourceLowSafeMode ||
blockManager.isInSafeMode();
}
{code}
{quote}
7. A cleaner approach is to put the {{reached}} timestamp into the constructor
of {{SafeModeMonitor()}}.
{quote}
It's a good point to define the {{reached}} value in the monitor. The v7 patch
initializes it when the monitor starts. As the {{reached}} timestamp is partly
used out of {{SafeModeMonitor}}, e.g. in {{getSafeModeTip}} and {{checkMode}},
the easy (may not be best) way is to treat it as class field.
{quote}
8. It might be good to have additional unit tests for BlockManagerSafeMode.
{quote}
That makes perfect sense to me. I'll add new unit test named
{{TestBlockManagerSafeMode}} in the next patch.
> Move the safemode block count into BlockManager
> -----------------------------------------------
>
> Key: HDFS-9129
> URL: https://issues.apache.org/jira/browse/HDFS-9129
> Project: Hadoop HDFS
> Issue Type: Sub-task
> Reporter: Haohui Mai
> Assignee: Mingliang Liu
> Attachments: HDFS-9129.000.patch, HDFS-9129.001.patch,
> HDFS-9129.002.patch, HDFS-9129.003.patch, HDFS-9129.004.patch,
> HDFS-9129.005.patch, HDFS-9129.006.patch, HDFS-9129.007.patch
>
>
> The {{SafeMode}} needs to track whether there are enough blocks so that the
> NN can get out of the safemode. These fields can moved to the
> {{BlockManager}} class.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)