数据中心的HBase(cdh3u3)集群已经稳定运行了差不多半年多了。由于前期规划的不合理,最近给所有的数据节点分批重装了一下系统,最后发现经常有几个节点出现磁盘空间不足的异常。查看文件系统,发现原来大约占用6T空间的HDFS已经占用了差不多15+T的数据
1、先用fsck进行文件系统检查,发现大约占用2T的空间(*3约等于6T,数据重量差不多就是这么多),并没有数据块有过多的备份。
2、查看对应datanode的数据目录,发现确实有很多的数据块(量非常大,都超过了实际hdfs中的数据块总量)
这时候,猜测应该是有很多需要被删除的数据块没有被删除。猜测可能是NameNode和DataNode之间的通讯出现异常导致。于是查看NameNode和DataNode日志,发现并没有任何异常信息,只是发现NameNode定时对其中的三台机器发出了删除指令
BLOCK* ask 192.168.200.8:50010 to delete blk_7080908721303033545_7530145
BLOCK* ask 192.168.200.9:50010 to delete blk_-6550808355677895247_7465333
BLOCK* ask 192.168.200.7:50010 to delete blk_2415291932316966347_7460687
其他节点则没有收到过相应的删除数据块的指令。因为所有节点的心跳一直没有问题,日志中也没有异常信息,一时想不到解决这个问题的办法。于是重启datanode,仍然无法删除过期的数据块。重启namenode,过了一段时间,发现数据量恢复正常了。
可是,过了一周发现同样的问题再次出现。google了一圈,只有在maillist中找到有人提到相关的问题,但是描述起来和我的情况并不完全一致:
Unbalanced Datanode
and Lots of Blocks
Waiting for Deletion
最后,通过dfsadmin证实了,确实是有大量的block在等待删除
hadoop dfsadmin -metasave meta.txt
meta.txt显示有:几十万的block等待删除
Metasave: Blocks 572428 waiting deletion from 8 datanodes.
4、没有办法,只好从源码着手。在FSNameSystem.java文件里面找到了最终问题的所在:
public int computeDatanodeWork() throws IOException {
int workFound = 0;
int blocksToProcess = 0;
int nodesToProcess = 0;
// blocks should not be replicated or removed if safe mode is on
if (isInSafeMode())
return workFound;
synchronized(heartbeats) {
blocksToProcess = (int)(heartbeats.size()
* ReplicationMonitor.REPLICATION_WORK_MULTIPLIER_PER_ITERATION);
nodesToProcess = (int)Math.ceil((double)heartbeats.size()
* ReplicationMonitor.INVALIDATE_WORK_PCT_PER_ITERATION / 100);
}
workFound = computeReplicationWork(blocksToProcess);
// Update FSNamesystemMetrics counters
synchronized (this) {
pendingReplicationBlocksCount = pendingReplications.size();
underReplicatedBlocksCount = neededReplications.size();
scheduledReplicationBlocksCount = workFound;
corruptReplicaBlocksCount = corruptReplicas.size();
}
workFound += computeInvalidateWork(nodesToProcess);
return workFound;
}
注意上面红色部分代码,computeInvalidateWork就是用于计算这次需要删除的数据块。但是并不是每次都把所有的节点都处理一遍,而是每次只处理nodesToProcess个节点,而这个数量决定于datanode的总数(heartbeats.size,我这儿是8)和一个系数(INVALIDATE_WORK_PCT_PER_ITERATION,写死的32)。
也就是说每次只处理
8*32% = 3(这就解释了为啥每次只删除三台数据节点上的数据块。)
再查看节点选择部分:
……
private Map<String, Collection<Block>> recentInvalidateSets =
new TreeMap<String, Collection<Block>>();
……
String firstNodeId = recentInvalidateSets.keySet().iterator().next();
……
发现是通过iterator遍历的,然后悲剧的发现recentInvalidateSets用的是TreeMap,也就是说是有序的……
所以只要这三个节点有数据需要删除,就不会删除到其他节点
这时候,发现这个问题是调整的时候,修改了一个配置项(dfs.replication.interval,默认是3秒,我修改成了30秒)导致的,当时修改的初衷是防止过早出现数据块复制。但是修改这个配置项以后,数据块副本数检查的间隔拉长了,导致30秒内,有几台机器一直有数据块需要删除,从而无法删除其他节点上的数据块,最终导致磁盘空间无法释放。因为INVALIDATE_WORK_PCT_PER_ITERATION是系统写死的,所以只能通过把dfs.replication.interval改回来,暂时解决这个问题。
ps:查了一下最新的1.0.4代码,这部分bug已经修复,改成随机抽取的模式,避免出现上述情况。(cdh3u4还存在这个问题)
分享到:
相关推荐
4.2.2 Datanode磁盘存储结构 315 4.2.3 DataStorage实现 317 4.3 文件系统数据集 334 4.3.1 Datanode上数据块副本的状态 335 4.3.2 BlockPoolSlice实现 335 4.3.3 FsVolumeImpl实现 342 4.3.4 ...
- **职责**:DataNode是集群中的“员工”,负责处理文件系统客户端或NameNode发送过来的指令,比如存储、检索和删除数据块等。 - **功能**: - 负责存储客户端发来的数据块block; - 执行数据块的读写操作。 ##...
在HDFS中,文件被分割成固定大小的块,这些块分布在集群的不同DataNode上。客户端在写入文件时,会先将文件块写入本地DataNode,然后将元数据信息更新到NameNode。读取文件时,NameNode会根据元数据信息指引客户端...
HDFS的基本架构主要由NameNode、DataNode和客户端三大部分组成: 1. **NameNode**:作为HDFS的主节点,负责管理文件系统的命名空间(目录和文件结构),以及文件块到DataNode的映射关系。它维护元数据信息,包括...
Hadoop Distributed File System (HDFS) 是Apache Hadoop项目的核心组件之一,是一个分布式文件系统,设计用于处理和存储大量数据。HDFS具有高容错性和高吞吐量的特点,非常适合在大规模集群环境中运行。以下是对...
6. 请求数据传输:客户端请求数据传输到DataNode,DataNode将数据写入磁盘。 7. 传输数据packet(chunk512+chunksum4byte):客户端将数据分割成小块,使用packet传输到DataNode。 8. 直到传输完成:客户端继续传输...
在HDFS中,当一个大文件需要存储时,例如10GB的文件,会在客户端被切割成多个128MB的Block块(可配置)。这些Block块会被分配到不同的DataNode节点上,通常每个Block有3个副本,以提高容错性。NameNode作为HDFS的主...
在分布式文件系统HDFS(Hadoop Distributed File System)中,数据的读写流程是其核心功能之一,确保了数据的安全性和高效性。本篇文章主要探讨HDFS的数据读写流程,特别是写数据的过程。 首先,我们关注HDFS的写...
HDFS中的文件以块的形式进行物理存储,块的大小可以通过配置参数`dfs.blocksize`来设定,默认情况下,在Hadoop 2.x版本中块大小为128MB,而在早期版本中则为64MB。实际生产环境中可以根据机器硬件性能进行调整。块的...
HDFS 中的 Block 数据块是以 blocks 分散在 DataNodes。通常,文件系统我们存放数据都是以一个 blocks 集进行存储,HDFS也是如此。在 hadoop 集群中,每个 block 的默认大小为 128M(此处指 hadoop 2.x 版本,hadoop...
- **分布式存储**: 数据被分割成Block(块)后分布存储在网络中的多个节点上。 - **主从结构**: HDFS采用主从(Master-Slave)架构,其中NameNode作为主节点负责管理文件系统的命名空间和客户端对文件的访问;...
HDFS(Hadoop Distributed File System)是Apache Hadoop项目的一个关键组成部分,它是一个高度容错性的系统,适合在廉价硬件上运行分布式存储大量数据集。本文将详细解析HDFS的安装部署及静态加密相关知识点。 ...
HDFS的设计还考虑了存储大文件的需求,它采用较大的块尺寸(默认为64MB,可在生产环境中调整到128MB、256MB、512MB等),这样做的好处是减少了磁盘寻道次数,提高了I/O性能。HDFS专为存储大文件设计,其数据块分布于...
namenode将这些元数据存储在内存中,为保证数据的安全性,也存储在磁盘上的两个文件中,即元数据镜像文件(fsimage)和数据操作日志文件(edits)。元数据的实时更新首先记录在edits文件中,然后定时与fsimage合并,...
- 描述:定义 DataNode 在本地磁盘中存放数据块的位置,可以通过逗号分隔多个目录。 - 示例:`dfs.data.dir=file:/opt/hadoop/tmp/dfs/data1,file:/opt/hadoop/tmp/dfs/data2` 4. **NameNode RPC 请求处理器线程...
9. **安全性与容错**:如果某个DataNode在写入过程中失败,HDFS会尝试在其他健康的DataNode上创建副本。客户端在写入期间会持续与NameNode交互,以获取最新的文件块位置信息。 10. **检查点**:为了防止NameNode的...
Client 端上传文件时,会将文件切分为多个 Block,然后将每个 Block 上传到多个 DataNode 中。 9. Hadoop 运行模式 Hadoop 可以运行在单机版、伪分布式和分布式三种模式下。 MapReduce 是 Hadoop 中的计算引擎,...
《Hadoop技术内幕:深入解析HADOOP COMMON和HDFS架构设计与实现原理》这本书是Hadoop技术领域的一本深入解析之作,它详尽地探讨了Hadoop的两大核心组件——HADOOP COMMON和HDFS(Hadoop Distributed File System)的...
HDFS(Hadoop Distributed File System)是Apache Hadoop项目的一个关键组成部分,它设计为分布式存储系统,旨在处理和存储大量数据。HDFS将大文件分割成块,并在多台机器上进行复制,以实现容错和高可用性。Hadoop ...