HDFS基本原理及数据存取实战

article/2025/10/24 4:06:27

---------------------------------------------------------------------------------------------------------------

[版权申明:本文系作者原创,转载请注明出处]

文章出处:http://blog.csdn.net/sdksdk0/article/details/51622547

作者:朱培

---------------------------------------------------------------------------------------------------------------


本文主要介绍了hdfs的基本原理、hdfs基本操作、hdfs的读取数据流程、namenode工作机制,rpc编程以及常见的两种必会的面试题等,旨在于全面深入的理解HDFS的基本工作流程并可以开发出简易的HDFS的程序。

一、HDFS简介

Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。HDFS体系结构中有两类节点,一类是NameNode,又叫"元数据节点";另一类是DataNode,又叫"数据节点"。这两类节点分别承担Master和Worker具体任务的执行节点。总的设计思想:分而治之——将大文件、大批量文件,分布式存放在大量独立的服务器上,以便于采取分而治之的方式对海量数据进行运算分析。

HDFS是一个主/从(Mater/Slave)体系结构,从最终用户的角度来看,它就像传统的文件系统一样,可以通过目录路径对文件执行CRUD(Create、Read、Update和Delete)操作。但由于分布式存储的性质,HDFS集群拥有一个NameNode和一些DataNode。NameNode管理文件系统的元数据,DataNode存储实际的数据。客户端通过同NameNode和DataNodes的交互访问文件系统。客户端联系NameNode以获取文件的元数据,而真正的文件I/O操作是直接和DataNode进行交互的。
HDFS一般是用来“一次写入,多次读取”,不适合做实时交互性很强的事情,不适合存储大量小文件(当然,如果你偏要存大量小文件的话本文末尾会有解决方案).

二、HDFS工作原理

2.1基本原理

1 分布式文件系统,它所管理的文件是被切块存储在若干台datanode服务器上.

2 hdfs提供了一个统一的目录树来定位hdfs中的文件,客户端访问文件时只要指定目录树的路径即可,不用关心文件的具体物理位置.

3 每一个文件的每一个切块,在hdfs集群中都可以保存多个备份(默认3份),在hdfs-site.xml中,dfs.replication的value的数量就是备份的数量.

4 hdfs中有一个关键进程服务进程:namenode,它维护了一个hdfs的目录树及hdfs目录结构与文件真实存储位置的映射关系(元数据).而datanode服务进程专门负责接收和管理"文件块"-block.默认大小为128M(可配置),(dfs.blocksize).(老版本的hadoop的默认block是64M的)


2.2 常用操作

hdfs的根目录,通过这条命令可以查看hdfs存储的文件,在hadoop的安装目录下面:
bin/hdfs dfs -ls /<pre name="code" class="html">hdfs dfs -chmod 600 /test.txt    //设置文件权限bin/hdfs dfs -df -h /    //查看磁盘空间bin/hdfs dfs -mkdir /aaa   //新建文件夹bin/hdfs dfs  -tail       //查看文件尾部
 hdfs块的存储位置位于:(在hadoop的根目录下面的tmp文件夹中)hadoop-2.5.2/tmp/hadoop/dfs/data/current/BP-33587274-127.0.0.1-1465370300743/current/finalized 

从图中我们可以看到hdfs存储的块的,当然这里面的两个块通过合并可以形成一个新的文件,然后可以通过解压进行验证。

touch full hadoop.tar.gz
cat blk_1073741825 >> hadoop.tar.gz
cat blk_1073741826 >> hadoop.tar.gz
tar -xvzf  hadoop.tar.gz 

同样,在hadoop的安装目录中,直接用命令来存取文件可以通过下面的命令:

存文件:
./hdfs dfs -put /home/admin1/桌面/test.txt  hdfs://localhost:9000/
取文件:
./hdfs dfs -get hdfs://localhost:9000/test.txt


hdfs的权限控制:

客户端的操作命令

bin/hdfs dfs -chown  aa:bgroup  /test.txt    

//将test.txt文件的权限改为aa用户的bgroup组.

(因为我根本就没有这个组和用户,但是也可以修改成功,所以说明hadoop本身对权限的控制不是很严格)

2.3 HDFS的shell操作

--appendToFile  ----追加一个文件到已经存在的文件末尾

-->hadoop fs  -appendToFile  ./hello.txt hdfs://hadoop-server01:9000/hello.txt

可以简写为:

Hadoop fs  -appendToFile  ./hello.txt /hello.txt

-cat  ---显示文件内容 

-->hadoop fs -cat /hello.txt

-chgrp

-chmod

-chown

上面三个跟linux中的用法一样

-->hadoop fs -chmod 666 /hello.txt

-copyFromLocal    #从本地文件系统中拷贝文件到hdfs路径去

-->hadoop fs  -copyFromLocal  ./jdk.tar.gz /aaa/

-copyToLocal      #从hdfs拷贝到本地

Eg: hadoop fs -copyToLocal /aaa/jdk.tar.gz

-count         #统计一个指定目录下的文件节点数量

-->hadoop fs -count /aaa/

-cp              #hdfs的一个路径拷贝hdfs的另一个路径

hadoop fs -cp/aaa/jdk.tar.gz /bbb/jdk.tar.gz.2

-createSnapshot

-deleteSnapshot

-renameSnapshot

以上三个用来操作hdfs文件系统目录信息快照

-->hadoop fs -createSnapshot /

-df               #统计文件系统的可用空间信息

-du

-->hadoop fs -df -h /

-->hadoop fs -du -s -h /aaa/*

-get              #等同于copyToLocal,就是从hdfs下载文件到本地

-getmerge             #合并下载多个文件

--> 比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...

hadoop fs -getmerge /aaa/log.* ./log.sum

-help             #输出这个命令参数手册

-ls                  #显示目录信息

-->hadoop fs -ls hdfs://hadoop-server01:9000/

这些参数中,所有的hdfs路径都可以简写

-->hadoop fs -ls /   等同于上一条命令的效果

-mkdir              #hdfs上创建目录

-->hadoop fs -mkdir -p /aaa/bbb/cc/dd

-moveFromLocal            #从本地剪切粘贴到hdfs

-moveToLocal              #从hdfs剪切粘贴到本地

-mv                     #hdfs目录中移动文件

-put                #等同于copyFromLocal

-rm                #删除文件或文件夹

--> hadoop fs -rm -r/aaa/bbb/

-rmdir                 #删除空目录

-setrep                #设置hdfs中文件的副本数量

-->hadoop fs -setrep 3 /aaa/jdk.tar.gz

-stat                  #显示一个文件或文件夹的元信息

-tail                  #显示一个文件的末尾

-text                  #以字符形式打印一个文件的内容


三、HDFS写入数据流程解析

3.1 基本原理

hdfs的数据写入是非常复杂的过程,下面来看一下简要的步骤。




那么问题来了,如果他们之间的一个datanode突然坏掉了怎么办。

1、如果传输过程中,有某个datanode出现了故障,那么当前的pipeline会被关闭,出现故障的datanode会从当前的pipeline中移除,剩余的block会继续剩下的datanode中继续以pipeline的形式传输,同时Namenode会分配一个新的datanode,保持replicas设定的数量。
2、关闭pipeline,将ack queue中的数据块放入data queue的开始。
3、当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。
4、失败的数据节点从pipeline中移除,另外的数据块则写入pipeline中的另外两个数据节点。
5、元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。
6、客户端调用create()来创建文件
7、DistributedFileSystem用RPC调用元数据节点,在文件系统的命名空间中创建一个新的文件。
8、元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。
9、DistributedFileSystem返回DFSOutputStream,客户端用于写数据。
10、客户端开始写入数据,DFSOutputStream将数据分成块,写入data queue。
11、Data queue由Data Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个pipeline里。
12、Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。
13、DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功。

3.2 编码实践

这段代码的意思是从/home/admin1/hadoop/eclipse.tar.gz上传文件到hdfs文件中,URI中写的是hdfs的地址
@Testpublic void testUpload() throws IOException, InterruptedException, URISyntaxException{Configuration conf = new Configuration();//to get a client of the hdfs systemFileSystem fs = FileSystem.get(new URI("hdfs://ubuntu2:9000"),conf,"admin1");fs.copyFromLocalFile(new Path("/home/admin1/hadoop/eclipse.tar.gz"), new Path("/"));fs.close();}


四、HDFS读取数据流程解析

4.1 基本原理

读取的流程比写入的流程就简单很多了。



4.2 编码实践

下载文件:
/*public static void main(String[] args) throws IOException {//download  from hdfsConfiguration conf = new Configuration();conf.set("fs.defaultFS", "hdfs://ubuntu2:9000/");conf.set("dfs.blocksize", "64");//to get a client of the hdfs systemFileSystem fs = FileSystem.get(conf);fs.copyToLocalFile(new Path("hdfs://ubuntu2:9000/test.txt"), new Path("/home/admin1/Downloads/test1.txt"));fs.close();}*/
删除文件:
@Testpublic void rmove() throws IOException, InterruptedException, URISyntaxException{Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://ubuntu2:9000"),conf,"admin1");fs.delete(new Path("/test.txt"));fs.close();}


五、NameNode工作机制

元数据放在内存中,同时需要备份,通过日志的记录(对元数据有修改操作时)写到磁盘中,用edits_ingropress,定期dump一次,当一旦断电时,很难恢复,
所以我们就用sercondName定期把操作日志下载和内存镜像文件,然后就定期合并操作记录,(日志+fsimage)然后生成一个新的namenode镜像文件  (fs.image.ckpt)
最后上传给namenode,然后namenode重命名为fsimage.


元数据管理机制:
1、元数据有3中存储形式:内存、edits日志、fsimage
2、最完整最新的元数据一定是内存中的这一部分

六、RPC编程

使用 RPC 编程是在客户机和服务器实体之间进行可靠通信的最强大、最高效的方法之一。它为在分布式计算环境中运行的几乎所有应用程序提供基础。任何 RPC 客户机-服务器程序的重要实体都包括 IDL 文件(接口定义文件)、客户机 stub、服务器 stub 以及由客户机和服务器程序共用的头文件。客户机和服务器 stub 使用 RPC 运行时库通信。RPC 运行时库提供一套标准的运行时例程来支持 RPC 应用程序。在一般的应用程序中,被调用的过程在相同的地址空间中运行,并把结果返回给发出调用的过程。在分布式环境中,客户机和服务器在不同的机器上运行,客户端调用在服务器端运行的过程,并把结果发送回客户机。这称为远程过程调用 (RPC),是 RPC 编程的基础。

以下实例是用来模拟用户登陆的过程。

在linux中的eclipse。新建一个java工程,新建java文件:

RPCServer.java

package hdfsTest;public interface  RPCService {public static final long versionID=100L;  //定义通信接口的版本号public String userLogin(String username,String password);  //用户名和密码}
RPCServerImpl.java

package hdfsTest;public class RPCServiceImpl  implements RPCService {@Overridepublic String userLogin(String username, String password) {	return username+"  logged in successfully!";}
}

RPCControl.java

package hdfsTest;import java.io.IOException;
import java.net.InetSocketAddress;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;//
public class RPCController {public static void main(String[] args) throws IOException {RPCService serverceImpl=RPC.getProxy(RPCService.class,100,new InetSocketAddress("ubuntu2",10000),new Configuration());
<span style="white-space:pre">		</span>//100是指前面设置的版本号,InetSocketAddress中的是hdfs主机名和10000是通信端口String result=serverceImpl.userLogin("aaa", "aaa");  //设置用户用户名和密码System.out.println(result);   }
}


ServerRunner.java
package hdfsTest;import java.io.IOException;import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Builder;
import org.apache.hadoop.ipc.Server;public class ServerRunner {public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {Builder builder=new RPC.Builder(new Configuration());builder.setBindAddress("ubuntu2");  //hdfs的主机名builder.setPort(10000);    //设置通信端口号builder.setProtocol(RPCService.class);builder.setInstance(new RPCServiceImpl());Server server=builder.build();server.start();   //开启服务}
}

运行结果:



七、常见问题分析

7.1.HDFS可不可以用来做网盘

答案:不可以,
网盘只存储,不用做分析,hdfs在增加节点,同时也加大了分析能力,主要是大容量存储之上的数据分析
1、容量成本太高,2、文件大小不确定,如果存大量小文件会造成很大的浪费 3、相对于网盘来说,文件读写的效率低  4、只适合一次写入,多次读取的操作
5、hdfs不支持文件内容修改,可支持往文件尾部追加内容。

7.2 HDFS大量小文件存储

1、对于待上传的文件,先将小文件合并为一个大文件再上传,利用SequenceFile、MapFile、Har等方式归档小文件,这个方法的原理就是把小文件归档起来管理,HBase就是基于此的。对于这种方法,如果想找回原来的小文件内容,那就必须得知道与归档文件的映射关系。
2、如果对于已经上传了的文件,需要进行合并的话,我们可以使用Map-redure来进行归档。
3、BlueSky解决方案,以一种two-level prefetching机制以提高小文件读取效率,即索引文件预取和数据文件预取。索引文件预取是指当用户访问某个文件时,该文件所在的block对应的索引文件被加载到内存中,这样,用户访问这些文件时不必再与namenode交互了。数据文件预取是指用户访问某个文件时,将该文件所在课件中的所有文件加载到内存中,这样,如果用户继续访问其他文件,速度会明显提高。




http://chatgpt.dhexx.cn/article/qsMPZlZH.shtml

相关文章

QT的开发学习路线

基础组件&#xff1b;页面布局&#xff1b;通信机制&#xff1b;

QT的学习

QT是利用C进行编写&#xff0c;而QT则是C的实际运用的一种方式。 QT也称GUI------grphical user interface&#xff08;图形用户接口&#xff09; 通过图形的方式操纵计算机用户界面 QT的特点以及应用&#xff1a; 1、跨平台&#xff08;可以在多个平台上进操作&#xff08…

Qt 学习之路 2 --- 读书笔记

一、文章来由 来自豆子老师非常好的一本Qt教程&#xff0c;但是只有网络版&#xff0c;所以用这个做笔记了&#xff0c;不动笔墨不读书嘛~~ 二、读书笔记 1、Qt 学习之路 2&#xff08;2&#xff09;&#xff1a;Qt 简介 1.1 关于 Qt 的一站式解决 Qt 是一个著名的 C 应用…

Qt学习之路之 QTextEdit 重温

其实&#xff0c;QTextEdit 也有对文本的编辑函数&#xff0c; 剪切&#xff0c;复制&#xff0c;撤销..... 看看下面的这个简单的例子&#xff1a; 控件一目了然。按钮 QTextedit 对象 &#xff0c; 垂直布局。 -------------------------------------------------- 环境&…

QT的进一步学习

QT的进一步学习 来源: ChinaUnix博客  日期&#xff1a; 2006.10.02 17:41 (共有条评论) 我要评论 本文收录了互联…

Qt学习之路之QMovie动画

QMovie类是一个很方便的类&#xff0c;用于播放动画。在刷新页面的时候&#xff0c;可以尝试用QMovie 来实现等待界面。 QMovie类用于显示简单的动画&#xff0c;没有声音。 首先&#xff0c;通过将一个文件的名称或者一个指针传递给QMovie的构造函数构建一个QMovie对象。传递…

QT学习之路-记事本

1、在创建记事本之前先明白有哪些功能&#xff1a; 先创建一个菜单栏&#xff0c;菜单栏是用来装各种功能的一个地方如上图所示&#xff0c;文件、编辑所在的地方为菜单栏&#xff0c; //创建菜单栏QMenuBar *menubarmenuBar();菜单栏创建好后再创建菜单&#xff0c;菜单在菜单…

QT学习

文章目录 前言一&#xff1a;Qt的三个基类QObject、QApplication和QWidget一&#xff1a;QObject类二&#xff1a;Qapplication类三&#xff1a;QWidget 二&#xff1a;Qt中QMainWindow、QWidget、QDialog的区别基础知识1&#xff1a;容器类常用的QListQStack和QQueueMap和Mult…

【QT学习之路】QThread的简单使用

QThread的使用说明&#xff1a;QThread线程类是QT已经封装好的&#xff0c; 如果要使用线程&#xff0c; 就派生出子类并且实现线程接口函数run&#xff08;run就是线程任务函数&#xff09; 下面就用QThread实现当前系统时间的获取并且在主界面(UI线程)上显示&#xff0c;实现…

【QT学习之路,QT安装】

1&#xff0c;安装QT 系统环境&#xff1a;ubuntu 22.04 sudo apt-get install build-essential sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools sudo apt-get install qtcreator sudo apt-get install qt5* 2&#xff0c;安装成功后会有4个程序 3…

qt学习之路(三)之使用QT语言家

一、简介 源代码中经常会出现一些字符串&#xff0c;比如定义要显示在控件上的文本&#xff0c;在不同的语言环境下&#xff0c;可能会需要显示不同语言对应的文本。针对多语言切换的需求&#xff0c;Qt提供的解决方案是&#xff0c;在所有需要翻译的字符串处都使用QObject::tr…

QT学习(2)

事件 事件与信号的关系&#xff1f;&#xff1f; 点击按钮&#xff0c;也会进入到事件循环&#xff0c;处理槽函数 事件对操作系统而言 事件大部分都是由硬件触发&#xff1b;事件产生&#xff0c;操作系统是知道的 鼠标移动&#xff1a; 事件在qt中是由多态去实现的&#xf…

Qt 进阶之路

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 古语有云&#xff1a;“工欲善其事&#xff0c;必先利其器”。一件好的开发工具可以帮助开发者快速、准确的完成任务。博主主要从…

Qt 入门学习路线

参考书目 《C GUI Qt4编程》 一、Qt框架概述 1. 什么是Qt? Qt是一个用C编写的、成熟的、跨平台的GUI工具包&#xff0c;它是挪威Trolltech公司的产品&#xff0c;该公司为商业市场开发、销售和支持Qt及其相关软件。 Qt作为一个出色的软件框架&#xff0c;除了为应用程序提供…

《Qt基础教程之Qt学习之路》

在Qt开源社区中&#xff0c;有一个很好的Qt教程&#xff0c;叫做《Qt 学习之路》&#xff0c;下面是它的链接和目录。 链接地址&#xff1a;http://www.qter.org/thread-629-1-1.html 评论区说上面这个地址打不开&#xff0c;有可能没人管理了。可以试一下面的&#xff1a; h…

Qt学习之路 (一)概述

Qt&#xff08;官方发音 [kju:t]&#xff0c;音同 cute&#xff09;是一个跨平台的 C 开发库&#xff0c;主要用来开发图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;程序&#xff0c;当然也可以开发不带界面的命令行&#xff08;Command User …

QT学习之路

文章目录 一、QT简单介绍二、.pro文件介绍三、 命名规范和常用快捷键以及QPushButton简单使用登录窗口布局控件--按钮组其他常用控件介绍自定义控件封装Qt中的鼠标事件定时器一定时器二event事件分发器事件过滤器绘图事件绘图高级设置绘图设备QFile文件读写操作QFileInfo文件信…

在自己电脑上搭建一个FTP服务器

在自己电脑上搭建一个FTP服务器 因为项目需要&#xff0c;第一次搭建FTP&#xff0c;也是在博客上找的经验&#xff0c;写这篇博客&#xff0c;主要是想记录一下&#xff0c;留个笔记&#xff0c;以防后面需要。 本文是在不借助工具的情况下在自己电脑上搭建FTP服务器。我的是w…

搭建自己本地的IIS服务器

在工作中有时候不想买服务器&#xff0c;这个时候就需要将自己的电脑搭建成服务器。如何搭建呢&#xff1f;其实很简单&#xff0c;以下几步教你搞定。 1. 打开控制面板(window图标直接输入控制面板(control)), 找到程序->程序与功能->启用或关闭Windows功能。 2.找到“…

阿里云服务器如何搭建ip

很多客户的业务要求需要多个ip 来完成业务要求。大家认为的每个服务器只有一个公网ip&#xff0c;那么如何实现多个ip呢&#xff1f;怎样来部署呢&#xff1f; 根据自己需求选择服务器&#xff0c;选购的过程中需要注意的是&#xff1a;实例的网络类型必须是专有网络&#xff…