HDDS-362. Modify functions impacted by SCM chill mode in ScmBlockLocationProtocol. Contributed by Ajay Kumar.
This commit is contained in:
parent
07385f886e
commit
95231f1749
|
@ -171,6 +171,13 @@ enum ReplicationFactor {
|
||||||
THREE = 3;
|
THREE = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ScmOps {
|
||||||
|
allocateBlock = 1;
|
||||||
|
keyBlocksInfoList = 2;
|
||||||
|
getScmInfo = 3;
|
||||||
|
deleteBlock = 4;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block ID that uniquely identify a block by SCM.
|
* Block ID that uniquely identify a block by SCM.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.hadoop.hdds.scm.block;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.conf.StorageUnit;
|
import org.apache.hadoop.conf.StorageUnit;
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ScmOps;
|
||||||
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
||||||
import org.apache.hadoop.hdds.scm.container.Mapping;
|
import org.apache.hadoop.hdds.scm.container.Mapping;
|
||||||
import org.apache.hadoop.hdds.scm.container.common.helpers.AllocatedBlock;
|
import org.apache.hadoop.hdds.scm.container.common.helpers.AllocatedBlock;
|
||||||
|
@ -28,6 +29,9 @@ import org.apache.hadoop.hdds.scm.node.NodeManager;
|
||||||
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
||||||
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor;
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor;
|
||||||
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
|
||||||
|
import org.apache.hadoop.hdds.scm.server.ChillModePrecheck;
|
||||||
|
import org.apache.hadoop.hdds.scm.server.Precheck;
|
||||||
|
import org.apache.hadoop.hdds.server.events.EventHandler;
|
||||||
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
||||||
import org.apache.hadoop.metrics2.util.MBeans;
|
import org.apache.hadoop.metrics2.util.MBeans;
|
||||||
import org.apache.hadoop.hdds.client.BlockID;
|
import org.apache.hadoop.hdds.client.BlockID;
|
||||||
|
@ -61,7 +65,8 @@ import static org.apache.hadoop.ozone.OzoneConfigKeys
|
||||||
.OZONE_BLOCK_DELETING_SERVICE_TIMEOUT_DEFAULT;
|
.OZONE_BLOCK_DELETING_SERVICE_TIMEOUT_DEFAULT;
|
||||||
|
|
||||||
/** Block Manager manages the block access for SCM. */
|
/** Block Manager manages the block access for SCM. */
|
||||||
public class BlockManagerImpl implements BlockManager, BlockmanagerMXBean {
|
public class BlockManagerImpl implements EventHandler<Boolean>,
|
||||||
|
BlockManager, BlockmanagerMXBean {
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
LoggerFactory.getLogger(BlockManagerImpl.class);
|
LoggerFactory.getLogger(BlockManagerImpl.class);
|
||||||
// TODO : FIX ME : Hard coding the owner.
|
// TODO : FIX ME : Hard coding the owner.
|
||||||
|
@ -80,6 +85,7 @@ public class BlockManagerImpl implements BlockManager, BlockmanagerMXBean {
|
||||||
private final int containerProvisionBatchSize;
|
private final int containerProvisionBatchSize;
|
||||||
private final Random rand;
|
private final Random rand;
|
||||||
private ObjectName mxBean;
|
private ObjectName mxBean;
|
||||||
|
private ChillModePrecheck chillModePrecheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -125,6 +131,7 @@ public class BlockManagerImpl implements BlockManager, BlockmanagerMXBean {
|
||||||
blockDeletingService =
|
blockDeletingService =
|
||||||
new SCMBlockDeletingService(deletedBlockLog, containerManager,
|
new SCMBlockDeletingService(deletedBlockLog, containerManager,
|
||||||
nodeManager, eventPublisher, svcInterval, serviceTimeout, conf);
|
nodeManager, eventPublisher, svcInterval, serviceTimeout, conf);
|
||||||
|
chillModePrecheck = new ChillModePrecheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,19 +194,13 @@ public class BlockManagerImpl implements BlockManager, BlockmanagerMXBean {
|
||||||
ReplicationType type, ReplicationFactor factor, String owner)
|
ReplicationType type, ReplicationFactor factor, String owner)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
LOG.trace("Size;{} , type : {}, factor : {} ", size, type, factor);
|
LOG.trace("Size;{} , type : {}, factor : {} ", size, type, factor);
|
||||||
|
preCheck(ScmOps.allocateBlock, chillModePrecheck);
|
||||||
if (size < 0 || size > containerSize) {
|
if (size < 0 || size > containerSize) {
|
||||||
LOG.warn("Invalid block size requested : {}", size);
|
LOG.warn("Invalid block size requested : {}", size);
|
||||||
throw new SCMException("Unsupported block size: " + size,
|
throw new SCMException("Unsupported block size: " + size,
|
||||||
INVALID_BLOCK_SIZE);
|
INVALID_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodeManager.isOutOfChillMode()) {
|
|
||||||
LOG.warn("Not out of Chill mode.");
|
|
||||||
throw new SCMException("Unable to create block while in chill mode",
|
|
||||||
CHILL_MODE_EXCEPTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Here is the high level logic.
|
Here is the high level logic.
|
||||||
|
|
||||||
|
@ -430,4 +431,36 @@ public class BlockManagerImpl implements BlockManager, BlockmanagerMXBean {
|
||||||
public SCMBlockDeletingService getSCMBlockDeletingService() {
|
public SCMBlockDeletingService getSCMBlockDeletingService() {
|
||||||
return this.blockDeletingService;
|
return this.blockDeletingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform all prechecks for given operations.
|
||||||
|
*
|
||||||
|
* @param operation
|
||||||
|
* @param preChecks prechecks to be performed
|
||||||
|
*/
|
||||||
|
public void preCheck(ScmOps operation, Precheck... preChecks)
|
||||||
|
throws SCMException {
|
||||||
|
for (Precheck preCheck : preChecks) {
|
||||||
|
preCheck.check(operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(Boolean inChillMode, EventPublisher publisher) {
|
||||||
|
this.chillModePrecheck.setInChillMode(inChillMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns status of scm chill mode determined by CHILL_MODE_STATUS event.
|
||||||
|
* */
|
||||||
|
public boolean isScmInChillMode() {
|
||||||
|
return this.chillModePrecheck.isInChillMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get class logger.
|
||||||
|
* */
|
||||||
|
public static Logger getLogger() {
|
||||||
|
return LOG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import javax.management.ObjectName;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.apache.hadoop.hdds.server.events.EventHandler;
|
import org.apache.hadoop.hdds.server.events.EventHandler;
|
||||||
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
||||||
import org.apache.hadoop.metrics2.util.MBeans;
|
import org.apache.hadoop.metrics2.util.MBeans;
|
||||||
|
@ -33,16 +32,22 @@ import org.slf4j.LoggerFactory;
|
||||||
/**
|
/**
|
||||||
* Event listener to track the current state of replication.
|
* Event listener to track the current state of replication.
|
||||||
*/
|
*/
|
||||||
public class ReplicationActivityStatus
|
public class ReplicationActivityStatus implements
|
||||||
implements EventHandler<Boolean>, ReplicationActivityStatusMXBean,
|
ReplicationActivityStatusMXBean, Closeable {
|
||||||
Closeable {
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
LoggerFactory.getLogger(ReplicationActivityStatus.class);
|
LoggerFactory.getLogger(ReplicationActivityStatus.class);
|
||||||
|
|
||||||
private AtomicBoolean replicationEnabled = new AtomicBoolean();
|
private AtomicBoolean replicationEnabled = new AtomicBoolean();
|
||||||
|
private AtomicBoolean replicationStatusSetExternally = new AtomicBoolean();
|
||||||
private ObjectName jmxObjectName;
|
private ObjectName jmxObjectName;
|
||||||
|
private ReplicationStatusListener replicationStatusListener;
|
||||||
|
private ChillModeStatusListener chillModeStatusListener;
|
||||||
|
|
||||||
|
public ReplicationActivityStatus(){
|
||||||
|
replicationStatusListener = new ReplicationStatusListener();
|
||||||
|
chillModeStatusListener = new ChillModeStatusListener();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isReplicationEnabled() {
|
public boolean isReplicationEnabled() {
|
||||||
return replicationEnabled.get();
|
return replicationEnabled.get();
|
||||||
|
@ -58,13 +63,6 @@ public class ReplicationActivityStatus
|
||||||
replicationEnabled.set(true);
|
replicationEnabled.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The replication status could be set by async events.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onMessage(Boolean enabled, EventPublisher publisher) {
|
|
||||||
replicationEnabled.set(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
try {
|
try {
|
||||||
|
@ -83,4 +81,37 @@ public class ReplicationActivityStatus
|
||||||
MBeans.unregister(jmxObjectName);
|
MBeans.unregister(jmxObjectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replication status listener.
|
||||||
|
*/
|
||||||
|
class ReplicationStatusListener implements EventHandler<Boolean> {
|
||||||
|
@Override
|
||||||
|
public void onMessage(Boolean status, EventPublisher publisher) {
|
||||||
|
replicationStatusSetExternally.set(true);
|
||||||
|
replicationEnabled.set(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replication status is influenced by Chill mode status as well.
|
||||||
|
*/
|
||||||
|
class ChillModeStatusListener implements EventHandler<Boolean> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(Boolean inChillMode, EventPublisher publisher) {
|
||||||
|
if (!replicationStatusSetExternally.get()) {
|
||||||
|
replicationEnabled.set(!inChillMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplicationStatusListener getReplicationStatusListener() {
|
||||||
|
return replicationStatusListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChillModeStatusListener getChillModeStatusListener() {
|
||||||
|
return chillModeStatusListener;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,8 @@ public final class SCMEvents {
|
||||||
*/
|
*/
|
||||||
public static final TypedEvent<Boolean> START_REPLICATION =
|
public static final TypedEvent<Boolean> START_REPLICATION =
|
||||||
new TypedEvent<>(Boolean.class);
|
new TypedEvent<>(Boolean.class);
|
||||||
|
public static final TypedEvent<Boolean> CHILL_MODE_STATUS =
|
||||||
|
new TypedEvent<>(Boolean.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private Ctor. Never Constructed.
|
* Private Ctor. Never Constructed.
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.hdds.scm.server;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ScmOps;
|
||||||
|
import org.apache.hadoop.hdds.scm.exceptions.SCMException;
|
||||||
|
import org.apache.hadoop.hdds.scm.exceptions.SCMException.ResultCodes;
|
||||||
|
import org.apache.hadoop.hdds.scm.server.SCMChillModeManager.ChillModeRestrictedOps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill mode pre-check for SCM operations.
|
||||||
|
* */
|
||||||
|
public class ChillModePrecheck implements Precheck<ScmOps> {
|
||||||
|
|
||||||
|
private boolean inChillMode;
|
||||||
|
public static final String PRECHECK_TYPE = "ChillModePrecheck";
|
||||||
|
|
||||||
|
public boolean check(ScmOps op) throws SCMException {
|
||||||
|
if(inChillMode && ChillModeRestrictedOps.isRestrictedInChillMode(op)) {
|
||||||
|
throw new SCMException("ChillModePrecheck failed for " + op,
|
||||||
|
ResultCodes.CHILL_MODE_EXCEPTION);
|
||||||
|
}
|
||||||
|
return inChillMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return PRECHECK_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInChillMode() {
|
||||||
|
return inChillMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInChillMode(boolean inChillMode) {
|
||||||
|
this.inChillMode = inChillMode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.hdds.scm.server;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.scm.exceptions.SCMException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Precheck for SCM operations.
|
||||||
|
* */
|
||||||
|
public interface Precheck<T> {
|
||||||
|
boolean check(T t) throws SCMException;
|
||||||
|
String type();
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
package org.apache.hadoop.hdds.scm.server;
|
package org.apache.hadoop.hdds.scm.server;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -26,12 +27,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hdds.HddsConfigKeys;
|
import org.apache.hadoop.hdds.HddsConfigKeys;
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ScmOps;
|
||||||
import org.apache.hadoop.hdds.scm.container.common.helpers.ContainerInfo;
|
import org.apache.hadoop.hdds.scm.container.common.helpers.ContainerInfo;
|
||||||
import org.apache.hadoop.hdds.scm.events.SCMEvents;
|
import org.apache.hadoop.hdds.scm.events.SCMEvents;
|
||||||
import org.apache.hadoop.hdds.scm.server.SCMDatanodeProtocolServer
|
import org.apache.hadoop.hdds.scm.server.SCMDatanodeProtocolServer
|
||||||
.NodeRegistrationContainerReport;
|
.NodeRegistrationContainerReport;
|
||||||
import org.apache.hadoop.hdds.server.events.EventHandler;
|
import org.apache.hadoop.hdds.server.events.EventHandler;
|
||||||
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
||||||
|
import org.apache.hadoop.hdds.server.events.EventQueue;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -57,16 +60,27 @@ public class SCMChillModeManager implements
|
||||||
private Map<String, ChillModeExitRule> exitRules = new HashMap(1);
|
private Map<String, ChillModeExitRule> exitRules = new HashMap(1);
|
||||||
private Configuration config;
|
private Configuration config;
|
||||||
private static final String CONT_EXIT_RULE = "ContainerChillModeRule";
|
private static final String CONT_EXIT_RULE = "ContainerChillModeRule";
|
||||||
|
private final EventQueue eventPublisher;
|
||||||
|
|
||||||
SCMChillModeManager(Configuration conf, List<ContainerInfo> allContainers,
|
SCMChillModeManager(Configuration conf, List<ContainerInfo> allContainers,
|
||||||
EventPublisher eventQueue) {
|
EventQueue eventQueue) {
|
||||||
this.config = conf;
|
this.config = conf;
|
||||||
|
this.eventPublisher = eventQueue;
|
||||||
exitRules
|
exitRules
|
||||||
.put(CONT_EXIT_RULE, new ContainerChillModeRule(config, allContainers));
|
.put(CONT_EXIT_RULE, new ContainerChillModeRule(config, allContainers));
|
||||||
if (!conf.getBoolean(HddsConfigKeys.HDDS_SCM_CHILLMODE_ENABLED,
|
if (!conf.getBoolean(HddsConfigKeys.HDDS_SCM_CHILLMODE_ENABLED,
|
||||||
HddsConfigKeys.HDDS_SCM_CHILLMODE_ENABLED_DEFAULT)) {
|
HddsConfigKeys.HDDS_SCM_CHILLMODE_ENABLED_DEFAULT)) {
|
||||||
exitChillMode(eventQueue);
|
exitChillMode(eventQueue);
|
||||||
}
|
}
|
||||||
|
emitChillModeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit Chill mode status.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public void emitChillModeStatus() {
|
||||||
|
eventPublisher.fireEvent(SCMEvents.CHILL_MODE_STATUS, inChillMode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateChillModeExitRules(EventPublisher eventQueue) {
|
private void validateChillModeExitRules(EventPublisher eventQueue) {
|
||||||
|
@ -78,11 +92,18 @@ public class SCMChillModeManager implements
|
||||||
exitChillMode(eventQueue);
|
exitChillMode(eventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exitChillMode(EventPublisher eventQueue) {
|
/**
|
||||||
|
* Exit chill mode. It does following actions:
|
||||||
|
* 1. Set chill mode status to fale.
|
||||||
|
* 2. Emits START_REPLICATION for ReplicationManager.
|
||||||
|
* 3. Cleanup resources.
|
||||||
|
* 4. Emit chill mode status.
|
||||||
|
* @param eventQueue
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public void exitChillMode(EventPublisher eventQueue) {
|
||||||
LOG.info("SCM exiting chill mode.");
|
LOG.info("SCM exiting chill mode.");
|
||||||
setInChillMode(false);
|
setInChillMode(false);
|
||||||
// Emit event to ReplicationManager to start replication.
|
|
||||||
eventQueue.fireEvent(SCMEvents.START_REPLICATION, true);
|
|
||||||
|
|
||||||
// TODO: Remove handler registration as there is no need to listen to
|
// TODO: Remove handler registration as there is no need to listen to
|
||||||
// register events anymore.
|
// register events anymore.
|
||||||
|
@ -90,6 +111,7 @@ public class SCMChillModeManager implements
|
||||||
for (ChillModeExitRule e : exitRules.values()) {
|
for (ChillModeExitRule e : exitRules.values()) {
|
||||||
e.cleanup();
|
e.cleanup();
|
||||||
}
|
}
|
||||||
|
emitChillModeStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,6 +128,9 @@ public class SCMChillModeManager implements
|
||||||
return inChillMode.get();
|
return inChillMode.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set chill mode status.
|
||||||
|
*/
|
||||||
public void setInChillMode(boolean inChillMode) {
|
public void setInChillMode(boolean inChillMode) {
|
||||||
this.inChillMode.set(inChillMode);
|
this.inChillMode.set(inChillMode);
|
||||||
}
|
}
|
||||||
|
@ -200,4 +225,20 @@ public class SCMChillModeManager implements
|
||||||
return ((ContainerChillModeRule) exitRules.get(CONT_EXIT_RULE))
|
return ((ContainerChillModeRule) exitRules.get(CONT_EXIT_RULE))
|
||||||
.getCurrentContainerThreshold();
|
.getCurrentContainerThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operations restricted in SCM chill mode.
|
||||||
|
*/
|
||||||
|
public static class ChillModeRestrictedOps {
|
||||||
|
private static EnumSet restrictedOps = EnumSet.noneOf(ScmOps.class);
|
||||||
|
|
||||||
|
static {
|
||||||
|
restrictedOps.add(ScmOps.allocateBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRestrictedInChillMode(ScmOps opName) {
|
||||||
|
return restrictedOps.contains(opName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,10 @@ public final class StorageContainerManager extends ServiceRuntimeInfoImpl
|
||||||
eventQueue.addHandler(SCMEvents.STALE_NODE, staleNodeHandler);
|
eventQueue.addHandler(SCMEvents.STALE_NODE, staleNodeHandler);
|
||||||
eventQueue.addHandler(SCMEvents.DEAD_NODE, deadNodeHandler);
|
eventQueue.addHandler(SCMEvents.DEAD_NODE, deadNodeHandler);
|
||||||
eventQueue.addHandler(SCMEvents.CMD_STATUS_REPORT, cmdStatusReportHandler);
|
eventQueue.addHandler(SCMEvents.CMD_STATUS_REPORT, cmdStatusReportHandler);
|
||||||
eventQueue.addHandler(SCMEvents.START_REPLICATION, replicationStatus);
|
eventQueue.addHandler(SCMEvents.START_REPLICATION,
|
||||||
|
replicationStatus.getReplicationStatusListener());
|
||||||
|
eventQueue.addHandler(SCMEvents.CHILL_MODE_STATUS,
|
||||||
|
replicationStatus.getChillModeStatusListener());
|
||||||
eventQueue
|
eventQueue
|
||||||
.addHandler(SCMEvents.PENDING_DELETE_STATUS, pendingDeleteHandler);
|
.addHandler(SCMEvents.PENDING_DELETE_STATUS, pendingDeleteHandler);
|
||||||
eventQueue.addHandler(SCMEvents.PIPELINE_ACTIONS,
|
eventQueue.addHandler(SCMEvents.PIPELINE_ACTIONS,
|
||||||
|
@ -258,6 +261,8 @@ public final class StorageContainerManager extends ServiceRuntimeInfoImpl
|
||||||
eventQueue.addHandler(SCMEvents.PIPELINE_CLOSE, pipelineCloseHandler);
|
eventQueue.addHandler(SCMEvents.PIPELINE_CLOSE, pipelineCloseHandler);
|
||||||
eventQueue.addHandler(SCMEvents.NODE_REGISTRATION_CONT_REPORT,
|
eventQueue.addHandler(SCMEvents.NODE_REGISTRATION_CONT_REPORT,
|
||||||
scmChillModeManager);
|
scmChillModeManager);
|
||||||
|
eventQueue.addHandler(SCMEvents.CHILL_MODE_STATUS,
|
||||||
|
(BlockManagerImpl) scmBlockManager);
|
||||||
|
|
||||||
long watcherTimeout =
|
long watcherTimeout =
|
||||||
conf.getTimeDuration(ScmConfigKeys.HDDS_SCM_WATCHER_TIMEOUT,
|
conf.getTimeDuration(ScmConfigKeys.HDDS_SCM_WATCHER_TIMEOUT,
|
||||||
|
|
|
@ -17,21 +17,28 @@
|
||||||
|
|
||||||
package org.apache.hadoop.hdds.scm.block;
|
package org.apache.hadoop.hdds.scm.block;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.FileUtil;
|
import org.apache.hadoop.fs.FileUtil;
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
||||||
import org.apache.hadoop.hdds.scm.container.ContainerMapping;
|
import org.apache.hadoop.hdds.scm.container.ContainerMapping;
|
||||||
import org.apache.hadoop.hdds.scm.container.MockNodeManager;
|
import org.apache.hadoop.hdds.scm.container.MockNodeManager;
|
||||||
import org.apache.hadoop.hdds.scm.container.common.helpers.AllocatedBlock;
|
import org.apache.hadoop.hdds.scm.container.common.helpers.AllocatedBlock;
|
||||||
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
||||||
|
import org.apache.hadoop.hdds.scm.events.SCMEvents;
|
||||||
|
import org.apache.hadoop.hdds.scm.server.SCMStorage;
|
||||||
|
import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
|
||||||
|
import org.apache.hadoop.hdds.server.events.EventHandler;
|
||||||
|
import org.apache.hadoop.hdds.server.events.EventPublisher;
|
||||||
import org.apache.hadoop.hdds.server.events.EventQueue;
|
import org.apache.hadoop.hdds.server.events.EventQueue;
|
||||||
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
||||||
|
import org.apache.hadoop.ozone.common.Storage.StorageState;
|
||||||
import org.apache.hadoop.ozone.container.common.SCMTestUtils;
|
import org.apache.hadoop.ozone.container.common.SCMTestUtils;
|
||||||
import org.apache.hadoop.test.GenericTestUtils;
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
import org.junit.AfterClass;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
@ -40,6 +47,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ENABLED;
|
||||||
import static org.apache.hadoop.ozone.OzoneConsts.GB;
|
import static org.apache.hadoop.ozone.OzoneConsts.GB;
|
||||||
import static org.apache.hadoop.ozone.OzoneConsts.MB;
|
import static org.apache.hadoop.ozone.OzoneConsts.MB;
|
||||||
|
|
||||||
|
@ -47,7 +55,7 @@ import static org.apache.hadoop.ozone.OzoneConsts.MB;
|
||||||
/**
|
/**
|
||||||
* Tests for SCM Block Manager.
|
* Tests for SCM Block Manager.
|
||||||
*/
|
*/
|
||||||
public class TestBlockManager {
|
public class TestBlockManager implements EventHandler<Boolean> {
|
||||||
private static ContainerMapping mapping;
|
private static ContainerMapping mapping;
|
||||||
private static MockNodeManager nodeManager;
|
private static MockNodeManager nodeManager;
|
||||||
private static BlockManagerImpl blockManager;
|
private static BlockManagerImpl blockManager;
|
||||||
|
@ -56,26 +64,30 @@ public class TestBlockManager {
|
||||||
private static HddsProtos.ReplicationFactor factor;
|
private static HddsProtos.ReplicationFactor factor;
|
||||||
private static HddsProtos.ReplicationType type;
|
private static HddsProtos.ReplicationType type;
|
||||||
private static String containerOwner = "OZONE";
|
private static String containerOwner = "OZONE";
|
||||||
|
private static EventQueue eventQueue;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
@BeforeClass
|
|
||||||
public static void setUp() throws Exception {
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
Configuration conf = SCMTestUtils.getConf();
|
Configuration conf = SCMTestUtils.getConf();
|
||||||
|
|
||||||
String path = GenericTestUtils
|
String path = GenericTestUtils
|
||||||
.getTempPath(TestBlockManager.class.getSimpleName());
|
.getTempPath(TestBlockManager.class.getSimpleName());
|
||||||
|
|
||||||
conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, path);
|
|
||||||
testDir = Paths.get(path).toFile();
|
testDir = Paths.get(path).toFile();
|
||||||
|
conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, path);
|
||||||
|
eventQueue = new EventQueue();
|
||||||
boolean folderExisted = testDir.exists() || testDir.mkdirs();
|
boolean folderExisted = testDir.exists() || testDir.mkdirs();
|
||||||
if (!folderExisted) {
|
if (!folderExisted) {
|
||||||
throw new IOException("Unable to create test directory path");
|
throw new IOException("Unable to create test directory path");
|
||||||
}
|
}
|
||||||
nodeManager = new MockNodeManager(true, 10);
|
nodeManager = new MockNodeManager(true, 10);
|
||||||
mapping =
|
mapping = new ContainerMapping(conf, nodeManager, 128, eventQueue);
|
||||||
new ContainerMapping(conf, nodeManager, 128, new EventQueue());
|
blockManager = new BlockManagerImpl(conf,
|
||||||
blockManager = new BlockManagerImpl(conf, nodeManager, mapping, null);
|
nodeManager, mapping, eventQueue);
|
||||||
|
eventQueue.addHandler(SCMEvents.CHILL_MODE_STATUS, blockManager);
|
||||||
|
eventQueue.addHandler(SCMEvents.START_REPLICATION, this);
|
||||||
if(conf.getBoolean(ScmConfigKeys.DFS_CONTAINER_RATIS_ENABLED_KEY,
|
if(conf.getBoolean(ScmConfigKeys.DFS_CONTAINER_RATIS_ENABLED_KEY,
|
||||||
ScmConfigKeys.DFS_CONTAINER_RATIS_ENABLED_DEFAULT)){
|
ScmConfigKeys.DFS_CONTAINER_RATIS_ENABLED_DEFAULT)){
|
||||||
factor = HddsProtos.ReplicationFactor.THREE;
|
factor = HddsProtos.ReplicationFactor.THREE;
|
||||||
|
@ -86,27 +98,45 @@ public class TestBlockManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@After
|
||||||
public static void cleanup() throws IOException {
|
public void cleanup() throws IOException {
|
||||||
blockManager.close();
|
blockManager.close();
|
||||||
mapping.close();
|
mapping.close();
|
||||||
FileUtil.fullyDelete(testDir);
|
FileUtil.fullyDelete(testDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
private static StorageContainerManager getScm(OzoneConfiguration conf)
|
||||||
public void clearChillMode() {
|
throws IOException {
|
||||||
nodeManager.setChillmode(false);
|
conf.setBoolean(OZONE_ENABLED, true);
|
||||||
|
SCMStorage scmStore = new SCMStorage(conf);
|
||||||
|
if(scmStore.getState() != StorageState.INITIALIZED) {
|
||||||
|
String clusterId = UUID.randomUUID().toString();
|
||||||
|
String scmId = UUID.randomUUID().toString();
|
||||||
|
scmStore.setClusterId(clusterId);
|
||||||
|
scmStore.setScmId(scmId);
|
||||||
|
// writes the version file properties
|
||||||
|
scmStore.initialize();
|
||||||
|
}
|
||||||
|
return StorageContainerManager.createSCM(null, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllocateBlock() throws Exception {
|
public void testAllocateBlock() throws Exception {
|
||||||
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, false);
|
||||||
|
GenericTestUtils.waitFor(() -> {
|
||||||
|
return !blockManager.isScmInChillMode();
|
||||||
|
}, 10, 1000 * 5);
|
||||||
AllocatedBlock block = blockManager.allocateBlock(DEFAULT_BLOCK_SIZE,
|
AllocatedBlock block = blockManager.allocateBlock(DEFAULT_BLOCK_SIZE,
|
||||||
type, factor, containerOwner);
|
type, factor, containerOwner);
|
||||||
Assert.assertNotNull(block);
|
Assert.assertNotNull(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllocateOversizedBlock() throws IOException {
|
public void testAllocateOversizedBlock() throws Exception {
|
||||||
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, false);
|
||||||
|
GenericTestUtils.waitFor(() -> {
|
||||||
|
return !blockManager.isScmInChillMode();
|
||||||
|
}, 10, 1000 * 5);
|
||||||
long size = 6 * GB;
|
long size = 6 * GB;
|
||||||
thrown.expectMessage("Unsupported block size");
|
thrown.expectMessage("Unsupported block size");
|
||||||
AllocatedBlock block = blockManager.allocateBlock(size,
|
AllocatedBlock block = blockManager.allocateBlock(size,
|
||||||
|
@ -115,10 +145,31 @@ public class TestBlockManager {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChillModeAllocateBlockFails() throws IOException {
|
public void testAllocateBlockFailureInChillMode() throws Exception {
|
||||||
nodeManager.setChillmode(true);
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, true);
|
||||||
thrown.expectMessage("Unable to create block while in chill mode");
|
GenericTestUtils.waitFor(() -> {
|
||||||
|
return blockManager.isScmInChillMode();
|
||||||
|
}, 10, 1000 * 5);
|
||||||
|
// Test1: In chill mode expect an SCMException.
|
||||||
|
thrown.expectMessage("ChillModePrecheck failed for "
|
||||||
|
+ "allocateBlock");
|
||||||
blockManager.allocateBlock(DEFAULT_BLOCK_SIZE,
|
blockManager.allocateBlock(DEFAULT_BLOCK_SIZE,
|
||||||
type, factor, containerOwner);
|
type, factor, containerOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateBlockSucInChillMode() throws Exception {
|
||||||
|
// Test2: Exit chill mode and then try allocateBock again.
|
||||||
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, false);
|
||||||
|
GenericTestUtils.waitFor(() -> {
|
||||||
|
return !blockManager.isScmInChillMode();
|
||||||
|
}, 10, 1000 * 5);
|
||||||
|
Assert.assertNotNull(blockManager.allocateBlock(DEFAULT_BLOCK_SIZE,
|
||||||
|
type, factor, containerOwner));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(Boolean aBoolean, EventPublisher publisher) {
|
||||||
|
System.out.println("test");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.hdds.scm.container.replication;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import org.apache.hadoop.hdds.scm.events.SCMEvents;
|
||||||
|
import org.apache.hadoop.hdds.server.events.EventQueue;
|
||||||
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for ReplicationActivityStatus.
|
||||||
|
*/
|
||||||
|
public class TestReplicationActivityStatus {
|
||||||
|
|
||||||
|
private static EventQueue eventQueue;
|
||||||
|
private static ReplicationActivityStatus replicationActivityStatus;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
eventQueue = new EventQueue();
|
||||||
|
replicationActivityStatus = new ReplicationActivityStatus();
|
||||||
|
eventQueue.addHandler(SCMEvents.START_REPLICATION,
|
||||||
|
replicationActivityStatus.getReplicationStatusListener());
|
||||||
|
eventQueue.addHandler(SCMEvents.CHILL_MODE_STATUS,
|
||||||
|
replicationActivityStatus.getChillModeStatusListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReplicationStatusForChillMode()
|
||||||
|
throws TimeoutException, InterruptedException {
|
||||||
|
assertFalse(replicationActivityStatus.isReplicationEnabled());
|
||||||
|
// In chill mode replication process should be stopped.
|
||||||
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, true);
|
||||||
|
assertFalse(replicationActivityStatus.isReplicationEnabled());
|
||||||
|
|
||||||
|
// Replication should be enabled when chill mode if off.
|
||||||
|
eventQueue.fireEvent(SCMEvents.CHILL_MODE_STATUS, false);
|
||||||
|
GenericTestUtils.waitFor(() -> {
|
||||||
|
return replicationActivityStatus.isReplicationEnabled();
|
||||||
|
}, 10, 1000*5);
|
||||||
|
assertTrue(replicationActivityStatus.isReplicationEnabled());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue