您的位置:首页 > Web前端 > Node.js

HDFS-datanode数据块部分笔记

2015-06-11 20:40 471 查看
之前在看查看datanode数据的时候觉得很奇怪,我在hdfs上有两个用户,一个是默认生成的http://master:9000/user/hduser,(其中master是linux下我的主机名hduser是linux下我的用户名)另一个是使用了hive存储之后hdfs自动建立的http://master:9000/user/hive。但是在datanode节点查看之后,总是找不到hive存储的文件,几番折腾之后终于弄清楚。
首先,数据存在哪里?
我们知道hadoop集群遵循的是主/从的架构,namenode很多时候都不作为文件的读写操作,只负责任务的调度和掌握数据块在哪些datanode的分布,保存的是一些数据结构,是namespace或者类似索引之类的东西,真正的数据存储和对数据的读写是发生在datanode里的。找到${HADOOP_HOME}/ect/hadoop/hdfs-site.xml文件,里面有你自己定义的dfs.datanode.data.dir一项就是你数据存放的位置。如果你没有修改过,就在放默认项,具体一些默认的配置可以查看这个文档 http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml [1]。进入datanode的数据目录之后,一层一层的cd直到找到真正数据所存放的地方。如图1所示。



图1

图1标红色框的就是datanode的数据路径,因人而异。除此之外,我们可以看到一系列blk_<数据块ID>的文件,这就是所谓的HDFS的数据块了。其实按照我自己的理解数据块并不是指操作系统中的文件系统里所说的扇区,数据块中的那个数据块。HDFS的数据块就是一个一个的文件,这个数据块文件大小有上限,默认值为64M(不一定的,下面会提到)。也就是说你一个数据文件假设有100M的大小,那么在HDFS中就需要两个数据块来存储,一个填满64M,剩下的36M存在另一个数据块。注意到,如果一个数据块写不满64M的话,会按照写入的数据的实际大小来存储而不会占用整个64M,也就是说系统不会给你分配64M在那里而不管你写不写满。而以blk_<数据块ID>为前缀、以.meta为后缀的文件是保存对应数据块的元数据,就是一些属性数据,校验码之类的信息。除此之外,还可以看到许多subdir为前缀的子目录。这是因为hdfs规定一个datanode下只能有64个数据块,超出的那部分hdfs会建立subdir0~63共64个子目录来存放。但是并不是每一个子目录下都存放了数据块,很多子目录里面都是空的。
除了上面的方法之外,还可以去hadoop的web页面下(http://master:50070)的hdfs查看你所存放的所有数据文件,而且更加的清晰简洁,包括文件的名称,用了多少个数据块存储,数据块的id,每个数据块写入数据的大小。如图2,图3所示。



图2



图3

进入图3之后看以看到在目录下所有的文件,点击图3名字叫做Name的那一栏的其中一个文件就会出现该文件的详细信息,包括使用了多少数据块来存储,每个数据块存储了多少数据量,数据块的ID ,你可以根据这个id找到图1对应的文件,即blk_<Block ID>文件。如上面说提到的,图1中并不是每一个subdir目录都有数据块文件,这就是为什么一开始我在web
ui上找到对应的文件的数据块ID,但是在datanode节点下却找不到这个ID号的数据文件,后来才发现subdir大部分是空目录,只有几个是放数据文件的,于是写了个简单的shell脚本把这几个放数据的目录找出来,然后进去这些目录,终于查看到数据。如图4所示



图4

part 1显示的是脚本代码,part 2是当前路径,part 3是列出非空的子目录。
但是我有两点不明白的,求指导
1、网上大部分资料都显示存放进hdfs的文件是以二进制数据的格式写进去的,但是我在datanode的blk_<block ID>下找到对应的文件都是我可以看得到原来文件内容的、而且是原来文件的格式的数据。
2、我自己上传存放的文件数目没有那么多,但是datanode下就已经有64个数据块文件,在这些数据块文件中的大部分很多才是以二进制格式显示,而我所上传的文件则按照原来的格式。所以,这些文件是什么?哪里来的?

其次,为什么数据块设置偏大?
关于这个问题,网上有很多相关的资料。hdfs默认的数据块文件大小是64M,官网也有提示可能是128M或者256M的,查看的话除了图3演示的方式,还可以直接在linux的shell下使用命令行:hdfs dfs -stat "%o" <path-to-file-in HDFS>,前提是HDFS集群已经启动(Tips: hdfs
command line [2])。如果你想修改数据块大小,可以在hadoop的hdfs-site.xml配置文件下添加属性dfs.blocksize。在文件[1]中也有相关说明。
hadoop和hdfs本身就是面向海量文件的,在数据量一定的条件下,数据块适当大一点,数据块的个数就少,于是:1)在进行磁盘搜索的时候,磁头寻址时间相对减少 2)这个原因更重要,namenode会将数据块的类似“inode”的信息放进内存,方便后面找到数据块,而每个这样的数据结构是150字节,因此,数据块个数少的话存在内存中的“inode”减少,处理的压力也减少。但是数据块大小也不是越大越好,要兼顾到每个块的传输效率。
这就是为什么hadoop适合存储个数相对少但单个文件数据量大,而不适合存储数量多但单个文件数据量小的文件,尽管可能两者在总量上一样大小。在这点上,淘宝针对自身的业务特点,为存储巨量的小图片开发的TFS(taobao file system)就很适合数量多而单个数据量小的类型文件。另外也有很多人提出合并的方法,也即在存储文件之前对文件大小做判断,如果size符合预设的阈值则直接存储,否则先对这些相对小的文件做合并形成大文件再存储。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: