HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,用于对海量数据的存储和管理,可以运行于廉价的服务器上,它的出现解决了海量非关系型的数据存储问题。
HDFS的优点
HDFS的缺点
读取数据
1.客户端发起RPC请求访问Namenode
2.namenode会查询元数据,找到这个文件的存储位置对应的数据块的信息。
3.namenode将文件对应的数据块的节点地址的全部或者部分放入一个队列中然后返回。
4.client收到这个数据块对应的节点地址
5.client会从队列中取出第一个数据块对应的节点地址,会从这些节点地址中选择一个最近的节点进行读取
6.将Block读取之后,对Block进行checksum的验证,如果验证失败,说明数据块产生损坏,那么client会向namenode发送信息说明该节点上的数据块损坏,然后从其他节点中再次读取这个数据块
7.验证成功,则从队列中取出下一个Block的地址,然后继续读取
8.当把这一次的文件块全部读完之后,client会向namenode要下一批block的地址
9.当把文件全部读取完成之后,从client会向namenode发送一个读取完毕的信号,namenode就会关闭对应的文件
写流程
1.client发送RPC请求给namenode
2.namenode接收到请求之后,对请求进行验证,例如这个请求中的文件是否存在,再例如权限验证
3.如果验证通过,namenode确定文件的大小以及分块的数量,确定对应的节点(会去找磁盘空间相对空闲的节点来使用),将节点地址放入队列中返回
4.客户端收到地址之后,从队列中依次取出节点地址,然后数据块依次放入对应的节点地址上
5.客户端在写完之后就会向namenode发送写完数据的信号,namenode会给客户端返回一个关闭文件的信号
6.datanode之间将会通过管道进行自动的备份,保证复本数量
删除流程
1.Client发起RPC请求到namenode
2.namenode收到请求之后,会将这个操作记录到edits中,然后将数据从内存中删掉,给客户端返回一个删除成功的信号
3.客户端收到信号之后认为数据已经删除,实际上数据依然存在datanode上
4.当datanode向namenode发送心跳消息(节点状态,节点数据)的时候,namenode就会检查这个datanode中的节点数据,发现datanode中的节点数据在namenode中的元数据中没有记录,namenode就会做出响应,就会命令对应的datanode删除指定的数据
hdfs的操作指令
hadoop fs -put a.txt /a.txt - 上传文件
hadoop fs -mkdir /hadoopnode01 - 创建目录
hadoop fs -rm /hadoop-2.7.1_64bit.tar.gz - 删除文件
hadoop fs -rmdir /hadoopnode01 - 删除目录
hadoop fs -rmr /a - 递归删除
hadoop fs -get /a.txt /home - 下载
hadoop fs -ls / - 查看
hadoop fs -lsr / - 递归查看
hadoop fs -cat /a.txt - 查看内容
hadoop fs -tail /a.txt - 产看文件的最后1000个字节
hadoop fs -mv /a/a.txt /a/b.txt - 移动或者重命名
hadoop fs -touchz /demo.txt - 创建空文件
hadoop fs -getmerge /a demo.txt - 合并下载
Hadoop插件的使用:
因为我使用的eclipse,所以就以eclipse为示例。。。
1.将前面hadoopbin_for_hadoop2.7.1.zip的安装包解压
2.复制hadoop-eclipse-plugin-2.7.1.jar
3.找到eclipse的安装目录,将插件复制到eclipse安装目录下的子目录plugins中
4.重启eclipse
5.在eclipse中指定hadoop的安装目录
6.Window -show view
7.需要添加环境变量:HADOOP_USER_NAME=用户名
HDFS的API操作(仅作了解,现在基本没人用这些方法了,有了上面的插件,上传和下载文件都非常方便)
下载:
@Test
public void get() throws IOException, URISyntaxException {
// 创建连接
// uri - 连接地址
// conf - 配置
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI(“hdfs://192.168.60.132:9000”), conf);
// 获取读取文件的流
InputStream in = fs.open(new Path("/a/a.txt"));
FileOutputStream out = new FileOutputStream(“a.txt”);
// 读取数据
byte[] bs = new byte[1024];
int len = -1;
while ((len = in.read(bs)) != -1) {
out.write(bs, 0, len);
}
out.close();
}
上传:
@Test
public void put() throws IOException, URISyntaxException, InterruptedException{
// 创建连接
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI(“hdfs://192.168.60.132:9000”), conf, “root”);
OutputStream out = fs.create(new Path("/a/c.txt"));
FileInputStream in = new FileInputStream(“c.txt”);
byte[] bs = new byte[1024];
int len = -1;
while ((len = in.read(bs)) != -1) {
out.write(bs, 0, len);
}
in.close();
}
以上,胡说八道之道请指出,不胜感激!!!