① HDFS的运行模式
在本机上使用HDFS,使用的就是本机的文件系统。
在core-default.xml中设置参数fs.defaultFS=file:///。
使用的文件系统是一个分布式的文件系统。一个分布式的文件系统,必须由NameNode、DataNode等若干进程共同运行完成文件系统的读写操作。
1、在$HADOOP_HOME/etc/hadoop/core-site.xml文件中加入以下配置。
2、格式化NameNode(只需要格式化一次)。
执行命令:hadoop namenode -format,该命令会生成/opt/mole/hadoop-2.7.2/data/tmp目录,并在目录中生成fsimage_0000000000000000000文件。
3、启动NameNode和DataNode。
执行命令:hadoop-daemon.sh start namenode。同时可以通过执行命令:hadoop-daemon.sh start datanode来启动DataNode。
4、查看。
通过jps命令查看NameNode进程是否已经开启,通过浏览器访问http://NameNode所在的主机名或者ip:50070可以查看HDFS。如果NameNode和DataNode都在一台机器,且只有一个DN节点,称为伪分布式!
可以自定义配置文件的目录: hadoop --config 配置文件的目录 fs 命令 文件路径。例如hadoop --config myconf/ fs -put /home/xzq/hello /(将文件hello拷贝到HDFS根目录)。
如果没有配置,会默认读取$HADOOP_HOME/etc/hadoop中对应的配置文件,此时使用命令:hadoop fs 命令 文件路径。例如hadoop fs -put hello /(将文件hello拷贝到HDFS根目录)。
② HDFS 权限管理
HDFS Permissions Guide
HDFS 实现了文件和目录的权限模型,很多跟POSIX模型共享。 每个文件、目录都关联到用户、组。文件、目录对于拥有者、组中的其他用户、其他用户有着不同的权限设置。对于文件,读取需要 r 权限,写入/追加需要 w 权限。对于目录,列出目录内容需要 r 权限,创建、删除文件或目录需要 w 权限,访问目录子项需要 x 权限。
与POSIX模型不同,因为没有可执行文件,所以文件没有 setuid or setgid bits。对于目录,也没有 setuid or setgid bits作为简化。粘滞位 sticky bit 可以被作用于目录,放置除superuser、目录所有者、文件所有者之外的任何用户删除、移动目录内的文件。粘滞位 sticky bit 对于文件不生效。 文件或目录的权限我们称为 mod 。一般来说,mdoe的展示使用Unix风格,比如描述的8进制数使用。当创建一个文件/目录后,它的所有者即为客户端进程的用户,它的组是父目录的组(BSD规则)。
HDFS 还支持POSIX ACLs (Access Control Lists),给指定用户、组配置更新颗粒度的规则来加强权限管理。ACLs稍后会详细介绍。
每个访问HDFS的客户端进程身份都有两部分组成:用户名,组列表。无论什么时候,HDFS都必须会客户端进程访问的文件或目录foo做权限检查,
如果权限校验失败,客户端操作失败。
自 Hadoop 0.22 起,Hadoop 支持两种不同的操作模式来判断用户的身份,通过 hadoop.security.authentication 属性指定:
不管是哪种模式,用户身份机制都是HDFS的外部机制。HDFS中没有用于创建用户、建立组、处理用户凭据的规定。
一旦username被判定,如上,groups list将由group mapping service 判断,配置在 hadoop.security.group.mapping 属性。参见 Hadoop Groups Mapping 获取更多内容。
每次HDFS操作都需要用户拥有指定权限(读,写,执行的组合),通过文件的 ownership,group membership or 其他权限进行授权。 一个操作会进行路径多个组件的权限检查,而不仅是最后一个组件。另外,一些操作依赖于路径owner的检查。
所有的操作都需要遍历访问(traversal access)。遍历访问需要对路径上的所有存在的组件拥有执行权限,最终路径组件除外。比如,任一访问 /foo/bar/baz 的操作,调用者需要拥有 /, /foo and /foo/bar 的可执行权限。
[1] 如果调用使用overwrite配置,并且该路径已经存在文件,那么 create 操作只需要对最终路径组件拥有写权限即可。
[2] 如果设置了 sticky bit ,对父目录写权限的检查操作,同样也会检查ownership。
[3] 调用 setOwner 来改变文件的拥有着需要 HDFS super-user 访问权限。变更组不需要HDFS super-user 访问权限,但是调用者必须是文件的拥有者并且是指定组的成员。
每个文件、目录操作都会将完全路径发送给NameNode,对每个操作都会沿着path进行权限检查。客户端框架隐式的将用户身份与到NameNode的连接关联,减少对现有客户端API的改动的需求。常见一种情况,当某文件的一个操作已经成功完成了,再操作的时候会失败,因为该路径上的文件、目录已经不存在了。举个例子,当客户端第一次开始读取一个文件,它向NameNode发出第一个请求,以发现文件的第一个块的位置。第二个请求查找其他的块可能会失败。另一方面,删除一个文件并不会撤回客户端对该文件的访问,该客户端已经知道该文件的块。通过添加权限,客户端对文件的访问可以在请求之间被撤回。同样,变更权限不会撤回客户端的访问,该客户端已经知道文件的块。
如果权限检查失败,所有使用路径参数的方法都会抛出 AccessControlException 。
新方法:
新文件、目录的mode受umask设置限制,umask设置是配置项。
当使用现有方法 create(path, …) (不带权限参数),新文件的 mode 是 0666 & ^umask 。
当使用新方法 create(path, permission, …) (带权限参数 P) ,新文件的 mode 是 P & ^umask & 0666 。
当使用现有方法 mkdirs(path) (不带权限参数)创建一个新目录, 新目录的 mode 是 0777 & ^umask 。
当使用新方法 mkdirs(path, permission) (带权限参数 P), 新目录的 mode 是 P & ^umask & 0777 。
新操作:
谁启动NameNode,谁就是super-user。 super-user可以执行任意操作,权限校验从不失败。HDFS super-user 不必是NameNode 主机上的super-user,也不是说集群内的说有主机都需要有这个super-user。
如果在个人电脑上实验运行HDFS,为方便起见无须任何配置该用户即成为安装的super-user。
另外,管理员还可以通过配置参数标识一个特定组。该组内的成员也是super-users。
默认,web server的身份是一个可配置项。即,NameNode不知道真实用户的身份,但是web server以管理员选定的用户的身份(用户/组)行动。 除非选择的身份匹配super-user,部分命名空间是不可以被web server访问的。
除了传统的POSIX权限模型,HDFS还支持POSIX ACLs (Access Control Lists)。ACLs 对于实现区分用户、组的自然组织层次结构的权限需求非常有用。ACL提供了一个方法,可以给指定用户、组设置不同的权限,而不仅仅是文件的拥有着和所属组。
默认,ACLs的支持是关闭的,并且NameNode不允许创建ACLs。要开启ACLs的支持,在NameNode配置内设置 dfs.namenode.acls.enabled 为 true。
一个ACL由一系列ACL entries组成。每条ACL entry 命名了特定用户/组,并授于/拒绝 读、写、执行 权限。比如:
ACL entries 由 type ,可选的 name 和 permission 组成。为了便于展示,‘:’ 用作分隔符。 在这个范例内,文件的owner有read-write权限,文件的group有read-execute权限,others有读取权限。因此,等同于设置文件的权限为654。
另外,有2个扩展ACL entries给用户 bruce 和组 sales,并全部赋予所有权限。 mask 是一个特殊的ACL entry,过滤给所有命名的user entries 和命名的group entries 以及非命名的group entry的权限。 在范例内, mask 仅有写权限,并且我们可以看到几个ACL entries的有效权限被相应的过滤了。
每个ACL都必要要有一个 mask 。如果在设置ACL的时候用户没有提供 mask ,那么会通过计算来自动插入,计算将被过滤的所有entries的权限的并集。
在拥有ACL的文件上运行 chmod 实际上改变了 mask 的权限。既然 mask 作为过滤器,这有效的约束了所有扩展ACLs的权限,而不仅是变更group entry并且可能会丢失其他扩展ACL entries。
模型还有效区分了 “access ACL” 和 “default ACL” 。
“access ACL” ,定义权限检查期间强制执行的规则; “default ACL” ,定义新子文件或子目录创建期间自动接受的规则。
比如:
只有目录可以拥有默认 ACL。当一个新文件或者子目录创建,它会自动的拷贝父级的默认ACL作为自己的ACL。新子目录还将其作为默认 ACL。这样,当新目录创建时,默认 ACL 会被复制到该文件系统数的任意深度层。
新子级的ACL的确切权限值将由mode参数进行过滤。考虑到默认umask 是 022,则新目录是755,新文件是644。mode参数给unnamed user (file owner), the mask and other过滤过滤拷贝过来的权限值。 使用这个特定范例ACL,并创建一个mod 755的子目录,该mode过滤器对最终结果没有影响。但是,如果我们考虑创建一个mode 644 的文件,mode过滤器会导致新文件的ACL接受unnamed user(file owner)的读写权限,mask的读权限,以及其他的读权限。 该mask意味着named user bruce 和 named group sales 的有效权限是只读。
注意,拷贝发生在创建新文件或子目录的时候。对父级默认ACL的后续修改不会影响存在的子级。
默认 ACL 必须拥有所有必要的ACL entries,包括unnamed user (file owner), unnamed group (file group) and other entries。当设置默认ACL的时候,如果用户没有指定其中某个entry,那么entries会自动插入,通过拷贝访问ACL相应的权限、如果没有访问ACL则拷贝permission bits来实现。默认ACL必须拥有mask。如上所属,如果没有指定会自动插入一个计算的值。
对拥有ACL的文件,权限的检查算法变更为:
最佳实践依赖传统的权限位来实现大多数权限需求,并定义较少数量的ACL来加强,用一些异常规则来扩充权限位。与只有权限位的文件相比,具有ACL的文件在NameNode中会增加内存开销。
新方法:
public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;
public void removeAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;
public void public void removeDefaultAcl(Path path) throws IOException;
public void removeAcl(Path path) throws IOException;
public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException;
public AclStatus getAclStatus(Path path) throws IOException;
参考 File System Shell 文档获取命令的全部内容。
如果是,则使用这里描述的权限系统。如果否,关闭权限检查,但是其他行为不变。从一个参数值切换到其他值不会改变mode、文件或目录的owner or group。无论权限是开还是关, chmod 、 chgrp 、 chown and setfacl 总是会检查权限。 这些功能仅在权限上下文有用,因此不存在向后兼容问题。此外,这允许管理员可靠的设置所有者和权限,在打开常规权限检查前。
web server使用的用户名。设置为super-user允许所有客户端看到任何内容。改为其他未使用的身份允许web客户端仅可以查看"other"权限可见的内容。其他将其他组添加到逗号分隔列表内。
super-users 的组。
当创建文件和目录时使用的 umask 。对于配置文件,可以使用十进制值 18。
集群的管理员被配置为ACL。这控制谁可以访问HDFS默认的servlets 等。
设置为true,开启HDFS ACLs (Access Control Lists)的支持。默认,ACLs是关闭的。当ACLs关闭的时候,NameNode拒绝所有设置ACL的企图。 .
设置为true,开启 POSIX风格的ACL继承。默认开启。当它被启动时,并且create请求来自于兼容客户端,NameNode会从父目录应用默认ACL来创建mode并忽视客户端umask。如果没有默认ACL,它将应用客户端umask。
③ NoSQL-HDFS-基本概念
Hadoop
文件系统:文件系统是用来存储和管理文件,并且提供文件的查询、增加、删除等操作。
直观上的体验:在shell窗口输入 ls 命令,就可以看到当前目录下的文件夹、文件。
文件存储在哪里?硬盘
一台只有250G硬盘的电脑,如果需要存储500G的文件可以怎么办?先将电脑硬盘扩容至少250G,再将文件分割成多块,放到多块硬盘上储存。
通过 hdfs dfs -ls 命令可以查看分布式文件系统中的文件,就像本地的ls命令一样。
HDFS在客户端上提供了查询、新增和删除的指令,可以实现将分布在多台机器上的文件系统进行统一的管理。
在分布式文件系统中,一个大文件会被切分成块,分别存储到几台机器上。结合上文中提到的那个存储500G大文件的那个例子,这500G的文件会按照一定的大小被切分成若干块,然后分别存储在若干台机器上,然后提供统一的操作接口。
看到这里,不少人可能会觉得,分布式文件系统不过如此,很简单嘛。事实真的是这样的么?
潜在问题
假如我有一个1000台机器组成的分布式系统,一台机器每天出现故障的概率是0.1%,那么整个系统每天出现故障的概率是多大呢?答案是(1-0.1%)^1000=63%,因此需要提供一个容错机制来保证发生差错时文件依然可以读出,这里暂时先不展开介绍。
如果要存储PB级或者EB级的数据,成千上万台机器组成的集群是很常见的,所以说分布式系统比单机系统要复杂得多呀。
这是一张HDFS的架构简图:
client通过nameNode了解数据在哪些DataNode上,从而发起查询。此外,不仅是查询文件,写入文件的时候也是先去请教NameNode,看看应该往哪个DateNode中去写。
为了某一份数据只写入到一个Datanode中,而这个Datanode因为某些原因出错无法读取的问题,需要通过冗余备份的方式来进行容错处理。因此,HDFS在写入一个数据块的时候,不会仅仅写入一个DataNode,而是会写入到多个DataNode中,这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,保证了数据不丢失。
实际上,每个数据块在HDFS上都会保存多份,保存在不同的DataNode上。这种是牺牲一定存储空间换取可靠性的做法。
接下来我们来看一下完整的文件写入的流程:
大文件要写入HDFS,client端根据配置将大文件分成固定大小的块,然后再上传到HDFS。
读取文件的流程:
1、client询问NameNode,我要读取某个路径下的文件,麻烦告诉我这个文件都在哪些DataNode上?
2、NameNode回复client,这个路径下的文件被切成了3块,分别在DataNode1、DataNode3和DataNode4上
3、client去找DataNode1、DataNode3和DataNode4,拿到3个文件块,通过stream读取并且整合起来
文件写入的流程:
1、client先将文件分块,然后询问NameNode,我要写入一个文件到某个路径下,文件有3块,应该怎么写?
2、NameNode回复client,可以分别写到DataNode1、DataNode2、DataNode3、DataNode4上,记住,每个块重复写3份,总共是9份
3、client找到DataNode1、DataNode2、DataNode3、DataNode4,把数据写到他们上面
出于容错的考虑,每个数据块有3个备份,但是3个备份快都直接由client端直接写入势必会带来client端过重的写入压力,这个点是否有更好的解决方案呢?回忆一下mysql主备之间是通过binlog文件进行同步的,HDFS当然也可以借鉴这个思想,数据其实只需要写入到一个datanode上,然后由datanode之间相互进行备份同步,减少了client端的写入压力,那么至于是一个datanode写入成功即成功,还是需要所有的参与备份的datanode返回写入成功才算成功,是可靠性配置的策略,当然这个设置会影响到数据写入的吞吐率,我们可以看到可靠性和效率永远是“鱼和熊掌不可兼得”的。
潜在问题
NameNode确实会回放editlog,但是不是每次都从头回放,它会先加载一个fsimage,这个文件是之前某一个时刻整个NameNode的文件元数据的内存快照,然后再在这个基础上回放editlog,完成后,会清空editlog,再把当前文件元数据的内存状态写入fsimage,方便下一次加载。
这样,全量回放就变成了增量回放,但是如果NameNode长时间未重启过,editlog依然会比较大,恢复的时间依然比较长,这个问题怎么解呢?
SecondNameNode是一个NameNode内的定时任务线程,它会定期地将editlog写入fsimage,然后情况原来的editlog,从而保证editlog的文件大小维持在一定大小。
NameNode挂了, SecondNameNode并不能替代NameNode,所以如果集群中只有一个NameNode,它挂了,整个系统就挂了。hadoop2.x之前,整个集群只能有一个NameNode,是有可能发生单点故障的,所以hadoop1.x有本身的不稳定性。但是hadoop2.x之后,我们可以在集群中配置多个NameNode,就不会有这个问题了,但是配置多个NameNode,需要注意的地方就更多了,系统就更加复杂了。
俗话说“一山不容二虎”,两个NameNode只能有一个是活跃状态active,另一个是备份状态standby,我们看一下两个NameNode的架构图。
两个NameNode通过JournalNode实现同步editlog,保持状态一致可以相互替换。
因为active的NameNode挂了之后,standby的NameNode要马上接替它,所以它们的数据要时刻保持一致,在写入数据的时候,两个NameNode内存中都要记录数据的元信息,并保持一致。这个JournalNode就是用来在两个NameNode中同步数据的,并且standby NameNode实现了SecondNameNode的功能。
进行数据同步操作的过程如下:
active NameNode有操作之后,它的editlog会被记录到JournalNode中,standby NameNode会从JournalNode中读取到变化并进行同步,同时standby NameNode会监听记录的变化。这样做的话就是实时同步了,并且standby NameNode就实现了SecondNameNode的功能。
优点:
缺点:
④ 大数据之HDFS
在现代的企业环境中,单机容量往往无法存储大量数据,需要跨机器存储。统一管理分布在集群上的文件系统称为 分布式文件系统 。
HDFS (Hadoop Distributed File System)是 Hadoop 的核心组件之一, 非常适于存储大型数据 (比如 TB 和 PB), HDFS 使用多台计算机存储文件,并且提供统一的访问接口,像是访问一个普通文件系统一样使用分布式文件系统。
HDFS是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。它所具有的 高容错、高可靠性、高可扩展性、高获得性、高吞吐率 等特征为海量数据提供了不怕故障的存储,为超大数据集的应用处理带来了很多便利。
HDFS 具有以下 优点 :
当然 HDFS 也有它的 劣势 ,并不适合以下场合:
HDFS 采用Master/Slave的架构来存储数据,这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。
Namenode是整个文件系统的管理节点,负责接收用户的操作请求。它维护着整个文件系统的目录树,文件的元数据信息以及文件到块的对应关系和块到节点的对应关系。
Namenode保存了两个核心的数据结构:
在NameNode启动的时候,先将fsimage中的文件系统元数据信息加载到内存,然后根据edits中的记录将内存中的元数据同步到最新状态;所以,这两个文件一旦损坏或丢失,将导致整个HDFS文件系统不可用。
为了避免edits文件过大, SecondaryNameNode会按照时间阈值或者大小阈值,周期性的将fsimage和edits合并 ,然后将最新的fsimage推送给NameNode。
并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。其主要任务是辅助 NameNode,定期合并 fsimage和fsedits。
Datanode是实际存储数据块的地方,负责执行数据块的读/写操作。
一个数据块在DataNode以文件存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据,包括数据块的长度,块数据的校验和,以及时间戳。
文件划分成块,默认大小128M,以快为单位,每个块有多个副本(默认3个)存储不同的机器上。
Hadoop2.X默认128M, 小于一个块的文件,并不会占据整个块的空间 。Block数据块大小设置较大的原因:
文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储。
Client 还提供一些命令来管理 HDFS,比如启动或者关闭HDFS。
Namenode始终在内存中保存metedata,用于处理“读请求”,到有“写请求”到来时,namenode会首 先写editlog到磁盘,即向edits文件中写日志,成功返回后,才会修改内存 ,并且向客户端返回,Hadoop会维护一个fsimage文件,也就是namenode中metedata的镜像,但是fsimage不会随时与namenode内存中的metedata保持一致,而是每隔一段时间通过合并edits文件来更新内容。
HDFS HA(High Availability)是为了解决单点故障问题。
HA集群设置两个名称节点,“活跃( Active )”和“待命( Standby )”,两种名称节点的状态同步,可以借助于一个共享存储系统来实现,一旦活跃名称节点出现故障,就可以立即切换到待命名称节点。
为了保证读写数据一致性,HDFS集群设计为只能有一个状态为Active的NameNode,但这种设计存在单点故障问题,官方提供了两种解决方案:
通过增加一个Secondary NameNode节点,处于Standby的状态,与Active的NameNode同时运行。当Active的节点出现故障时,切换到Secondary节点。
为了保证Secondary节点能够随时顶替上去,Standby节点需要定时同步Active节点的事务日志来更新本地的文件系统目录树信息,同时DataNode需要配置所有NameNode的位置,并向所有状态的NameNode发送块列表信息和心跳。
同步事务日志来更新目录树由JournalNode的守护进程来完成,简称为QJM,一个NameNode对应一个QJM进程,当Active节点执行任何命名空间文件目录树修改时,它会将修改记录持久化到大多数QJM中,Standby节点从QJM中监听并读取编辑事务日志内容,并将编辑日志应用到自己的命名空间。发生故障转移时,Standby节点将确保在将自身提升为Active状态之前,从QJM读取所有编辑内容。
注意,QJM只是实现了数据的备份,当Active节点发送故障时,需要手工提升Standby节点为Active节点。如果要实现NameNode故障自动转移,则需要配套ZKFC组件来实现,ZKFC也是独立运行的一个守护进程,基于zookeeper来实现选举和自动故障转移。
虽然HDFS HA解决了“单点故障”问题,但是在系统扩展性、整体性能和隔离性方面仍然存在问题:
HDFS HA本质上还是单名称节点。HDFS联邦可以解决以上三个方面问题。
在HDFS联邦中,设计了多个相互独立的NN,使得HDFS的命名服务能够水平扩展,这些NN分别进行各自命名空间和块的管理,不需要彼此协调。每个DN要向集群中所有的NN注册,并周期性的发送心跳信息和块信息,报告自己的状态。
HDFS联邦拥有多个独立的命名空间,其中,每一个命名空间管理属于自己的一组块,这些属于同一个命名空间的块组成一个“块池”。每个DN会为多个块池提供块的存储,块池中的各个块实际上是存储在不同DN中的。
⑤ ftp提取文件到hdfs
实际场景中,我们经常需要通过ftp协议把不同数据源的文件统一汇入到hdfs数据中心,经过实践,有以下的三种方法,分别列出其优缺点及适用场景。
1、 先把文件ftp到本地,然后用命令hdfsdfs –put [local_path] [hdfs_path]
优点:文件在本地可以进行本地化的一系列操作后,再放回hdfs中
缺点:文件传输经过两层,并且从源服务器到本地提取是单机串行,比较消耗时间。
适用于文件放入hfds前需要预处理的情景,如:.zip压缩文件不被hadoop支持的,所以我们可以先在本地转压缩方式然后再放入hdfs中。
2、 hdfs dfs –cp [ftp://username:password@hostname/ftp_path] [hdfs:///hdfs_path]
优点:简单,提取速度快
缺点:CLI执行不会显示进度
适用场景:适用于小文件的ftp拷贝。
3、 hadoop distcp [ftp://username:password@hostname/ftp_path] [hdfs:///hdfs_path]
优点:简单,能显示拷贝进度,并且是分布式提取的,数据比较快。
缺点: 如果拷贝的文件是不断有其他程序写入,会报错,因为该命令最后要对数据进行checksum导致两边不一致,当然,该命令是主要用于集群间拷贝的。
适用场景:大量文件或大文件的拷贝。
⑥ HDFS文件
Hadoop支持的文件系统由很多(见下图),HDFS只是其中一种实现。java抽象类 org.apache.hadoop.fs.FileSystem 定义了Hadoop中一个文件系统的客户端接口,并且该抽象类有几个具体实现。Hadoop一般使用URI(下图)方案来选取合适的文件系统实例进行交互。
特别的,HDFS文件系统的操作可以使用 FsSystem shell 、客户端(http rest api、Java api、C api等)。
FsSystem shell 的用法基本同本地shell类似,命令可参考 FsSystem shell
Hadoop是用Java写的,通过Java Api( FileSystem 类)可以调用大部分Hadoop文件系统的交互操作。更详细的介绍可参考 hadoop Filesystem 。
非Java开发的应用可以使用由WebHDFS协议提供的HTTP REST API,但是HTTP比原生的Java客户端要慢,所以不到万不得已尽量不要使用HTTP传输特大数据。通过HTTP来访问HDFS有两种方法:
两种如图
在第一种情况中,namenode和datanode内嵌的web服务作为WebHDFS的端节点运行(是否启用WebHDFS可通过dfs.webhdfs.enabled设置,默认为true)。文件元数据在namenode上,文件读写操作首先被发往namenode,有namenode发送一个HTTP重定向至某个客户端,指示以流的方式传输文件数据的目的或源datanode。
第二种方法依靠一个或多个独立代理服务器通过HTTP访问HDFS。所有集群的网络通信都需要通过代理,因此客户端从来不直接访问namenode或datanode。使用代理后可以使用更严格的防火墙策略和带宽策略。
HttpFs代理提供和WebHDFS相同的HTTP接口,这样客户端能够通过webhdfs URI访问接口。HttpFS代理启动独立于namenode和datanode的守护进程,使用httpfs.sh 脚本,默认在一个不同的端口上监听(14000)。
下图描述了
读文件时客户端与 HDFS 中的 namenode, datanode 之间的数据流动。
对上图的解释如下:
在读取过程中, 如果 FSDataInputStream 在和一个 datanode 进行交流时出现了一个错误,他就去试一试下一个最接近的块,他当然也会记住刚才发生错误的 datanode 以至于之后不会再在这个 datanode 上进行没必要的尝试。 DFSInputStream 也会在 datanode 上传输出的数据上核查检查数(checknums).如果损坏的块被发现了, DFSInputStream 就试图从另一个拥有备份的 datanode 中去读取备份块中的数据。
在这个设计中一个重要的方面就是客户端直接从 datanode 上检索数据,并通过 namenode 指导来得到每一个块的最佳 datanode。这种设计允许 HDFS 扩展大量的并发客户端,因为数据传输只是集群上的所有 datanode 展开的。期间,namenode 仅仅只需要服务于获取块位置的请求(块位置信息是存放在内存中,所以效率很高)。如果不这样设计,随着客户端数据量的增长,数据服务就会很快成为一个瓶颈。
我们知道,相对于客户端(之后就是 maprece task 了),块的位置有以下可能性:
我们认为他们对于客户端的带宽递减,距离递增(括号中表示距离)。示意图如下:
如果集群中的机器都在同一个机架上,我们无需其他配置,若集群比较复杂,由于hadoop无法自动发现网络拓扑,所以需要额外配置网络拓扑。
基本读取程序,将文件内容输出到console
FileSystemCat
随机读取
展开原码
下图描述了写文件时客户端与 HDFS 中的 namenode, datanode 之间的数据流动。
对上图的解释如下:
如果在任何一个 datanode 在写入数据的时候失败了,接下来所做的一切对客户端都是透明的:首先, pipeline 被关闭,在确认队列中的剩下的包会被添加进数据队列的起始位置上,以至于在失败的节点下游的任 何节点都不会丢失任何的包。然后与 namenode 联系后,当前在一个好的 datanode 会联系 namenode, 给失败节点上还未写完的块生成一个新的标识ID, 以至于如果这个失败的 datanode 不久后恢复了,这个不完整的块将会被删除。失败节点会从 pipeline 中移除,然后剩下两个好的 datanode 会组成一个的新的 pipeline ,剩下的 这些块的包(也就是刚才放在数据队列队首的包)会继续写进 pipeline 中好的 datanode 中。最后,namenode 注意到块备份数小于规定的备份数,他就安排在另一个节点上创建完成备份,直接从已有的块中复制就可以。然后一直到满足了备份数( dfs.replication )。如果有多个节点的写入失败了,如果满足了最小备份数的设置( dfs.namenode.repliction.min ),写入也将会成功,然后剩下的备份会被集群异步的执行备份,直到满足了备份数( dfs.replication )。
创建目录
文件压缩有两大好处:
Hadoop 对于压缩格式的是自动识别。如果我们压缩的文件有相应压缩格式的扩展名(比如 lzo,gz,bzip2 等)。Hadoop 会根据压缩格式的扩展名自动选择相对应的解码器来解压数据,此过程完全是 Hadoop 自动处理,我们只需要确保输入的压缩文件有扩展名。
Hadoop中有多种压缩格式、算法和工具,下图列出了常用的压缩方法。
表中的“是否可切分”表示对应的压缩算法是否支持切分,也就是说是否可以搜索数据流的任意位置并进一步往下读取数据,可切分的压缩格式尤其适合MapRece。
所有的压缩算法都需要权衡空间/时间:压缩和解压缩速度更快,其代价通常是只能节省少量的空间。不同的压缩工具有不同的特性:
更详细的比较如下
1.压缩性能比较
2.优缺点
另外使用hadoop原生(native)类库比其他java实现有更快的压缩和解压缩速度。特征比较如下:
使用容器文件格式结合压缩算法也能更好的提高效率。顺序文件、Arvo文件、ORCFiles、Parqurt文件同时支持压缩和切分。
压缩举例(Java)
压缩
解压缩
六、文件序列化
序列化是指将结构化数据转换为字节流以便在网络上传输或写到磁盘进行永久存储。反序列化狮子将字节流转换回结构化对象的逆过程。
序列化用于分布式数据处理的两大领域:进程间通信和永久存储。
对序列化的要求时是格式紧凑(高效使用存储空间)、快速(读写效率高)、可扩展(可以透明地读取老格式数据)且可以互操作(可以使用不同的语言读写数据)。
Hadoop使用的是自己的序列化格式 Writable ,它绝对紧凑、速度快,但不太容易用java以外的语言进行扩展或使用。
当然,用户也可以使用其他序列化框架或者自定义序列化方式,如 Avro 框架。
Hadoop内部还使用了 Apache Thrift 和 Protocal Buffers 来实现RPC和数据交换。
⑦ HDFS(五):NN和2NN
内存一份数据,fsImage存储数据(合并后的数据,即没有追加前数据),edits文件只追加,不参与计算
内存数据 == fsImage+edits
服务器启动:将(fsImage+edits)数据加载到内存
服务器关闭:将 fsImage+edits合并
2nn将fsimage和edits文件定期合并
NameNode 被格式化后,将在/opt/mole/hadoop-3.1.3/data/tmp/dfs/name/current目录中产生如下文件
2NN 在/opt/mole/hadoop-3.1.3/data/tmp/dfs/namesecondary/current
NameNode相比较2nn多了edits_inprogress
NameNode被格式化之后,将在/opt/mole/hadoop-3.1.3/data/tmp/dfs/name/current目录产生如下文件
1)fsimage文件:HDFS文件系统元数据的一个永久性检查点,其中包含HDFS文件系统的所有目录和inode的序列化信息
2)Edits文件:存放HDFS文件系统的所有更新操作的路径,文件系统客户端执行的所有写操作首先会被记录到edits文件中
3)seen_txid:文件保存的是一个数字,就是最后一个edits_数字
4)VERSION,当前nameNode的命名空间,和集群id
(1)基本语法
hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
(2)实操
NameNode没有记录块所对应DataNode,DataNode启动后向NameNode汇报自己有哪些文件块
(1)基本语法
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
(2)实操
只进行追加,不进行合并操作。
在服务器启动进入内存,只加载edits后缀大于fsimage后缀。
hdfs-default.xml
1)通常情况下,SecondaryNameNode每隔一个小时执行一次。[hdfs-default.xml]
2)一分钟检查一次操作次数,当操作次数达到1百万次,SecondaryNameNode执行一次。
2nn每隔1分钟,主动查询一次。
通过本节可以知道两个文件fsimage和edits文件作用,通过这两个文件就是NameNode存储的元数据。
⑧ hadoop面试题之HDFS
1、简单介绍下hadoop吧?
广义上hadoop是指与hadoop相关的大数据生态圈。包含hive、spark、hbase等。
狭义上hadoop指的是apache的开源框架。有三个核心组件:
----hdfs:分布式文件存储系统
----yarn:分布式资源管理调度平台
----mr:分布式计算引擎
2、介绍下hdfs?
全称为Hadoop Distributed File System。有三个核心组件:
namenode:有三个作用,第一是负责保存集群的元数据信息,第二是负责维护整个集群节点的正常运行。
第三是负责处理客户端的请求。
datanode:负责实际保存数据。实际执行数据块的读写操作。
secondarynamenode:辅助namenode进行元数据的管理。不是namenode的备份。
3、namenode的工作机制?
namenode在内存中保存着整个内存系统的名称空间和文件数据块的地址映射。整个hdfs可存储的文件数受限于namenode的内存大小。所以hdfs不适合大量小文件的存储。
---namenode有三种元数据存储方式来管理元数据:
》内存元数据:内存中保存了完整的元数据
》保存在磁盘上的元数据镜像文件(fsimage):该文件时hdfs存在磁盘中的元数据检查点,里面保存的是最后一次检查点之前的hdfs文件系统中所有目录和文件的序列化信息。
》数据操作日志文件(edits):用于衔接内存meta data和持久化元数据镜像fsimage之间的操作日志文件。保存了自最后一次检查点之后所有针对hdfs文件系统的操作。如对文件的增删改查。
4、如何查看元数据信息?
因为edits和fsimage文件是经过序列化的,所以不能直接查看。hadoop2.0以上提供了查看两种文件的工具。
----命令:hdfs oiv 可以将fsimage文件转换成其他格式,如xml和文本文件。-i 表示输入fsimage文件。-o 输出文件路径,-p 指定输出文件
hdfs oev可以查看edits文件。同理需要指定相关参数。
详情查看: https://www.imooc.com/article/79705
4、datanode的工作机制?
1)以数据块的形式存储hdfs文件
2)datanode响应客户端的读写请求
3)周期性的向namenode汇报心跳信息、数据块信息、缓存数据块信息
5、secondary namenode工作机制?
当发生checkpoint机制时会触发second namenode进行工作。checkpoint:
新的edists文件不会立即和fsimage文件合并,是在edits文件大小超过(默认)64m,或者时间超过(默认)1小时,会触发checkpoint操作。当checkpoint时,namenode会新建一个edits.new的文件,此时second namenode将文件fsimage文件和edits文件(http get)到本地,然后加载到内存中进行合并,完成的文件名称为fsimage.ckpt。最后 second namenode将该文件(http post)到namenode,然后edits.new和fsimage.ckpt文件转换为fsimage和edits。
6、hdfs的文件副本机制?
所有的文件都是以块的形式保存到hdfs中。块的大小默认为128m。在hdfs-site文件中进行指定。
动态副本创建策略:默认副本数是3,可以在上传文件时,显式设定replication。也可以通过指令修改文件的副本数 hadoop fs -setrep -R 1
7、为实现高可用,hdfs采用了哪些策略?
副本机制、机架感知、心跳机制、安全模式、校验和、回收站、元数据保护、快照机制(具体介绍导航- https://www.jianshu.com/writer#/notebooks/44567747/notes/66453316 )
8、hdfs的存储过程?
①client向hdfs发起写请求,通过RPC与namenode建立通讯。namenode检查文件是否存在等信息,返回是否可以存储。
②client将文件切割为一个个block块,client申请存储第一块block。namenode返回可以存储这个block块的datanode的地址,假设为ABC。
③A到B到C逐级构建pipeline。client向A上传第一个packet,默认为64k。A收到一个packet后会将packet传给B,再传给C。pipeline反方向返回ack信息。最终由第一个节点A将pipelineack发送给client
④一个block完成之后,再进行下一个block的存储过程。
9、hdfs的读过程?
10、hdfs的垃圾桶机制?
hdfs的垃圾桶机制默认是关闭的,需要手动开启。hdfs删除的文件不会立刻就删除,而是在设定的时间后进行删除。
11、hdfs的扩容和缩容
【
12、
⑨ HDFS笔记
1.Hadoop 分布式 文件系统。特点:性能高、效率高、速度快
2.可以在廉价的机器上运行的 可容错 文件系统。
当集群中有机器挂掉时,HDFS会自动将挂掉的机器上的任务分配给正常的机器,使任务继续保持正常工作。
2.HDFS处理更加容易。当对一个大型文件进行写操作时,如果将该文件整个写入一个节点,那么该节点的负载便会急剧增加,这样就丧失了分布式文件系统的意义。所以,应该利用HDFS将文件拆分成不同的块,然后将不同的块分配到不同的节点上去,此时,DFS就需要管理者确定文件如何进行拆分,以及每一个块应该分配到哪一个节点。对文件进行操作时,在单机情况下,首先需要知道文件被拆分成多少块,每一个块被放在了哪一个节点上,以及块之间的顺序(文件的粘连)。而HDFS的出现,使得分布式文件集群不再需要人进行管理,利用HDFS读取文件时,我们不需要关心文件如何拆分,分配,粘连。只用告诉HDFS文件的路径即可。
HDFS的指令类似于linux下的指令。
查看文件:hdfs dfs -ls /查询的文件目录
删除文件:hdfs dfs -rm r /删除的文件
创建文件夹:hdfs dfs -mkdir /文件夹名称
上传文件至HDFS:hdfs dfs -put 需要上传的文件 /上传的文件路径
为什么需要学习HDFS结构?
1.面试中,能够运用于所有分布式文件系统设计。
既然分布式系统下是多节点运行,那么节点之间是否通信?slave节点只接受来自master节点的命令,向master节点发送心跳指令,slave节点之间不会主动通信。
a.Master slaver 模式:
1.High consistency:一致性。当文件中的一个数据块写入slave节点时,当且仅当数据块被成功写入到所有备份的slave节点,slave节点向client反馈写入操作成功,否则,重传写入;
2.Simple design:易设计:不需要考虑子节点如何通信。只需要考虑主节点的工作;
3.单master节点不具有鲁棒性。
b.Peer peer 模式:
1.所有的读写操作均匀分布在每一个节点上,每一个节点的负载不会很高;
2.任意一个节点挂掉不会影响其他节点;
3.低一致性。没有数据的复制步骤。
2.更好的理解hadoop生态系统
a.master节点会传输数据吗?
不会,master节点只接收client的请求,决定哪一个slave节点进行读写操作,然后,client直接与slave节点进行通信。如果数据从master节点传输,那么master节点就会成为影响数据传输的瓶颈。
b.slave节点如何存储数据?
整个大文件?小的文件块?。HDFS借鉴GFS的设计理念,以block为传输单位,将大文件拆分成一个一个小文件,而一个小文件就是block。block的大小可以由Configuration定义,默认大小是128M。
c.谁来决定将文件拆分成块?
master?slave?。两者都不是,由HDFS client决定将大文件拆分成block(块)。HDFS的目的是将所有的节点包装起来,可以理解成将所有的节点放在一个黑箱里,我们不需要知道黑箱里到底发生了什么,只需要告诉黑箱需要做什么工作,这里的HDFS client相当于HDFS与user通信的中间媒介。HDFS client相当于一个软件包(api),可以存放在master或者slave或者额外的一个新节点上。
写入in memory失败(ACK出现问题)时,master会重新选择3个新的slave节点。