You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by bo...@apache.org on 2018/09/19 21:00:33 UTC
[23/50] [abbrv] hadoop git commit: HDDS-488. Handle chill mode
exception from SCM in OzoneManager. Contributed by Ajay Kumar.
HDDS-488. Handle chill mode exception from SCM in OzoneManager. Contributed by Ajay Kumar.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/39296537
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/39296537
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/39296537
Branch: refs/heads/YARN-7402
Commit: 39296537076d19b3713a75f8453d056884c49be6
Parents: 17f5651
Author: Xiaoyu Yao <xy...@apache.org>
Authored: Tue Sep 18 19:58:09 2018 -0700
Committer: Xiaoyu Yao <xy...@apache.org>
Committed: Tue Sep 18 20:05:25 2018 -0700
----------------------------------------------------------------------
.../hadoop/ozone/om/helpers/OmBucketInfo.java | 2 +-
.../hadoop/ozone/om/helpers/OmVolumeArgs.java | 2 +-
.../hadoop/ozone/om/TestScmChillMode.java | 171 +++++++++++++++++++
.../apache/hadoop/ozone/om/KeyManagerImpl.java | 32 +++-
.../hadoop/ozone/om/exceptions/OMException.java | 3 +-
.../hadoop/ozone/om/TestKeyManagerImpl.java | 165 ++++++++++++++++++
6 files changed, 367 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
index 0a136a7..5199ce3 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
@@ -167,7 +167,7 @@ public final class OmBucketInfo implements Auditable {
private StorageType storageType;
private long creationTime;
- Builder() {
+ public Builder() {
//Default values
this.acls = new LinkedList<>();
this.isVersionEnabled = false;
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
index 27e25f9..165d9ab 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
@@ -151,7 +151,7 @@ public final class OmVolumeArgs implements Auditable{
/**
* Constructs a builder.
*/
- Builder() {
+ public Builder() {
keyValueMap = new HashMap<>();
aclMap = new OmOzoneAclMap();
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestScmChillMode.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestScmChillMode.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestScmChillMode.java
new file mode 100644
index 0000000..954fa0f
--- /dev/null
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestScmChillMode.java
@@ -0,0 +1,171 @@
+/*
+ * 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.ozone.om;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.scm.container.common.helpers.ContainerInfo;
+import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
+import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.TestStorageContainerManagerHelper;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
+import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
+import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
+import org.apache.hadoop.test.GenericTestUtils;
+import org.apache.hadoop.test.LambdaTestUtils;
+import org.apache.hadoop.util.Time;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Test Ozone Manager operation in distributed handler scenario.
+ */
+public class TestScmChillMode {
+
+ private static MiniOzoneCluster cluster = null;
+ private static MiniOzoneCluster.Builder builder = null;
+ private static OzoneConfiguration conf;
+ private static OzoneManager om;
+
+
+ @Rule
+ public Timeout timeout = new Timeout(1000 * 200);
+
+ /**
+ * Create a MiniDFSCluster for testing.
+ * <p>
+ * Ozone is made active by setting OZONE_ENABLED = true and
+ * OZONE_HANDLER_TYPE_KEY = "distributed"
+ *
+ * @throws IOException
+ */
+ @Before
+ public void init() throws Exception {
+ conf = new OzoneConfiguration();
+ builder = MiniOzoneCluster.newBuilder(conf)
+ .setHbInterval(1000)
+ .setHbProcessorInterval(500)
+ .setStartDataNodes(false);
+ cluster = builder.build();
+ cluster.startHddsDatanodes();
+ cluster.waitForClusterToBeReady();
+ om = cluster.getOzoneManager();
+ }
+
+ /**
+ * Shutdown MiniDFSCluster.
+ */
+ @After
+ public void shutdown() {
+ if (cluster != null) {
+ cluster.shutdown();
+ }
+ }
+
+ @Test
+ public void testChillModeOperations() throws Exception {
+ final AtomicReference<MiniOzoneCluster> miniCluster =
+ new AtomicReference<>();
+
+ try {
+ // Create {numKeys} random names keys.
+ TestStorageContainerManagerHelper helper =
+ new TestStorageContainerManagerHelper(cluster, conf);
+ Map<String, OmKeyInfo> keyLocations = helper.createKeys(100, 4096);
+ final List<ContainerInfo> containers = cluster
+ .getStorageContainerManager()
+ .getScmContainerManager().getStateManager().getAllContainers();
+ GenericTestUtils.waitFor(() -> {
+ return containers.size() > 10;
+ }, 100, 1000);
+
+ String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+ String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
+ String keyName = "key" + RandomStringUtils.randomNumeric(5);
+ String userName = "user" + RandomStringUtils.randomNumeric(5);
+ String adminName = "admin" + RandomStringUtils.randomNumeric(5);
+ OmKeyArgs keyArgs = new OmKeyArgs.Builder()
+ .setVolumeName(volumeName)
+ .setBucketName(bucketName)
+ .setKeyName(keyName)
+ .setDataSize(1000)
+ .build();
+ OmVolumeArgs volArgs = new OmVolumeArgs.Builder()
+ .setAdminName(adminName)
+ .setCreationTime(Time.monotonicNow())
+ .setQuotaInBytes(10000)
+ .setVolume(volumeName)
+ .setOwnerName(userName)
+ .build();
+ OmBucketInfo bucketInfo = new OmBucketInfo.Builder()
+ .setBucketName(bucketName)
+ .setIsVersionEnabled(false)
+ .setVolumeName(volumeName)
+ .build();
+ om.createVolume(volArgs);
+ om.createBucket(bucketInfo);
+ om.openKey(keyArgs);
+ //om.commitKey(keyArgs, 1);
+
+ cluster.stop();
+
+ new Thread(() -> {
+ try {
+ miniCluster.set(builder.build());
+ } catch (IOException e) {
+ fail("failed");
+ }
+ }).start();
+
+ StorageContainerManager scm;
+ GenericTestUtils.waitFor(() -> {
+ return miniCluster.get() != null;
+ }, 100, 1000 * 3);
+
+ scm = miniCluster.get().getStorageContainerManager();
+ Assert.assertTrue(scm.isInChillMode());
+
+ om = miniCluster.get().getOzoneManager();
+
+ LambdaTestUtils.intercept(OMException.class,
+ "ChillModePrecheck failed for allocateBlock",
+ () -> om.openKey(keyArgs));
+
+ } finally {
+ if (miniCluster.get() != null) {
+ try {
+ miniCluster.get().shutdown();
+ } catch (Exception e) {
+ // do nothing.
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
index c14d0d8..41b391a 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
@@ -21,6 +21,7 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
import org.apache.hadoop.hdds.scm.container.common.helpers.AllocatedBlock;
+import org.apache.hadoop.hdds.scm.exceptions.SCMException;
import org.apache.hadoop.hdds.scm.protocol.ScmBlockLocationProtocol;
import org.apache.hadoop.hdfs.DFSUtil;
import org.apache.hadoop.ozone.OzoneConsts;
@@ -155,9 +156,18 @@ public class KeyManagerImpl implements KeyManager {
}
OmKeyInfo keyInfo =
OmKeyInfo.getFromProtobuf(KeyInfo.parseFrom(keyData));
- AllocatedBlock allocatedBlock =
- scmBlockClient.allocateBlock(scmBlockSize, keyInfo.getType(),
- keyInfo.getFactor(), omId);
+ AllocatedBlock allocatedBlock;
+ try {
+ allocatedBlock =
+ scmBlockClient.allocateBlock(scmBlockSize, keyInfo.getType(),
+ keyInfo.getFactor(), omId);
+ } catch (SCMException ex) {
+ if (ex.getResult()
+ .equals(SCMException.ResultCodes.CHILL_MODE_EXCEPTION)) {
+ throw new OMException(ex.getMessage(), ResultCodes.SCM_IN_CHILL_MODE);
+ }
+ throw ex;
+ }
OmKeyLocationInfo info = new OmKeyLocationInfo.Builder()
.setBlockID(allocatedBlock.getBlockID())
.setShouldCreateContainer(allocatedBlock.getCreateContainer())
@@ -208,8 +218,20 @@ public class KeyManagerImpl implements KeyManager {
// some blocks and piggyback to client, to save RPC calls.
while (requestedSize > 0) {
long allocateSize = Math.min(scmBlockSize, requestedSize);
- AllocatedBlock allocatedBlock =
- scmBlockClient.allocateBlock(allocateSize, type, factor, omId);
+ AllocatedBlock allocatedBlock;
+ try {
+ allocatedBlock = scmBlockClient
+ .allocateBlock(allocateSize, type, factor, omId);
+ } catch (IOException ex) {
+ if (ex instanceof SCMException) {
+ if (((SCMException) ex).getResult()
+ .equals(SCMException.ResultCodes.CHILL_MODE_EXCEPTION)) {
+ throw new OMException(ex.getMessage(),
+ ResultCodes.SCM_IN_CHILL_MODE);
+ }
+ }
+ throw ex;
+ }
OmKeyLocationInfo subKeyInfo = new OmKeyLocationInfo.Builder()
.setBlockID(allocatedBlock.getBlockID())
.setShouldCreateContainer(allocatedBlock.getCreateContainer())
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
index 55cef97..393ac91 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
@@ -113,6 +113,7 @@ public class OMException extends IOException {
FAILED_METADATA_ERROR,
FAILED_INTERNAL_ERROR,
OM_NOT_INITIALIZED,
- SCM_VERSION_MISMATCH_ERROR
+ SCM_VERSION_MISMATCH_ERROR,
+ SCM_IN_CHILL_MODE
}
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/39296537/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
----------------------------------------------------------------------
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
new file mode 100644
index 0000000..d722155
--- /dev/null
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
@@ -0,0 +1,165 @@
+/*
+ * 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.ozone.om;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
+import org.apache.hadoop.hdds.scm.exceptions.SCMException;
+import org.apache.hadoop.hdds.scm.exceptions.SCMException.ResultCodes;
+import org.apache.hadoop.hdds.scm.protocol.ScmBlockLocationProtocol;
+import org.apache.hadoop.hdfs.DFSUtil;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyInfo;
+import org.apache.hadoop.test.LambdaTestUtils;
+import org.apache.hadoop.util.Time;
+import org.apache.hadoop.utils.db.RDBStore;
+import org.apache.hadoop.utils.db.Table;
+import org.apache.hadoop.utils.db.TableConfig;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.Mockito;
+import org.rocksdb.ColumnFamilyOptions;
+import org.rocksdb.DBOptions;
+import org.rocksdb.RocksDB;
+import org.rocksdb.Statistics;
+import org.rocksdb.StatsLevel;
+
+/**
+ * Test class for @{@link KeyManagerImpl}.
+ * */
+public class TestKeyManagerImpl {
+
+ private static KeyManagerImpl keyManager;
+ private static ScmBlockLocationProtocol scmBlockLocationProtocol;
+ private static OzoneConfiguration conf;
+ private static OMMetadataManager metadataManager;
+ private static long blockSize = 1000;
+ private static final String KEY_NAME = "key1";
+ private static final String BUCKET_NAME = "bucket1";
+ private static final String VOLUME_NAME = "vol1";
+ private static RDBStore rdbStore = null;
+ private static Table rdbTable = null;
+ private static DBOptions options = null;
+ private KeyInfo keyData;
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Before
+ public void setUp() throws Exception {
+ conf = new OzoneConfiguration();
+ scmBlockLocationProtocol = Mockito.mock(ScmBlockLocationProtocol.class);
+ metadataManager = Mockito.mock(OMMetadataManager.class);
+ keyManager = new KeyManagerImpl(scmBlockLocationProtocol, metadataManager,
+ conf, "om1");
+ setupMocks();
+ }
+
+ private void setupMocks() throws Exception {
+ Mockito.when(scmBlockLocationProtocol
+ .allocateBlock(Mockito.anyLong(), Mockito.any(ReplicationType.class),
+ Mockito.any(ReplicationFactor.class), Mockito.anyString()))
+ .thenThrow(
+ new SCMException("ChillModePrecheck failed for allocateBlock",
+ ResultCodes.CHILL_MODE_EXCEPTION));
+ setupRocksDb();
+ Mockito.when(metadataManager.getVolumeTable()).thenReturn(rdbTable);
+ Mockito.when(metadataManager.getBucketTable()).thenReturn(rdbTable);
+ Mockito.when(metadataManager.getOpenKeyTable()).thenReturn(rdbTable);
+ Mockito.when(metadataManager.getLock())
+ .thenReturn(new OzoneManagerLock(conf));
+ Mockito.when(metadataManager.getVolumeKey(VOLUME_NAME))
+ .thenReturn(VOLUME_NAME.getBytes());
+ Mockito.when(metadataManager.getBucketKey(VOLUME_NAME, BUCKET_NAME))
+ .thenReturn(BUCKET_NAME.getBytes());
+ Mockito.when(metadataManager.getOpenKeyBytes(VOLUME_NAME, BUCKET_NAME,
+ KEY_NAME, 1)).thenReturn(KEY_NAME.getBytes());
+ }
+
+ private void setupRocksDb() throws Exception {
+ options = new DBOptions();
+ options.setCreateIfMissing(true);
+ options.setCreateMissingColumnFamilies(true);
+
+ Statistics statistics = new Statistics();
+ statistics.setStatsLevel(StatsLevel.ALL);
+ options = options.setStatistics(statistics);
+
+ Set<TableConfig> configSet = new HashSet<>();
+ for (String name : Arrays
+ .asList(DFSUtil.bytes2String(RocksDB.DEFAULT_COLUMN_FAMILY),
+ "testTable")) {
+ TableConfig newConfig = new TableConfig(name, new ColumnFamilyOptions());
+ configSet.add(newConfig);
+ }
+ keyData = KeyInfo.newBuilder()
+ .setKeyName(KEY_NAME)
+ .setBucketName(BUCKET_NAME)
+ .setVolumeName(VOLUME_NAME)
+ .setDataSize(blockSize)
+ .setType(ReplicationType.STAND_ALONE)
+ .setFactor(ReplicationFactor.ONE)
+ .setCreationTime(Time.now())
+ .setModificationTime(Time.now())
+ .build();
+
+ rdbStore = new RDBStore(folder.newFolder(), options, configSet);
+ rdbTable = rdbStore.getTable("testTable");
+ rdbTable.put(VOLUME_NAME.getBytes(),
+ RandomStringUtils.random(10).getBytes(StandardCharsets.UTF_8));
+ rdbTable.put(BUCKET_NAME.getBytes(),
+ RandomStringUtils.random(10).getBytes(StandardCharsets.UTF_8));
+ rdbTable.put(KEY_NAME.getBytes(), keyData.toByteArray());
+ }
+
+ @Test
+ public void allocateBlockFailureInChillMode() throws Exception {
+ OmKeyArgs keyArgs = new OmKeyArgs.Builder().setKeyName(KEY_NAME)
+ .setBucketName(BUCKET_NAME)
+ .setFactor(ReplicationFactor.ONE)
+ .setType(ReplicationType.STAND_ALONE)
+ .setVolumeName(VOLUME_NAME).build();
+ LambdaTestUtils.intercept(OMException.class,
+ "ChillModePrecheck failed for allocateBlock", () -> {
+ keyManager.allocateBlock(keyArgs, 1);
+ });
+ }
+
+ @Test
+ public void openKeyFailureInChillMode() throws Exception {
+ OmKeyArgs keyArgs = new OmKeyArgs.Builder().setKeyName(KEY_NAME)
+ .setBucketName(BUCKET_NAME)
+ .setFactor(ReplicationFactor.ONE)
+ .setDataSize(1000)
+ .setType(ReplicationType.STAND_ALONE)
+ .setVolumeName(VOLUME_NAME).build();
+ LambdaTestUtils.intercept(OMException.class,
+ "ChillModePrecheck failed for allocateBlock", () -> {
+ keyManager.openKey(keyArgs);
+ });
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org