HDDS-176. Add keyCount and container maximum size to ContainerData. Contributed by Bharat Viswanadham.
This commit is contained in:
parent
44b091a8d7
commit
e1f4b3b560
|
@ -53,12 +53,15 @@ public class ContainerData {
|
||||||
// State of the Container
|
// State of the Container
|
||||||
private ContainerLifeCycleState state;
|
private ContainerLifeCycleState state;
|
||||||
|
|
||||||
|
private final int maxSizeGB;
|
||||||
|
|
||||||
/** parameters for read/write statistics on the container. **/
|
/** parameters for read/write statistics on the container. **/
|
||||||
private final AtomicLong readBytes;
|
private final AtomicLong readBytes;
|
||||||
private final AtomicLong writeBytes;
|
private final AtomicLong writeBytes;
|
||||||
private final AtomicLong readCount;
|
private final AtomicLong readCount;
|
||||||
private final AtomicLong writeCount;
|
private final AtomicLong writeCount;
|
||||||
private final AtomicLong bytesUsed;
|
private final AtomicLong bytesUsed;
|
||||||
|
private final AtomicLong keyCount;
|
||||||
|
|
||||||
private HddsVolume volume;
|
private HddsVolume volume;
|
||||||
|
|
||||||
|
@ -67,8 +70,9 @@ public class ContainerData {
|
||||||
* Creates a ContainerData Object, which holds metadata of the container.
|
* Creates a ContainerData Object, which holds metadata of the container.
|
||||||
* @param type - ContainerType
|
* @param type - ContainerType
|
||||||
* @param containerId - ContainerId
|
* @param containerId - ContainerId
|
||||||
|
* @param size - container maximum size
|
||||||
*/
|
*/
|
||||||
public ContainerData(ContainerType type, long containerId) {
|
public ContainerData(ContainerType type, long containerId, int size) {
|
||||||
this.containerType = type;
|
this.containerType = type;
|
||||||
this.containerId = containerId;
|
this.containerId = containerId;
|
||||||
this.layOutVersion = ChunkLayOutVersion.getLatestVersion().getVersion();
|
this.layOutVersion = ChunkLayOutVersion.getLatestVersion().getVersion();
|
||||||
|
@ -79,6 +83,8 @@ public class ContainerData {
|
||||||
this.writeCount = new AtomicLong(0L);
|
this.writeCount = new AtomicLong(0L);
|
||||||
this.writeBytes = new AtomicLong(0L);
|
this.writeBytes = new AtomicLong(0L);
|
||||||
this.bytesUsed = new AtomicLong(0L);
|
this.bytesUsed = new AtomicLong(0L);
|
||||||
|
this.keyCount = new AtomicLong(0L);
|
||||||
|
this.maxSizeGB = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,9 +92,10 @@ public class ContainerData {
|
||||||
* @param type - ContainerType
|
* @param type - ContainerType
|
||||||
* @param containerId - ContainerId
|
* @param containerId - ContainerId
|
||||||
* @param layOutVersion - Container layOutVersion
|
* @param layOutVersion - Container layOutVersion
|
||||||
|
* @param size - Container maximum size
|
||||||
*/
|
*/
|
||||||
public ContainerData(ContainerType type, long containerId, int
|
public ContainerData(ContainerType type, long containerId, int
|
||||||
layOutVersion) {
|
layOutVersion, int size) {
|
||||||
this.containerType = type;
|
this.containerType = type;
|
||||||
this.containerId = containerId;
|
this.containerId = containerId;
|
||||||
this.layOutVersion = layOutVersion;
|
this.layOutVersion = layOutVersion;
|
||||||
|
@ -99,6 +106,8 @@ public class ContainerData {
|
||||||
this.writeCount = new AtomicLong(0L);
|
this.writeCount = new AtomicLong(0L);
|
||||||
this.writeBytes = new AtomicLong(0L);
|
this.writeBytes = new AtomicLong(0L);
|
||||||
this.bytesUsed = new AtomicLong(0L);
|
this.bytesUsed = new AtomicLong(0L);
|
||||||
|
this.keyCount = new AtomicLong(0L);
|
||||||
|
this.maxSizeGB = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,6 +142,14 @@ public class ContainerData {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return's maximum size of the container in GB.
|
||||||
|
* @return maxSizeGB
|
||||||
|
*/
|
||||||
|
public int getMaxSizeGB() {
|
||||||
|
return maxSizeGB;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the layOutVersion of the actual container data format.
|
* Returns the layOutVersion of the actual container data format.
|
||||||
* @return layOutVersion
|
* @return layOutVersion
|
||||||
|
@ -309,5 +326,34 @@ public class ContainerData {
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the number of keys in the container.
|
||||||
|
*/
|
||||||
|
public void incrKeyCount() {
|
||||||
|
this.keyCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrements number of keys in the container.
|
||||||
|
*/
|
||||||
|
public void decrKeyCount() {
|
||||||
|
this.keyCount.decrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns number of keys in the container.
|
||||||
|
* @return key count
|
||||||
|
*/
|
||||||
|
public long getKeyCount() {
|
||||||
|
return this.keyCount.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set's number of keys in the container.
|
||||||
|
* @param count
|
||||||
|
*/
|
||||||
|
public void setKeyCount(long count) {
|
||||||
|
this.keyCount.set(count);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -47,7 +48,6 @@ import org.yaml.snakeyaml.nodes.ScalarNode;
|
||||||
import org.yaml.snakeyaml.nodes.Tag;
|
import org.yaml.snakeyaml.nodes.Tag;
|
||||||
import org.yaml.snakeyaml.representer.Representer;
|
import org.yaml.snakeyaml.representer.Representer;
|
||||||
|
|
||||||
import static org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData.YAML_FIELDS;
|
|
||||||
import static org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData.YAML_TAG;
|
import static org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData.YAML_TAG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,10 +150,11 @@ public final class ContainerDataYaml {
|
||||||
// When a new Container type is added, we need to add what fields need
|
// When a new Container type is added, we need to add what fields need
|
||||||
// to be filtered here
|
// to be filtered here
|
||||||
if (type.equals(KeyValueContainerData.class)) {
|
if (type.equals(KeyValueContainerData.class)) {
|
||||||
|
List<String> yamlFields = KeyValueContainerData.getYamlFields();
|
||||||
// filter properties
|
// filter properties
|
||||||
for (Property prop : set) {
|
for (Property prop : set) {
|
||||||
String name = prop.getName();
|
String name = prop.getName();
|
||||||
if (YAML_FIELDS.contains(name)) {
|
if (yamlFields.contains(name)) {
|
||||||
filtered.add(prop);
|
filtered.add(prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,9 +184,12 @@ public final class ContainerDataYaml {
|
||||||
long layOutVersion = (long) nodes.get("layOutVersion");
|
long layOutVersion = (long) nodes.get("layOutVersion");
|
||||||
int lv = (int) layOutVersion;
|
int lv = (int) layOutVersion;
|
||||||
|
|
||||||
|
long size = (long) nodes.get("maxSizeGB");
|
||||||
|
int maxSize = (int) size;
|
||||||
|
|
||||||
//When a new field is added, it needs to be added here.
|
//When a new field is added, it needs to be added here.
|
||||||
KeyValueContainerData kvData = new KeyValueContainerData((long) nodes
|
KeyValueContainerData kvData = new KeyValueContainerData((long) nodes
|
||||||
.get("containerId"), lv);
|
.get("containerId"), lv, maxSize);
|
||||||
kvData.setContainerDBType((String)nodes.get("containerDBType"));
|
kvData.setContainerDBType((String)nodes.get("containerDBType"));
|
||||||
kvData.setMetadataPath((String) nodes.get(
|
kvData.setMetadataPath((String) nodes.get(
|
||||||
"metadataPath"));
|
"metadataPath"));
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.apache.hadoop.ozone.container.common.states.endpoint;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
|
||||||
import org.apache.hadoop.hdds.protocol.proto
|
import org.apache.hadoop.hdds.protocol.proto
|
||||||
.StorageContainerDatanodeProtocolProtos.SCMVersionResponseProto;
|
.StorageContainerDatanodeProtocolProtos.SCMVersionResponseProto;
|
||||||
import org.apache.hadoop.ozone.OzoneConsts;
|
import org.apache.hadoop.ozone.OzoneConsts;
|
||||||
|
@ -30,7 +29,6 @@ import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
|
||||||
import org.apache.hadoop.ozone.protocol.VersionResponse;
|
import org.apache.hadoop.ozone.protocol.VersionResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
@ -67,7 +65,6 @@ public class VersionEndpointTask implements
|
||||||
rpcEndPoint.setVersion(response);
|
rpcEndPoint.setVersion(response);
|
||||||
VolumeSet volumeSet = ozoneContainer.getVolumeSet();
|
VolumeSet volumeSet = ozoneContainer.getVolumeSet();
|
||||||
Map<String, HddsVolume> volumeMap = volumeSet.getVolumeMap();
|
Map<String, HddsVolume> volumeMap = volumeSet.getVolumeMap();
|
||||||
List<HddsProtos.KeyValue> keyValues = versionResponse.getKeysList();
|
|
||||||
|
|
||||||
String scmId = response.getValue(OzoneConsts.SCM_ID);
|
String scmId = response.getValue(OzoneConsts.SCM_ID);
|
||||||
String clusterId = response.getValue(OzoneConsts.CLUSTER_ID);
|
String clusterId = response.getValue(OzoneConsts.CLUSTER_ID);
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.hadoop.fs.FileUtil;
|
||||||
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
|
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
|
||||||
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos
|
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos
|
||||||
.ContainerLifeCycleState;
|
.ContainerLifeCycleState;
|
||||||
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
|
||||||
import org.apache.hadoop.hdds.scm.container.common.helpers
|
import org.apache.hadoop.hdds.scm.container.common.helpers
|
||||||
.StorageContainerException;
|
.StorageContainerException;
|
||||||
import org.apache.hadoop.io.IOUtils;
|
import org.apache.hadoop.io.IOUtils;
|
||||||
|
@ -84,7 +83,6 @@ public class KeyValueContainer implements Container {
|
||||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
private final KeyValueContainerData containerData;
|
private final KeyValueContainerData containerData;
|
||||||
private long containerMaxSize;
|
|
||||||
private Configuration config;
|
private Configuration config;
|
||||||
|
|
||||||
public KeyValueContainer(KeyValueContainerData containerData, Configuration
|
public KeyValueContainer(KeyValueContainerData containerData, Configuration
|
||||||
|
@ -95,9 +93,6 @@ public class KeyValueContainer implements Container {
|
||||||
"be null");
|
"be null");
|
||||||
this.config = ozoneConfig;
|
this.config = ozoneConfig;
|
||||||
this.containerData = containerData;
|
this.containerData = containerData;
|
||||||
this.containerMaxSize = (long) ozoneConfig.getInt(ScmConfigKeys
|
|
||||||
.OZONE_SCM_CONTAINER_SIZE_GB, ScmConfigKeys
|
|
||||||
.OZONE_SCM_CONTAINER_SIZE_DEFAULT) * 1024L * 1024L * 1024L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,9 +106,10 @@ public class KeyValueContainer implements Container {
|
||||||
File containerMetaDataPath = null;
|
File containerMetaDataPath = null;
|
||||||
//acquiring volumeset lock and container lock
|
//acquiring volumeset lock and container lock
|
||||||
volumeSet.acquireLock();
|
volumeSet.acquireLock();
|
||||||
|
long maxSize = (containerData.getMaxSizeGB() * 1024L * 1024L * 1024L);
|
||||||
try {
|
try {
|
||||||
HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume(volumeSet
|
HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume(volumeSet
|
||||||
.getVolumesList(), containerMaxSize);
|
.getVolumesList(), maxSize);
|
||||||
String containerBasePath = containerVolume.getHddsRootDir().toString();
|
String containerBasePath = containerVolume.getHddsRootDir().toString();
|
||||||
|
|
||||||
long containerId = containerData.getContainerId();
|
long containerId = containerData.getContainerId();
|
||||||
|
|
|
@ -39,9 +39,9 @@ public class KeyValueContainerData extends ContainerData {
|
||||||
public static final Tag YAML_TAG = new Tag("KeyValueContainerData");
|
public static final Tag YAML_TAG = new Tag("KeyValueContainerData");
|
||||||
|
|
||||||
// Fields need to be stored in .container file.
|
// Fields need to be stored in .container file.
|
||||||
public static final List<String> YAML_FIELDS = Lists.newArrayList(
|
private static final List<String> YAML_FIELDS = Lists.newArrayList(
|
||||||
"containerType", "containerId", "layOutVersion", "state", "metadata",
|
"containerType", "containerId", "layOutVersion", "state", "metadata",
|
||||||
"metadataPath", "chunksPath", "containerDBType");
|
"metadataPath", "chunksPath", "containerDBType", "maxSizeGB");
|
||||||
|
|
||||||
// Path to Container metadata Level DB/RocksDB Store and .container file.
|
// Path to Container metadata Level DB/RocksDB Store and .container file.
|
||||||
private String metadataPath;
|
private String metadataPath;
|
||||||
|
@ -60,9 +60,10 @@ public class KeyValueContainerData extends ContainerData {
|
||||||
/**
|
/**
|
||||||
* Constructs KeyValueContainerData object.
|
* Constructs KeyValueContainerData object.
|
||||||
* @param id - ContainerId
|
* @param id - ContainerId
|
||||||
|
* @param size - maximum size of the container
|
||||||
*/
|
*/
|
||||||
public KeyValueContainerData(long id) {
|
public KeyValueContainerData(long id, int size) {
|
||||||
super(ContainerProtos.ContainerType.KeyValueContainer, id);
|
super(ContainerProtos.ContainerType.KeyValueContainer, id, size);
|
||||||
this.numPendingDeletionBlocks = 0;
|
this.numPendingDeletionBlocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +71,11 @@ public class KeyValueContainerData extends ContainerData {
|
||||||
* Constructs KeyValueContainerData object.
|
* Constructs KeyValueContainerData object.
|
||||||
* @param id - ContainerId
|
* @param id - ContainerId
|
||||||
* @param layOutVersion
|
* @param layOutVersion
|
||||||
|
* @param size - maximum size of the container
|
||||||
*/
|
*/
|
||||||
public KeyValueContainerData(long id,
|
public KeyValueContainerData(long id, int layOutVersion, int size) {
|
||||||
int layOutVersion) {
|
super(ContainerProtos.ContainerType.KeyValueContainer, id, layOutVersion,
|
||||||
super(ContainerProtos.ContainerType.KeyValueContainer, id, layOutVersion);
|
size);
|
||||||
this.numPendingDeletionBlocks = 0;
|
this.numPendingDeletionBlocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,4 +207,8 @@ public class KeyValueContainerData extends ContainerData {
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getYamlFields() {
|
||||||
|
return YAML_FIELDS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos
|
||||||
.PutSmallFileRequestProto;
|
.PutSmallFileRequestProto;
|
||||||
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos
|
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos
|
||||||
.Type;
|
.Type;
|
||||||
|
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
|
||||||
import org.apache.hadoop.hdds.scm.container.common.helpers
|
import org.apache.hadoop.hdds.scm.container.common.helpers
|
||||||
.StorageContainerException;
|
.StorageContainerException;
|
||||||
import org.apache.hadoop.ozone.container.common.helpers.ChunkInfo;
|
import org.apache.hadoop.ozone.container.common.helpers.ChunkInfo;
|
||||||
|
@ -104,6 +105,7 @@ public class KeyValueHandler extends Handler {
|
||||||
private final KeyManager keyManager;
|
private final KeyManager keyManager;
|
||||||
private final ChunkManager chunkManager;
|
private final ChunkManager chunkManager;
|
||||||
private VolumeChoosingPolicy volumeChoosingPolicy;
|
private VolumeChoosingPolicy volumeChoosingPolicy;
|
||||||
|
private final int maxContainerSizeGB;
|
||||||
|
|
||||||
// TODO : Add metrics and populate it.
|
// TODO : Add metrics and populate it.
|
||||||
|
|
||||||
|
@ -125,6 +127,8 @@ public class KeyValueHandler extends Handler {
|
||||||
chunkManager = new ChunkManagerImpl();
|
chunkManager = new ChunkManagerImpl();
|
||||||
// TODO: Add supoort for different volumeChoosingPolicies.
|
// TODO: Add supoort for different volumeChoosingPolicies.
|
||||||
volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy();
|
volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy();
|
||||||
|
maxContainerSizeGB = config.getInt(ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE_GB,
|
||||||
|
ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -207,7 +211,7 @@ public class KeyValueHandler extends Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyValueContainerData newContainerData = new KeyValueContainerData(
|
KeyValueContainerData newContainerData = new KeyValueContainerData(
|
||||||
containerID);
|
containerID, maxContainerSizeGB);
|
||||||
// TODO: Add support to add metadataList to ContainerData. Add metadata
|
// TODO: Add support to add metadataList to ContainerData. Add metadata
|
||||||
// to container during creation.
|
// to container during creation.
|
||||||
KeyValueContainer newContainer = new KeyValueContainer(
|
KeyValueContainer newContainer = new KeyValueContainer(
|
||||||
|
@ -565,8 +569,8 @@ public class KeyValueHandler extends Handler {
|
||||||
try {
|
try {
|
||||||
checkContainerOpen(kvContainer);
|
checkContainerOpen(kvContainer);
|
||||||
|
|
||||||
BlockID blockID = BlockID.getFromProtobuf(
|
BlockID blockID = BlockID.getFromProtobuf(putSmallFileReq.getKey()
|
||||||
putSmallFileReq.getKey().getKeyData().getBlockID());
|
.getKeyData().getBlockID());
|
||||||
KeyData keyData = KeyData.getFromProtoBuf(
|
KeyData keyData = KeyData.getFromProtoBuf(
|
||||||
putSmallFileReq.getKey().getKeyData());
|
putSmallFileReq.getKey().getKeyData());
|
||||||
Preconditions.checkNotNull(keyData);
|
Preconditions.checkNotNull(keyData);
|
||||||
|
@ -613,8 +617,8 @@ public class KeyValueHandler extends Handler {
|
||||||
GetSmallFileRequestProto getSmallFileReq = request.getGetSmallFile();
|
GetSmallFileRequestProto getSmallFileReq = request.getGetSmallFile();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BlockID blockID = BlockID.getFromProtobuf(
|
BlockID blockID = BlockID.getFromProtobuf(getSmallFileReq.getKey()
|
||||||
getSmallFileReq.getKey().getBlockID());
|
.getBlockID());
|
||||||
KeyData responseData = keyManager.getKey(kvContainer, blockID);
|
KeyData responseData = keyManager.getKey(kvContainer, blockID);
|
||||||
|
|
||||||
ContainerProtos.ChunkInfo chunkInfo = null;
|
ContainerProtos.ChunkInfo chunkInfo = null;
|
||||||
|
|
|
@ -302,6 +302,7 @@ public final class KeyValueContainerUtil {
|
||||||
}
|
}
|
||||||
}).sum();
|
}).sum();
|
||||||
containerData.setBytesUsed(bytesUsed);
|
containerData.setBytesUsed(bytesUsed);
|
||||||
|
containerData.setKeyCount(liveKeys.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,9 @@ public class KeyManagerImpl implements KeyManager {
|
||||||
Preconditions.checkNotNull(db, "DB cannot be null here");
|
Preconditions.checkNotNull(db, "DB cannot be null here");
|
||||||
db.put(Longs.toByteArray(data.getLocalID()), data.getProtoBufMessage()
|
db.put(Longs.toByteArray(data.getLocalID()), data.getProtoBufMessage()
|
||||||
.toByteArray());
|
.toByteArray());
|
||||||
|
|
||||||
|
// Increment keycount here
|
||||||
|
container.getContainerData().incrKeyCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,6 +151,9 @@ public class KeyManagerImpl implements KeyManager {
|
||||||
NO_SUCH_KEY);
|
NO_SUCH_KEY);
|
||||||
}
|
}
|
||||||
db.delete(kKey);
|
db.delete(kKey);
|
||||||
|
|
||||||
|
// Decrement keycount here
|
||||||
|
container.getContainerData().decrKeyCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* 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.container.keyvalue.impl;
|
||||||
|
/**
|
||||||
|
This package contains chunk manager and key manager implementation for
|
||||||
|
keyvalue container type.
|
||||||
|
**/
|
|
@ -109,11 +109,9 @@ public class ContainerReader implements Runnable {
|
||||||
.getContainerFile(metadataPath, containerName);
|
.getContainerFile(metadataPath, containerName);
|
||||||
File checksumFile = KeyValueContainerLocationUtil
|
File checksumFile = KeyValueContainerLocationUtil
|
||||||
.getContainerCheckSumFile(metadataPath, containerName);
|
.getContainerCheckSumFile(metadataPath, containerName);
|
||||||
File dbFile = KeyValueContainerLocationUtil
|
if (containerFile.exists() && checksumFile.exists()) {
|
||||||
.getContainerDBFile(metadataPath, containerName);
|
verifyContainerFile(containerName, containerFile,
|
||||||
if (containerFile.exists() && checksumFile.exists() &&
|
checksumFile);
|
||||||
dbFile.exists()) {
|
|
||||||
verifyContainerFile(containerFile, checksumFile, dbFile);
|
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Missing container metadata files for Container: " +
|
LOG.error("Missing container metadata files for Container: " +
|
||||||
"{}", containerName);
|
"{}", containerName);
|
||||||
|
@ -129,8 +127,8 @@ public class ContainerReader implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyContainerFile(File containerFile, File checksumFile,
|
private void verifyContainerFile(String containerName, File containerFile,
|
||||||
File dbFile) {
|
File checksumFile) {
|
||||||
try {
|
try {
|
||||||
ContainerData containerData = ContainerDataYaml.readContainerFile(
|
ContainerData containerData = ContainerDataYaml.readContainerFile(
|
||||||
containerFile);
|
containerFile);
|
||||||
|
@ -139,6 +137,15 @@ public class ContainerReader implements Runnable {
|
||||||
case KeyValueContainer:
|
case KeyValueContainer:
|
||||||
KeyValueContainerData keyValueContainerData = (KeyValueContainerData)
|
KeyValueContainerData keyValueContainerData = (KeyValueContainerData)
|
||||||
containerData;
|
containerData;
|
||||||
|
File dbFile = KeyValueContainerLocationUtil
|
||||||
|
.getContainerDBFile(new File(containerFile.getParent()),
|
||||||
|
containerName);
|
||||||
|
if (!dbFile.exists()) {
|
||||||
|
LOG.error("Container DB file is missing for Container {}, skipping " +
|
||||||
|
"this", containerName);
|
||||||
|
// Don't further process this container, as it is missing db file.
|
||||||
|
return;
|
||||||
|
}
|
||||||
KeyValueContainerUtil.parseKeyValueContainerData(keyValueContainerData,
|
KeyValueContainerUtil.parseKeyValueContainerData(keyValueContainerData,
|
||||||
containerFile, checksumFile, dbFile, config);
|
containerFile, checksumFile, dbFile, config);
|
||||||
KeyValueContainer keyValueContainer = new KeyValueContainer(
|
KeyValueContainer keyValueContainer = new KeyValueContainer(
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
*/
|
*/
|
||||||
public class TestKeyValueContainerData {
|
public class TestKeyValueContainerData {
|
||||||
|
|
||||||
|
private static final int MAXSIZE = 5;
|
||||||
@Test
|
@Test
|
||||||
public void testKeyValueData() {
|
public void testKeyValueData() {
|
||||||
long containerId = 1L;
|
long containerId = 1L;
|
||||||
|
@ -42,7 +43,8 @@ public class TestKeyValueContainerData {
|
||||||
.ContainerLifeCycleState.CLOSED;
|
.ContainerLifeCycleState.CLOSED;
|
||||||
AtomicLong val = new AtomicLong(0);
|
AtomicLong val = new AtomicLong(0);
|
||||||
|
|
||||||
KeyValueContainerData kvData = new KeyValueContainerData(containerId);
|
KeyValueContainerData kvData = new KeyValueContainerData(containerId,
|
||||||
|
MAXSIZE);
|
||||||
|
|
||||||
assertEquals(containerType, kvData.getContainerType());
|
assertEquals(containerType, kvData.getContainerType());
|
||||||
assertEquals(containerId, kvData.getContainerId());
|
assertEquals(containerId, kvData.getContainerId());
|
||||||
|
@ -54,6 +56,8 @@ public class TestKeyValueContainerData {
|
||||||
assertEquals(val.get(), kvData.getWriteBytes());
|
assertEquals(val.get(), kvData.getWriteBytes());
|
||||||
assertEquals(val.get(), kvData.getReadCount());
|
assertEquals(val.get(), kvData.getReadCount());
|
||||||
assertEquals(val.get(), kvData.getWriteCount());
|
assertEquals(val.get(), kvData.getWriteCount());
|
||||||
|
assertEquals(val.get(), kvData.getKeyCount());
|
||||||
|
assertEquals(MAXSIZE, kvData.getMaxSizeGB());
|
||||||
|
|
||||||
kvData.setState(state);
|
kvData.setState(state);
|
||||||
kvData.setContainerDBType(containerDBType);
|
kvData.setContainerDBType(containerDBType);
|
||||||
|
@ -63,6 +67,7 @@ public class TestKeyValueContainerData {
|
||||||
kvData.incrWriteBytes(10);
|
kvData.incrWriteBytes(10);
|
||||||
kvData.incrReadCount();
|
kvData.incrReadCount();
|
||||||
kvData.incrWriteCount();
|
kvData.incrWriteCount();
|
||||||
|
kvData.incrKeyCount();
|
||||||
|
|
||||||
assertEquals(state, kvData.getState());
|
assertEquals(state, kvData.getState());
|
||||||
assertEquals(containerDBType, kvData.getContainerDBType());
|
assertEquals(containerDBType, kvData.getContainerDBType());
|
||||||
|
@ -73,6 +78,7 @@ public class TestKeyValueContainerData {
|
||||||
assertEquals(10, kvData.getWriteBytes());
|
assertEquals(10, kvData.getWriteBytes());
|
||||||
assertEquals(1, kvData.getReadCount());
|
assertEquals(1, kvData.getReadCount());
|
||||||
assertEquals(1, kvData.getWriteCount());
|
assertEquals(1, kvData.getWriteCount());
|
||||||
|
assertEquals(1, kvData.getKeyCount());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import static org.junit.Assert.fail;
|
||||||
*/
|
*/
|
||||||
public class TestContainerDataYaml {
|
public class TestContainerDataYaml {
|
||||||
|
|
||||||
|
private static final int MAXSIZE = 5;
|
||||||
@Test
|
@Test
|
||||||
public void testCreateContainerFile() throws IOException {
|
public void testCreateContainerFile() throws IOException {
|
||||||
String path = new FileSystemTestHelper().getTestRootDir();
|
String path = new FileSystemTestHelper().getTestRootDir();
|
||||||
|
@ -45,7 +46,8 @@ public class TestContainerDataYaml {
|
||||||
File filePath = new File(new FileSystemTestHelper().getTestRootDir());
|
File filePath = new File(new FileSystemTestHelper().getTestRootDir());
|
||||||
filePath.mkdirs();
|
filePath.mkdirs();
|
||||||
|
|
||||||
KeyValueContainerData keyValueContainerData = new KeyValueContainerData(Long.MAX_VALUE);
|
KeyValueContainerData keyValueContainerData = new KeyValueContainerData(
|
||||||
|
Long.MAX_VALUE, MAXSIZE);
|
||||||
keyValueContainerData.setContainerDBType("RocksDB");
|
keyValueContainerData.setContainerDBType("RocksDB");
|
||||||
keyValueContainerData.setMetadataPath(path);
|
keyValueContainerData.setMetadataPath(path);
|
||||||
keyValueContainerData.setChunksPath(path);
|
keyValueContainerData.setChunksPath(path);
|
||||||
|
@ -72,6 +74,7 @@ public class TestContainerDataYaml {
|
||||||
.getState());
|
.getState());
|
||||||
assertEquals(1, kvData.getLayOutVersion());
|
assertEquals(1, kvData.getLayOutVersion());
|
||||||
assertEquals(0, kvData.getMetadata().size());
|
assertEquals(0, kvData.getMetadata().size());
|
||||||
|
assertEquals(MAXSIZE, kvData.getMaxSizeGB());
|
||||||
|
|
||||||
// Update ContainerData.
|
// Update ContainerData.
|
||||||
kvData.addMetadata("VOLUME", "hdfs");
|
kvData.addMetadata("VOLUME", "hdfs");
|
||||||
|
@ -101,6 +104,7 @@ public class TestContainerDataYaml {
|
||||||
assertEquals(2, kvData.getMetadata().size());
|
assertEquals(2, kvData.getMetadata().size());
|
||||||
assertEquals("hdfs", kvData.getMetadata().get("VOLUME"));
|
assertEquals("hdfs", kvData.getMetadata().get("VOLUME"));
|
||||||
assertEquals("ozone", kvData.getMetadata().get("OWNER"));
|
assertEquals("ozone", kvData.getMetadata().get("OWNER"));
|
||||||
|
assertEquals(MAXSIZE, kvData.getMaxSizeGB());
|
||||||
|
|
||||||
FileUtil.fullyDelete(filePath);
|
FileUtil.fullyDelete(filePath);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class TestContainerSet {
|
||||||
ContainerProtos.ContainerLifeCycleState state = ContainerProtos
|
ContainerProtos.ContainerLifeCycleState state = ContainerProtos
|
||||||
.ContainerLifeCycleState.CLOSED;
|
.ContainerLifeCycleState.CLOSED;
|
||||||
|
|
||||||
KeyValueContainerData kvData = new KeyValueContainerData(containerId);
|
KeyValueContainerData kvData = new KeyValueContainerData(containerId, 5);
|
||||||
kvData.setState(state);
|
kvData.setState(state);
|
||||||
KeyValueContainer keyValueContainer = new KeyValueContainer(kvData, new
|
KeyValueContainer keyValueContainer = new KeyValueContainer(kvData, new
|
||||||
OzoneConfiguration());
|
OzoneConfiguration());
|
||||||
|
@ -163,7 +163,7 @@ public class TestContainerSet {
|
||||||
private ContainerSet createContainerSet() throws StorageContainerException {
|
private ContainerSet createContainerSet() throws StorageContainerException {
|
||||||
ContainerSet containerSet = new ContainerSet();
|
ContainerSet containerSet = new ContainerSet();
|
||||||
for (int i=0; i<10; i++) {
|
for (int i=0; i<10; i++) {
|
||||||
KeyValueContainerData kvData = new KeyValueContainerData(i);
|
KeyValueContainerData kvData = new KeyValueContainerData(i, 5);
|
||||||
if (i%2 == 0) {
|
if (i%2 == 0) {
|
||||||
kvData.setState(ContainerProtos.ContainerLifeCycleState.CLOSED);
|
kvData.setState(ContainerProtos.ContainerLifeCycleState.CLOSED);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class TestChunkManagerImpl {
|
||||||
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
||||||
.thenReturn(hddsVolume);
|
.thenReturn(hddsVolume);
|
||||||
|
|
||||||
keyValueContainerData = new KeyValueContainerData(1L);
|
keyValueContainerData = new KeyValueContainerData(1L, 5);
|
||||||
|
|
||||||
keyValueContainer = new KeyValueContainer(keyValueContainerData, config);
|
keyValueContainer = new KeyValueContainer(keyValueContainerData, config);
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class TestKeyManagerImpl {
|
||||||
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
||||||
.thenReturn(hddsVolume);
|
.thenReturn(hddsVolume);
|
||||||
|
|
||||||
keyValueContainerData = new KeyValueContainerData(1L);
|
keyValueContainerData = new KeyValueContainerData(1L, 5);
|
||||||
|
|
||||||
keyValueContainer = new KeyValueContainer(
|
keyValueContainer = new KeyValueContainer(
|
||||||
keyValueContainerData, config);
|
keyValueContainerData, config);
|
||||||
|
@ -104,9 +104,11 @@ public class TestKeyManagerImpl {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPutAndGetKey() throws Exception {
|
public void testPutAndGetKey() throws Exception {
|
||||||
|
assertEquals(0, keyValueContainer.getContainerData().getKeyCount());
|
||||||
//Put Key
|
//Put Key
|
||||||
keyManager.putKey(keyValueContainer, keyData);
|
keyManager.putKey(keyValueContainer, keyData);
|
||||||
|
|
||||||
|
assertEquals(1, keyValueContainer.getContainerData().getKeyCount());
|
||||||
//Get Key
|
//Get Key
|
||||||
KeyData fromGetKeyData = keyManager.getKey(keyValueContainer,
|
KeyData fromGetKeyData = keyManager.getKey(keyValueContainer,
|
||||||
keyData.getBlockID());
|
keyData.getBlockID());
|
||||||
|
@ -123,10 +125,13 @@ public class TestKeyManagerImpl {
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteKey() throws Exception {
|
public void testDeleteKey() throws Exception {
|
||||||
try {
|
try {
|
||||||
|
assertEquals(0, keyValueContainer.getContainerData().getKeyCount());
|
||||||
//Put Key
|
//Put Key
|
||||||
keyManager.putKey(keyValueContainer, keyData);
|
keyManager.putKey(keyValueContainer, keyData);
|
||||||
|
assertEquals(1, keyValueContainer.getContainerData().getKeyCount());
|
||||||
//Delete Key
|
//Delete Key
|
||||||
keyManager.deleteKey(keyValueContainer, blockID);
|
keyManager.deleteKey(keyValueContainer, blockID);
|
||||||
|
assertEquals(0, keyValueContainer.getContainerData().getKeyCount());
|
||||||
try {
|
try {
|
||||||
keyManager.getKey(keyValueContainer, blockID);
|
keyManager.getKey(keyValueContainer, blockID);
|
||||||
fail("testDeleteKey");
|
fail("testDeleteKey");
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class TestKeyValueContainer {
|
||||||
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
Mockito.when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong()))
|
||||||
.thenReturn(hddsVolume);
|
.thenReturn(hddsVolume);
|
||||||
|
|
||||||
keyValueContainerData = new KeyValueContainerData(1L);
|
keyValueContainerData = new KeyValueContainerData(1L, 5);
|
||||||
|
|
||||||
keyValueContainer = new KeyValueContainer(
|
keyValueContainer = new KeyValueContainer(
|
||||||
keyValueContainerData, conf);
|
keyValueContainerData, conf);
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class TestOzoneContainer {
|
||||||
volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy();
|
volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy();
|
||||||
|
|
||||||
for (int i=0; i<10; i++) {
|
for (int i=0; i<10; i++) {
|
||||||
keyValueContainerData = new KeyValueContainerData(i);
|
keyValueContainerData = new KeyValueContainerData(i, 1);
|
||||||
keyValueContainer = new KeyValueContainer(
|
keyValueContainer = new KeyValueContainer(
|
||||||
keyValueContainerData, conf);
|
keyValueContainerData, conf);
|
||||||
keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId);
|
keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId);
|
||||||
|
|
|
@ -5,6 +5,7 @@ containerId: 9223372036854775807
|
||||||
containerType: KeyValueContainer
|
containerType: KeyValueContainer
|
||||||
metadataPath: /hdds/current/aed-fg4-hji-jkl/containerdir0/1
|
metadataPath: /hdds/current/aed-fg4-hji-jkl/containerdir0/1
|
||||||
layOutVersion: 1
|
layOutVersion: 1
|
||||||
|
maxSizeGB: 5
|
||||||
metadata: {OWNER: ozone, VOLUME: hdfs}
|
metadata: {OWNER: ozone, VOLUME: hdfs}
|
||||||
state: CLOSED
|
state: CLOSED
|
||||||
aclEnabled: true
|
aclEnabled: true
|
|
@ -5,5 +5,6 @@ containerId: 9223372036854775807
|
||||||
containerType: KeyValueContainer
|
containerType: KeyValueContainer
|
||||||
metadataPath: /hdds/current/aed-fg4-hji-jkl/containerdir0/1
|
metadataPath: /hdds/current/aed-fg4-hji-jkl/containerdir0/1
|
||||||
layOutVersion: 1
|
layOutVersion: 1
|
||||||
|
maxSizeGB: 5
|
||||||
metadata: {OWNER: ozone, VOLUME: hdfs}
|
metadata: {OWNER: ozone, VOLUME: hdfs}
|
||||||
state: INVALID
|
state: INVALID
|
Loading…
Reference in New Issue