Skip to content

Commit 4f1fae8

Browse files
committed
HDFS-6670. Add block storage policy support with default HOT, WARM and COLD policies.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-6584@1610529 13f79535-47bb-0310-9956-ffa450edef68
1 parent 6f41baa commit 4f1fae8

File tree

9 files changed

+432
-2
lines changed

9 files changed

+432
-2
lines changed

hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ HDFS-6584: Archival Storage
55
HDFS-6677. Change INodeFile and FSImage to support storage policy ID.
66
(szetszwo)
77

8+
HDFS-6670. Add block storage policy support with default HOT, WARM and COLD
9+
policies. (szetszwo)
10+
811
Trunk (Unreleased)
912

1013
INCOMPATIBLE CHANGES
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.hdfs;
20+
21+
import java.util.Arrays;
22+
import java.util.EnumSet;
23+
24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
26+
import org.apache.hadoop.classification.InterfaceAudience;
27+
import org.apache.hadoop.conf.Configuration;
28+
29+
/**
30+
* A block storage policy describes how to select the storage types
31+
* for the replicas of a block.
32+
*/
33+
@InterfaceAudience.Private
34+
public class BlockStoragePolicy {
35+
public static final Log LOG = LogFactory.getLog(BlockStoragePolicy.class);
36+
37+
public static final String DFS_BLOCK_STORAGE_POLICIES_KEY
38+
= "dfs.block.storage.policies";
39+
public static final String DFS_BLOCK_STORAGE_POLICY_KEY_PREFIX
40+
= "dfs.block.storage.policy.";
41+
public static final String DFS_BLOCK_STORAGE_POLICY_CREATION_FALLBACK_KEY_PREFIX
42+
= "dfs.block.storage.policy.creation-fallback.";
43+
public static final String DFS_BLOCK_STORAGE_POLICY_REPLICATION_FALLBACK_KEY_PREFIX
44+
= "dfs.block.storage.policy.replication-fallback.";
45+
46+
public static final int ID_BIT_LENGTH = 4;
47+
public static final int ID_MAX = (1 << ID_BIT_LENGTH) - 1;
48+
49+
/** A 4-bit policy ID */
50+
private final byte id;
51+
/** Policy name */
52+
private final String name;
53+
54+
/** The storage types to store the replicas of a new block. */
55+
private final StorageType[] storageTypes;
56+
/** The fallback storage type for block creation. */
57+
private final StorageType[] creationFallbacks;
58+
/** The fallback storage type for replication. */
59+
private final StorageType[] replicationFallbacks;
60+
61+
BlockStoragePolicy(byte id, String name, StorageType[] storageTypes,
62+
StorageType[] creationFallbacks, StorageType[] replicationFallbacks) {
63+
this.id = id;
64+
this.name = name;
65+
this.storageTypes = storageTypes;
66+
this.creationFallbacks = creationFallbacks;
67+
this.replicationFallbacks = replicationFallbacks;
68+
}
69+
70+
/**
71+
* @return a list of {@link StorageType}s for storing the replicas of a block.
72+
*/
73+
StorageType[] getStoragteTypes(short replication) {
74+
final StorageType[] types = new StorageType[replication];
75+
int i = 0;
76+
for(; i < types.length && i < storageTypes.length; i++) {
77+
types[i] = storageTypes[i];
78+
}
79+
final StorageType last = storageTypes[storageTypes.length - 1];
80+
for(; i < types.length; i++) {
81+
types[i] = last;
82+
}
83+
return types;
84+
}
85+
86+
/** @return the fallback {@link StorageType} for creation. */
87+
StorageType getCreationFallback(EnumSet<StorageType> unavailables) {
88+
return getFallback(unavailables, creationFallbacks);
89+
}
90+
91+
/** @return the fallback {@link StorageType} for replication. */
92+
StorageType getReplicationFallback(EnumSet<StorageType> unavailables) {
93+
return getFallback(unavailables, replicationFallbacks);
94+
}
95+
96+
@Override
97+
public String toString() {
98+
return getClass().getSimpleName() + "{" + name + ":" + id
99+
+ ", storageTypes=" + Arrays.asList(storageTypes)
100+
+ ", creationFallbacks=" + Arrays.asList(creationFallbacks)
101+
+ ", replicationFallbacks=" + Arrays.asList(replicationFallbacks);
102+
}
103+
104+
private static StorageType getFallback(EnumSet<StorageType> unavailables,
105+
StorageType[] fallbacks) {
106+
for(StorageType fb : fallbacks) {
107+
if (!unavailables.contains(fb)) {
108+
return fb;
109+
}
110+
}
111+
return null;
112+
}
113+
114+
private static byte parseID(String string) {
115+
final byte id = Byte.parseByte(string);
116+
if (id < 1) {
117+
throw new IllegalArgumentException(
118+
"Invalid block storage policy ID: id = " + id + " < 1");
119+
}
120+
if (id > 15) {
121+
throw new IllegalArgumentException(
122+
"Invalid block storage policy ID: id = " + id + " > MAX = " + ID_MAX);
123+
}
124+
return id;
125+
}
126+
127+
private static StorageType[] parseStorageTypes(String[] strings) {
128+
if (strings == null) {
129+
return StorageType.EMPTY_ARRAY;
130+
}
131+
final StorageType[] types = new StorageType[strings.length];
132+
for(int i = 0; i < types.length; i++) {
133+
types[i] = StorageType.valueOf(strings[i].trim().toUpperCase());
134+
}
135+
return types;
136+
}
137+
138+
private static StorageType[] readStorageTypes(byte id, String keyPrefix,
139+
Configuration conf) {
140+
final String[] values = conf.getStrings(keyPrefix + id);
141+
return parseStorageTypes(values);
142+
}
143+
144+
public static BlockStoragePolicy readBlockStoragePolicy(byte id, String name,
145+
Configuration conf) {
146+
final StorageType[] storageTypes = readStorageTypes(id,
147+
DFS_BLOCK_STORAGE_POLICY_KEY_PREFIX, conf);
148+
final StorageType[] creationFallbacks = readStorageTypes(id,
149+
DFS_BLOCK_STORAGE_POLICY_CREATION_FALLBACK_KEY_PREFIX, conf);
150+
final StorageType[] replicationFallbacks = readStorageTypes(id,
151+
DFS_BLOCK_STORAGE_POLICY_REPLICATION_FALLBACK_KEY_PREFIX, conf);
152+
return new BlockStoragePolicy(id, name, storageTypes, creationFallbacks,
153+
replicationFallbacks);
154+
}
155+
156+
public static BlockStoragePolicy[] readBlockStoragePolicies(
157+
Configuration conf) {
158+
final BlockStoragePolicy[] policies = new BlockStoragePolicy[ID_MAX + 1];
159+
final String[] values = conf.getStrings(DFS_BLOCK_STORAGE_POLICIES_KEY);
160+
for(String v : values) {
161+
v = v.trim();
162+
final int i = v.indexOf(':');
163+
final String name = v.substring(0, i);
164+
final byte id = parseID(v.substring(i + 1));
165+
if (policies[id] != null) {
166+
throw new IllegalArgumentException(
167+
"Policy duplication: ID " + id + " appears more than once in "
168+
+ DFS_BLOCK_STORAGE_POLICIES_KEY);
169+
}
170+
policies[id] = readBlockStoragePolicy(id, name, conf);
171+
LOG.info(policies[id]);
172+
}
173+
return policies;
174+
}
175+
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSConfigKeys.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,15 @@ public class DFSConfigKeys extends CommonConfigurationKeys {
421421
public static final Class<BlockPlacementPolicyDefault> DFS_BLOCK_REPLICATOR_CLASSNAME_DEFAULT = BlockPlacementPolicyDefault.class;
422422
public static final String DFS_REPLICATION_MAX_KEY = "dfs.replication.max";
423423
public static final int DFS_REPLICATION_MAX_DEFAULT = 512;
424+
public static final String DFS_BLOCK_STORAGE_POLICIES_KEY
425+
= BlockStoragePolicy.DFS_BLOCK_STORAGE_POLICIES_KEY;
426+
public static final String DFS_BLOCK_STORAGE_POLICY_KEY_PREFIX
427+
= BlockStoragePolicy.DFS_BLOCK_STORAGE_POLICY_KEY_PREFIX;
428+
public static final String DFS_BLOCK_STORAGE_POLICY_CREATION_FALLBACK_KEY_PREFIX
429+
= BlockStoragePolicy.DFS_BLOCK_STORAGE_POLICY_CREATION_FALLBACK_KEY_PREFIX;
430+
public static final String DFS_BLOCK_STORAGE_POLICY_REPLICATION_FALLBACK_KEY_PREFIX
431+
= BlockStoragePolicy.DFS_BLOCK_STORAGE_POLICY_REPLICATION_FALLBACK_KEY_PREFIX;
432+
424433
public static final String DFS_DF_INTERVAL_KEY = "dfs.df.interval";
425434
public static final int DFS_DF_INTERVAL_DEFAULT = 60000;
426435
public static final String DFS_BLOCKREPORT_INTERVAL_MSEC_KEY = "dfs.blockreport.intervalMsec";

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/StorageType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
@InterfaceStability.Unstable
3030
public enum StorageType {
3131
DISK,
32-
SSD;
32+
SSD,
33+
ARCHIVE;
3334

3435
public static final StorageType DEFAULT = DISK;
36+
37+
public static final StorageType[] EMPTY_ARRAY = {};
3538
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/PBHelper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,8 @@ private static StorageTypeProto convertStorageType(
16121612
return StorageTypeProto.DISK;
16131613
case SSD:
16141614
return StorageTypeProto.SSD;
1615+
case ARCHIVE:
1616+
return StorageTypeProto.ARCHIVE;
16151617
default:
16161618
throw new IllegalStateException(
16171619
"BUG: StorageType not found, type=" + type);
@@ -1640,6 +1642,8 @@ private static StorageType convertType(StorageTypeProto type) {
16401642
return StorageType.DISK;
16411643
case SSD:
16421644
return StorageType.SSD;
1645+
case ARCHIVE:
1646+
return StorageType.ARCHIVE;
16431647
default:
16441648
throw new IllegalStateException(
16451649
"BUG: StorageTypeProto not found, type=" + type);

hadoop-hdfs-project/hadoop-hdfs/src/main/proto/hdfs.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ message FsPermissionProto {
134134
enum StorageTypeProto {
135135
DISK = 1;
136136
SSD = 2;
137+
ARCHIVE = 3;
137138
}
138139

139140
/**
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?xml version="1.0"?>
2+
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3+
4+
<!--
5+
Licensed to the Apache Software Foundation (ASF) under one or more
6+
contributor license agreements. See the NOTICE file distributed with
7+
this work for additional information regarding copyright ownership.
8+
The ASF licenses this file to You under the Apache License, Version 2.0
9+
(the "License"); you may not use this file except in compliance with
10+
the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing, software
15+
distributed under the License is distributed on an "AS IS" BASIS,
16+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
See the License for the specific language governing permissions and
18+
limitations under the License.
19+
-->
20+
21+
<!-- Do not modify this file directly. Instead, copy entries that you wish -->
22+
<!-- to modify from this file into blockStoragePolicy-site.xml and change -->
23+
<!-- there. If blockStoragePolicy-site.xml does not exist, create it. -->
24+
25+
<configuration>
26+
<property>
27+
<name>dfs.block.storage.policies</name>
28+
<value>HOT:12, WARM:8, COLD:4</value>
29+
<description>
30+
A list of block storage policy names and IDs. The syntax is
31+
32+
NAME_1:ID_1, NAME_2:ID_2, ..., NAME_n:ID_n
33+
34+
where ID is an integer in the range [1,15] and NAME is case insensitive.
35+
</description>
36+
</property>
37+
38+
<!-- Block Storage Policy HOT:12 -->
39+
<property>
40+
<name>dfs.block.storage.policy.12</name>
41+
<value>DISK</value>
42+
<description>
43+
A list of storage types for storing the block replicas such as
44+
45+
STORAGE_TYPE_1, STORAGE_TYPE_2, ..., STORAGE_TYPE_n
46+
47+
When creating a block, the i-th replica is stored using i-th storage type
48+
for i less than or equal to n, and
49+
the j-th replica is stored using n-th storage type for j greater than n.
50+
51+
The value cannot specified as an empty list.
52+
53+
Examples:
54+
DISK : all replicas stored using DISK.
55+
DISK, ARCHIVE : the first replica is stored using DISK and all the
56+
remaining are stored using ARCHIVE.
57+
</description>
58+
</property>
59+
60+
<property>
61+
<name>dfs.block.storage.policy.creation-fallback.12</name>
62+
<value></value>
63+
<description>
64+
A list of storage types for creation fallback storage.
65+
66+
STORAGE_TYPE_1, STORAGE_TYPE_2, ..., STORAGE_TYPE_n
67+
68+
When creating a block, if a particular storage type specified in the policy
69+
is unavailable, the fallback STORAGE_TYPE_1 is used. Further, if
70+
STORAGE_TYPE_i is also unavailable, the fallback STORAGE_TYPE_(i+1) is used.
71+
In case that all fallback storages are unavailabe, the block will be created
72+
with number of replicas less than the specified replication factor.
73+
74+
An empty list indicates that there is no fallback storage.
75+
</description>
76+
</property>
77+
78+
<property>
79+
<name>dfs.block.storage.policy.replication-fallback.12</name>
80+
<value>ARCHIVE</value>
81+
<description>
82+
Similar to dfs.block.storage.policy.creation-fallback.x but for replication.
83+
</description>
84+
</property>
85+
86+
<!-- Block Storage Policy WARM:8 -->
87+
<property>
88+
<name>dfs.block.storage.policy.8</name>
89+
<value>DISK, ARCHIVE</value>
90+
</property>
91+
92+
<property>
93+
<name>dfs.block.storage.policy.creation-fallback.8</name>
94+
<value>DISK, ARCHIVE</value>
95+
</property>
96+
97+
<property>
98+
<name>dfs.block.storage.policy.replication-fallback.8</name>
99+
<value>DISK, ARCHIVE</value>
100+
</property>
101+
102+
<!-- Block Storage Policy COLD:4 -->
103+
<property>
104+
<name>dfs.block.storage.policy.4</name>
105+
<value>ARCHIVE</value>
106+
</property>
107+
108+
<property>
109+
<name>dfs.block.storage.policy.creation-fallback.4</name>
110+
<value></value>
111+
</property>
112+
113+
<property>
114+
<name>dfs.block.storage.policy.replication-fallback.4</name>
115+
<value></value>
116+
</property>
117+
</configuration>

hadoop-hdfs-project/hadoop-hdfs/src/main/resources/hdfs-default.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
<!-- wish to modify from this file into hdfs-site.xml and change them -->
2323
<!-- there. If hdfs-site.xml does not already exist, create it. -->
2424

25-
<configuration>
25+
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
26+
<xi:include href="blockStoragePolicy-default.xml" />
2627

2728
<property>
2829
<name>hadoop.hdfs.configuration.version</name>

0 commit comments

Comments
 (0)