背景
现在我们已经引入了HDFS-15150,我们可以开始改进一些DN操作来使用读锁而不是写入锁来提高并发。
第一步是对Replicamap进行更改
- ReplicaMap:一些方法会调用`replicmap .replicas()`(例如`getBlockReports`, `getFinalizedBlocks`, `deepCopyReplica`),并且只以只读方式使用,所以它们也可以切换到使用readLock。
接下来是目录扫描仪和磁盘均衡器,只需要读锁。
- `Disk Balancer`, `Directory Scanner`: Next is the directory scanner and disk balancer, which only require a read lock.
最后,FSDATASETIMPL在那里它相当明显,他们只需要读锁。
- BlockSender and fsdatasetImpl: where is it fairly obvious they only need a read lock.
分析
(1)ReplicaMap
该类维护副本的集合
- ReplicaInfo get(String bpid, long blockId) 方法写锁改为读锁
- int size(String bpid)方法写锁改为读锁
其他写相关依旧使用写锁
(2)DiskBalancer
- private Map<String, String> getStorageIDToVolumeBasePathMap() 锁改为读锁
(3)FsDatasetImpl
- public FsVolumeImpl getVolume(final ExtendedBlock b)写锁改为读锁
- public Block getStoredBlock(String bpid, long blkid)写锁改为读锁
- public Set<? extends Replica> deepCopyReplica(String bpid)写锁改为读锁
- public ReplicaInputStreams getTmpInputStreams 写锁改为读锁
- public ReplicaInfo moveBlockAcrossStorage 写锁改为读锁
- getBlockReports ...
- 其他方法
(3)BlockSender
配置
增加一项配置:开关 dn hdfs-site.xml中配置
<name>dfs.datanode.lock.read.write.enabled</name>
<value>true</value>
默认打开,如果开启则使用读写锁,如果关闭,所有的锁都是写锁。
FsDatasetImpl中
boolean enableRL = conf.getBoolean(
DFSConfigKeys.DFS_DATANODE_LOCK_READ_WRITE_ENABLED_KEY,
DFSConfigKeys.DFS_DATANODE_LOCK_READ_WRITE_ENABLED_DEFAULT);
// The read lock can be disabled by the above config key. If it is disabled
// then we simply make the both the read and write lock variables hold
// the write lock. All accesses to the lock are via these variables, so that
// effectively disables the read lock.
if (enableRL) {
LOG.info("The datanode lock is a read write lock");
this.datasetReadLock = new AutoCloseableLock(datasetRWLock.readLock());
} else {
LOG.info("The datanode lock is an exclusive write lock");
this.datasetReadLock = this.datasetWriteLock;
}
测试
- 单元测试通过