Skip to content

Commit e17c96a

Browse files
authored
HDFS-16429. Add DataSetLockManager to manage fine-grain locks for FsDataSetImpl. (#3900). Contributed by limingxiang.
Signed-off-by: He Xiaoqiao <[email protected]>
1 parent 6136d63 commit e17c96a

File tree

8 files changed

+637
-3
lines changed

8 files changed

+637
-3
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/LightWeightResizableGSet.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import org.apache.hadoop.HadoopIllegalArgumentException;
2121
import org.apache.hadoop.classification.InterfaceAudience;
2222

23+
import java.util.Iterator;
24+
import java.util.function.Consumer;
25+
2326
/**
2427
* A low memory footprint {@link GSet} implementation,
2528
* which uses an array for storing the elements
@@ -86,17 +89,36 @@ public LightWeightResizableGSet(int initCapacity) {
8689
}
8790

8891
@Override
89-
public E put(final E element) {
92+
public synchronized E put(final E element) {
9093
E existing = super.put(element);
9194
expandIfNecessary();
9295
return existing;
9396
}
9497

98+
@Override
99+
public synchronized E get(K key) {
100+
return super.get(key);
101+
}
102+
103+
@Override
104+
public synchronized E remove(K key) {
105+
return super.remove(key);
106+
}
107+
108+
@Override
109+
public synchronized int size() {
110+
return super.size();
111+
}
112+
113+
public synchronized void getIterator(Consumer<Iterator<E>> consumer) {
114+
consumer.accept(super.values().iterator());
115+
}
116+
95117
/**
96118
* Resize the internal table to given capacity.
97119
*/
98120
@SuppressWarnings("unchecked")
99-
protected void resize(int cap) {
121+
protected synchronized void resize(int cap) {
100122
int newCapacity = actualArrayLength(cap);
101123
if (newCapacity == this.capacity) {
102124
return;
@@ -121,7 +143,7 @@ protected void resize(int cap) {
121143
/**
122144
* Checks if we need to expand, and expands if necessary.
123145
*/
124-
protected void expandIfNecessary() {
146+
protected synchronized void expandIfNecessary() {
125147
if (size > this.threshold && capacity < MAX_ARRAY_LENGTH) {
126148
resize(capacity * 2);
127149
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,13 @@ public class DFSConfigKeys extends CommonConfigurationKeys {
16581658
DFS_NAMESERVICES_RESOLVER_IMPL =
16591659
"dfs.datanode.nameservices.resolver.impl";
16601660

1661+
public static final String
1662+
DFS_DATANODE_LOCKMANAGER_TRACE =
1663+
"dfs.datanode.lockmanager.trace";
1664+
1665+
public static final boolean
1666+
DFS_DATANODE_LOCKMANAGER_TRACE_DEFAULT = false;
1667+
16611668
// dfs.client.retry confs are moved to HdfsClientConfigKeys.Retry
16621669
@Deprecated
16631670
public static final String DFS_CLIENT_RETRY_POLICY_ENABLED_KEY
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
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.server.common;
20+
21+
import org.apache.hadoop.util.AutoCloseableLock;
22+
import org.apache.hadoop.util.StringUtils;
23+
24+
import java.util.concurrent.locks.Lock;
25+
26+
import static org.apache.hadoop.hdfs.server.datanode.DataSetLockManager.LOG;
27+
28+
/**
29+
* Extending AutoCloseableLock such that the users can
30+
* use a try-with-resource syntax.
31+
*/
32+
public class AutoCloseDataSetLock extends AutoCloseableLock {
33+
private Lock lock;
34+
private AutoCloseDataSetLock parentLock;
35+
private DataNodeLockManager<AutoCloseDataSetLock> dataNodeLockManager;
36+
37+
public AutoCloseDataSetLock(Lock lock) {
38+
this.lock = lock;
39+
}
40+
41+
@Override
42+
public void close() {
43+
if (lock != null) {
44+
lock.unlock();
45+
if (dataNodeLockManager != null) {
46+
dataNodeLockManager.hook();
47+
}
48+
} else {
49+
LOG.error("Try to unlock null lock" +
50+
StringUtils.getStackTrace(Thread.currentThread()));
51+
}
52+
if (parentLock != null) {
53+
parentLock.close();
54+
}
55+
}
56+
57+
/**
58+
* Actually acquire the lock.
59+
*/
60+
public void lock() {
61+
if (lock != null) {
62+
lock.lock();
63+
return;
64+
}
65+
LOG.error("Try to lock null lock" +
66+
StringUtils.getStackTrace(Thread.currentThread()));
67+
}
68+
69+
public void setParentLock(AutoCloseDataSetLock parent) {
70+
if (parentLock == null) {
71+
this.parentLock = parent;
72+
}
73+
}
74+
75+
public void setDataNodeLockManager(DataNodeLockManager<AutoCloseDataSetLock>
76+
dataNodeLockManager) {
77+
this.dataNodeLockManager = dataNodeLockManager;
78+
}
79+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
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.server.common;
20+
21+
/**
22+
* Use for manage a set of lock for datanode.
23+
*/
24+
public interface DataNodeLockManager<T extends AutoCloseDataSetLock> {
25+
26+
/**
27+
* Acquire block pool level first if you want to Acquire volume lock.
28+
* Or only acquire block pool level lock.
29+
*/
30+
enum LockLevel {
31+
BLOCK_POOl,
32+
VOLUME
33+
}
34+
35+
/**
36+
* Acquire readLock and then lock.
37+
*/
38+
T readLock(LockLevel level, String... resources);
39+
40+
/**
41+
* Acquire writeLock and then lock.
42+
*/
43+
T writeLock(LockLevel level, String... resources);
44+
45+
/**
46+
* Add a lock to LockManager.
47+
*/
48+
void addLock(LockLevel level, String... resources);
49+
50+
/**
51+
* Remove a lock from LockManager.
52+
*/
53+
void removeLock(LockLevel level, String... resources);
54+
55+
/**
56+
* LockManager may need to back hook.
57+
*/
58+
void hook();
59+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
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.server.common;
20+
21+
import java.util.concurrent.locks.Lock;
22+
23+
/**
24+
* Some ut or temp replicaMap not need to lock with DataSetLockManager.
25+
*/
26+
public class NoLockManager implements DataNodeLockManager<AutoCloseDataSetLock> {
27+
private final NoDataSetLock lock = new NoDataSetLock(null);
28+
29+
private static final class NoDataSetLock extends AutoCloseDataSetLock {
30+
31+
private NoDataSetLock(Lock lock) {
32+
super(lock);
33+
}
34+
35+
@Override
36+
public void lock() {
37+
}
38+
39+
@Override
40+
public void close() {
41+
}
42+
}
43+
44+
public NoLockManager() {
45+
}
46+
47+
@Override
48+
public AutoCloseDataSetLock readLock(LockLevel level, String... resources) {
49+
return lock;
50+
}
51+
52+
@Override
53+
public AutoCloseDataSetLock writeLock(LockLevel level, String... resources) {
54+
return lock;
55+
}
56+
57+
@Override
58+
public void addLock(LockLevel level, String... resources) {
59+
}
60+
61+
@Override
62+
public void removeLock(LockLevel level, String... resources) {
63+
}
64+
65+
@Override
66+
public void hook() {
67+
}
68+
}

0 commit comments

Comments
 (0)