1T文件操作
1T文本文件,按行排列
电脑配置:
128MB可用内存
1、找出该文件中重复的两行
2、全排序
3、数单词
该任务能不能完成?
读取1T文件耗时:≈30分钟
将小文件读取到内存比较,≈30分钟
最终60分钟找到重复的行
时间用在了IO上
依次读取有序的小文件,将读取到内存的小文件排序之后
写入到磁盘1T文件该文件就是有序的
≈1小时 IO耗时
每个小文件是有序的,文件之间无序
读取1T文件耗时:≈30分钟
将小文件读取到内存比较,≈30分钟
最终60分钟找到重复的行
时间用在了IO上
归并-或许内存大小并不重要
时间减少
假设有2000台计算机
2000个小文件,每个500MB,一次读取需要时间:1s
如果hashcode对2000求余,2000台计算机读取求余获得的每台服务器上的若干小文件合并之后比较,由于涉及到计算机之间文件传输,千兆带宽,100MB/s:5s
则1T分为2000个500MB的,则需要2.5小时。
如果一开始文件就是分开存放的,这个时间就可以很小;
数据一次写入,多次读取,增量好于全量
MapReduce的41个单词的解释:
|
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRThPLU0-1617441280654)(media/ef073e73f1fb213bd436fe09cc609dcf.jpeg)]
制胜之道
并行,加快速度
分布式运行
计算向数据移动
hadoop起源
|
发展历史
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WCBG7o6O-1617441280659)(media/c6d178d9247944ca2f11aba3a56d6b05.jpeg)]
Doug Cutting
- 2002年10月,Doug Cutting和Mike Cafarella创建了开源网页爬虫项目Nutch。
- 2003年10月,Google发表Google File System论文。
- 2004年7月,Doug Cutting和Mike
Cafarella在Nutch中实现了类似GFS的功能,即后来HDFS的前身。 - 2004年10月,Google发表了MapReduce论文。
- 2005年2月,Mike Cafarella在Nutch中实现了MapReduce的最初版本。
- 2005年12月,开源搜索项目Nutch移植到新框架,使用MapReduce和NDFS在20个节点稳定运行。
- 2006年1月,Doug
Cutting加入雅虎,Yahoo!提供一个专门的团队和资源将Hadoop发展成一个可在网络上运行的系统。 - 2006年2月,Apache Hadoop项目正式启动以支持MapReduce和HDFS的独立发展。
- 2006年3月,Yahoo!建设了第一个Hadoop集群用于开发。
- 2006年4月,第一个Apache Hadoop发布。
- 2006年11月,Google发表了Bigtable论文,激起了Hbase的创建。
- 2007年10月,第一个Hadoop用户组会议召开,社区贡献开始急剧上升。
- 2007年,百度开始使用Hadoop做离线处理。
- 2007年,中国移动开始在“大云”研究中使用Hadoop技术。
- 2008年,淘宝开始投入研究基于Hadoop的系统——云梯,并将其用于处理电子商务相关数据。
- 2008年1月,Hadoop成为Apache顶级项目。
- 2008年2月,Yahoo!运行了世界上最大的Hadoop应用,宣布其搜索引擎产品部署在一个拥有1万个内核的Hadoop集群上。
- 2008年4月,在900个节点上运行1TB排序测试集仅需209秒,成为世界最快。
- 2008年8月,第一个Hadoop商业化公司Cloudera成立。
- 2008年10月,研究集群每天装载10TB的数据。
- 2009 年3月,Cloudera推出世界上首个Hadoop发行版——CDH(Cloudera’s Distribution
including Apache Hadoop)平台,完全由开放源码软件组成。 - 2009年6月,Cloudera的工程师Tom
White编写的《Hadoop权威指南》初版出版,后被誉为Hadoop圣经。 - 2009年7月 ,Hadoop Core项目更名为Hadoop Common;
- 2009年7月 ,MapReduce 和 Hadoop Distributed File System (HDFS)
成为Hadoop项目的独立子项目。 - 2009年8月,Hadoop创始人Doug Cutting加入Cloudera担任首席架构师。
- 2009年10月,首届Hadoop World大会在纽约召开。
- 2010年5月,IBM提供了基于Hadoop 的大数据分析软件——InfoSphere
BigInsights,包括基础版和企业版。 - 2011年3月,Apache Hadoop获得Media Guardian Innovation Awards媒体卫报创新奖
- 2012年3月,企业必须的重要功能HDFS NameNode HA被加入Hadoop主版本。
- 2012年8月,另外一个重要的企业适用功能YARN成为Hadoop子项目。
- 2014年2月,Spark逐渐代替MapReduce成为Hadoop的缺省执行引擎,并成为Apache基金会顶级项目。
- 2017年12月,Release 3.0.0 generally available
核心组件
- hadoop通用组件 - Hadoop Common
- 包含了其他hadoop模块要用到的库文件和工具
- 分布式文件系统 - Hadoop Distributed File System (HDFS)
- 运行于通用硬件上的分布式文件系统,高吞吐,高可靠
- 资源管理组件 - Hadoop YARN
- 于2012年引入的组件,用于管理集群中的计算资源并在这些资源上调度用户应用。
- 分布式计算框架 - Hadoop MapReduce
- 用于处理超大数据集计算的MapReduce编程模型的实现。
hadoop关联项目
- Apache Ambari是一种基于Web的工具,支持Apache
Hadoop集群的供应、管理和监控。Apache Ambari
支持HDFS、MapReduce、Hive、Pig、Hbase、Zookeepr、Sqoop和Hcatalog等的集中管理。也是5个顶级hadoop管理工具之一。 - Avro™:数据序列化系统
- Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon
Dynamo的完全分布式的架构于一身,Facebook于2008将 Cassandra 开源。 - chukwa 是一个开源的用于监控大型分布式系统的数据收集系统。这是构建在 hadoop
的 HDFS 和MapReduce框架之上的,继承了 hadoop 的可伸缩性和健壮性。Chukwa
还包含了一个强大和灵活的工具集,可用于展示、监控和分析已收集的数据。 - hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
- Mahout
提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout包含许多实现,包括聚类、分类、推荐过滤、频繁子项挖掘。此外,通过使用
Apache Hadoop 库,Mahout 可以有效地扩展到云中。 - Apache Pig 是一个高级过程语言,适合于使用 Hadoop 和 MapReduce
平台来查询大型半结构化数据集。通过允许对分布式数据集进行类似 SQL 的查询,Pig
可以简化 Hadoop 的使用。 - Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC
Berkeley AMP lab开源的类Hadoop
MapReduce的通用并行框架,拥有MapReduce所具有的优点;但是Job中间输出结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的MapReduce的算法。 - Tez 是 Apache 最新的支持 DAG
作业的开源计算框架。它允许开发者为最终用户构建性能更快、扩展性更好的应用程序。Hadoop传统上是一个大量数据批处理平台。但是,有很多用例需要近乎实时的查询处理性能。还有一些工作则不太适合MapReduce,例如机器学习。Tez的目的就是帮助Hadoop处理这些用例场景。 - ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
- HBase是一个分布式的、高可靠性、高性能、面向列、可伸缩的分布式存储系统,该技术来源于Fay
Chang所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File
System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。
HDFS架构
前提和设计目标
- 硬件错误
- 硬件错误是常态而不是异常。
- HDFS可能由成百上千的服务器所构成,单机故障概率的存在意味着总有一部分服务器不工作的。
- 错误检测和快速自动恢复是HDFS最核心架构目标。
- 流式数据访问
- 运行在HDFS上的应用需要流式访问它们的数据集。
- HDFS的设计重点是批处理,而不是交互处理。是高吞吐量而不是低延迟。
- 为了提高数据的吞吐量,在关键方面修改POSIX的语义。
- 大规模数据集
- HDFS上的一个典型文件大小一般都在G字节至T字节。
- HDFS支持大文件存储。
- 单一HDFS实例能支撑数以千万计的文件。
- 简单的一致性模型
- HDFS应用遵循“一次写入多次读取”的文件访问模型。
- 简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。
- Map/Reduce应用或者网络爬虫应用都非常适合这个模型。
- 移动计算比移动数据更划算
- 降低网络阻塞的影响,提高系统数据的吞吐量。
- 将计算程序发送到数据所在的主机,比GB级别TB级别的数据移动更便捷。
- 异构软硬件平台间的可移植性
- HDFS在设计的时候就考虑到平台的可移植性。
- 这种特性方便了HDFS作为大规模数据应用平台的推广。
HDFS架构
问题:
100台服务器,存储空间单个100GB
5T文件如何存储?
web.log 5TB
BufferedReader breader = new
BufferedReader(InputStreamReader(FileInputStream(“E:\file”)));long index = 0;
byte[] buf = new byte[1024];
int len = -1;
while ((len = breader.read(buf)) != -1) {
index+= len;
if (index < 128*1024*1024) {
bwriter.write(buf, 0, len);
} else {
bwriter2.write(buf, 0, len);
}
}
128MB一块 8192*5块 128*8MB=1GB 128*8*1024=1TB
8*1024块 8192 *5 =5T数据分成的128MB的块数。
清单:
5TB文件分的块:
元数据:
文件名称:web.log
大小:5TB
创建时间:
权限:
文件所有者:
文件数组:
文件类型:
文件块列表信息:
0~128*1024*1024 -1:128MB:node1:path
128*1024*1024~2*128*1024*1024 -1:128MB:node2:path
2*128*1024*1024~3*128*1024*1024 -1:128MB:node3:path
0~128*1024*1024 -1:128MB:node1:
0~128*1024*1024 -1:128MB:node1:
0~128*1024*1024 -1:128MB:node1:
0~128*1024*1024 -1:128MB:node1:
0~128*1024*1024 -1:128MB:node1:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSMDMEv7-1617441280662)(media/3806fc4d7e3d976e315538e7d55f2d68.png)]
NameNode
NameNode管理文件系统的命名空间
- 文件和目录的元数据:(运行时,元数据放内存)
文件的block副本个数
修改和访问的时间
访问权限
block大小以及组成文件的block列表信息
- 以两种方式在NameNode本地进行持久化:
命名空间镜像文件(fsimage)和编辑日志(edits log)。
- fsimage文件不记录每个block所在的DataNode信息,这些信息在每次系统启动的时候从DataNode重建。之后DataNode会周期性地通过心跳包向NameNode报告block信息。DataNode向NameNode注册的时候NameNode请求DataNode发送block列表信息。
|
存储结构
一个运行的NameNode如下的目录结构,该目录结构在第一次格式化的时候创建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzzdwnUb-1617441280665)(media/f841efd874d73b6fbda5babf859e3751.jpeg)]
如果属性dfs.namenode.name.dir指定了多个路径,则每个路径中的内容是一样的,尤其是当其中一个是挂载的NFS的时候,这种机制为管理提供了一些弹性。备份数据
in_use.lock文件用于NameNode锁定存储目录。这样就防止其他同时运行的NameNode实例使用相同的存储目录。
edits表示edits log日志文件
fsimage表示文件系统元数据镜像文件
NameNode在checkpoint之前首先要切换新的edits
log文件,在切换时更新seen_txid的值。上次合并fsimage和editslog之后的第一个操作编号
VERSION文件是一个Java的属性文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Hs4wkL8-1617441280668)(media/30312a66f806764afcbaa5d23643d221.jpeg)]
layoutVersion是一个负数,定义了HDFS持久化数据结构的版本。这个版本数字跟hadoop发行的版本无关。当layout改变的时候,该数字减1(比如从-57到-58)。当对HDFDS进行了升级,就会发生layoutVersion的改变。
namespaceID是该文件系统的唯一标志符,当NameNode第一次格式化的时候生成。
clusterID是HDFS集群使用的一个唯一标志符,在HDFS联邦的情况下,就看出它的作用了,因为联邦情况下,集群有多个命名空间,不同的命名空间由不同的NameNode管理。
blockpoolID是block池的唯一标志符,一个NameNode管理一个命名空间,该命名空间中的所有文件存储的block都在block池中。
cTime标记着当前NameNode创建的时间。对于刚格式化的存储,该值永远是0,但是当文件系统更新的时候,这个值就会更新为一个时间戳。
storageType表示当前目录存储NameNode内容的数据结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBLd6WWb-1617441280670)(media/026dc5e478177aa23a678fb4c6a99ca0.emf)]
当文件系统客户端进行了写操作(例如创建或移动了文件),这个事务首先在edits
log中记录下来。NameNode在内存中有文件系统的元数据,当edits
log记录结束后,就更新内存中的元数据。内存中的元数据用于响应客户端的读请求。
edits
log在磁盘上表现为一定数量的文件。每个文件称为片段(Segment),前缀“edits”,后缀是其中包含的事务ID(transaction
IDs)。每个写操作事务都仅仅打开一个文件(比如:edits_inprogress_00000000000010),写完后冲刷缓冲区并同步到磁盘,然后返回客户端success状态码。如果NameNode的元数据需要写到多个目录中,则对于每个写事务需要所有的写操作都完成,并冲刷缓冲区同步到磁盘才返回success状态码。这样就可以保证在发生宕机的时候没有事务数据丢失。
用户的操作是一个事务,每个操作NN都要先将操作记录到edits
log中,如果给NN指定了多个目录,则在多个目录中都存在edits
log文件,用户的操作要在多个目录中都写完成,才让NN同步数据到内存中。当NN在内存中也同步了数据,就返回客户端success。
每个fsimage文件都是系统元数据的一个完整的持久化检查点(checkpoint)(后缀表示镜像中的最后一个事务)。写操作不更新这个数据,因为镜像文件通常为GB数量级,写到磁盘很慢。如果NameNode宕机,可以将最新fsimage加载到内存,同时执行edits
log对应于该faimage之后的操作,就可以重建元数据的状态。而这正是每次启动NameNode的时候NameNode要做的工作。
tb_user
update tb_user set username=‘张三’ where id=7000;
my.log : update tb_user set username=‘张三’ where id=7000;
SecondaryNameNode
存在的意义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ao3ReYDr-1617441280672)(media/65cd55a5513a8174cf85dc53d4e7962b.GIF)]
edits
log会随着对文件系统的操作而无限制地增长,这对正在运行的NameNode而言没有任何影响,如果NameNode重启,则需要很长的时间执行edits
log的记录以更新fsimage(元数据镜像文件)。在此期间,整个系统不可用。
在系统启动期间,NameNode合并fsimage+edits log
fsimage=0
edist log=很大
内存
fsimage=GB
edits log=很大 TB
内存->执行edits log条目
解决方案就是运行SecondaryNameNode,它的作用就是为NameNode内存中的文件系统元数据生成检查点(checkpoint)。fsimage
工作流程
edits_inprogress_00000000018_0000000028 seen_txid=29
1、secondarynamenode请求namenode生成新的edits
log文件并向其中写日志。NameNode会在所有的存储目录中更新seen_txid文件
2、SecondaryNameNode通过HTTP GET的方式从NameNode下载fsimage和edits文件到本地。
3、SecondaryNameNode将fsimage加载到自己的内存,并根据edits
log更新内存中的fsimage信息,然后将更新完毕之后的fsimage写到磁盘上。
4、SecondaryNameNode通过HTTP
PUT将新的fsimage文件发送到NameNode,NameNode将该文件保存为.ckpt的临时文件备用。
5、NameNode重命名该临时文件并准备使用。此时NameNode拥有一个新的fsimage文件和一个新的很小的edits
log文件(可能不是空的,因为在SecondaryNameNode合并期间可能对元数据进行了读写操作)。管理员也可以将NameNode置于safemode,通过hdfs
dfsadmin -saveNamespace命令来进行edits log和fsimage的合并。
SecondaryNameNode要和NameNode拥有相同的内存。对大的集群,SecondaryNameNode运行于一台专用的物理主机。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jZAugtd-1617441280674)(media/369e6715b9b3afa365aa839604b8ba77.png)]
检查点创建时机
对于创建检查点(checkpoint)的过程,有三个参数进行配置:
1、默认情况下,SecondaryNameNode每个小时进行一次checkpoint合并
由dfs.namenode.checkpoint.period设置,单位秒
2、在不足一小时的情况下,如果edits
log存储的事务达到了1000000个也进行一次checkpoint合并
由dfs.namenode.checkpoint.txns设置事务数量
3、事务数量检查默认每分钟进行一次
由dfs.namenode.checkpoint.check.period设置,单位秒。
总结:
namenode 管理文件元数据 文件名称、大小、所属关系、权限、副本大小、副本个数 文件块的列表信息:(块的ID,偏移量,块的大小,块所在的主机名称列表) 持久化文件 fsimage(内存快照),edits log fsimage很大,GB级别;edits log只追加的文件 用户操作首先记录到edits log中,然后更新内存 fsimage不保存数据块位置信息 在系统启动的时候,datanode向namenode发送文件块列表信息(bid) datanode通过心跳向namenode汇报列表信息。 namenode元数据正常工作时,元数据放内存,高并发。 secondarynamenode 在系统启动的时候,namenode首先加载fsimage,然后逐条执行edits log中的日志操作,如果edits log很大,则需要很长时间才能加载完毕,向磁盘写新的fsimage,之后才可以对外提供服务。 周期性地从namenode拷贝fsimage+edits log,在SNN中合并为新的fsimage,推送给namenode。 条件:1、每小时一次,2、不足一小时,则只要edits log中记录的事务数达到了1000000,则合并。 datanode ? |
存储结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fRQgyt4S-1617441280676)(media/f841efd874d73b6fbda5babf859e3751.jpeg)]
1、SecondaryNameNode中checkpoint目录布局(dfs.namenode.checkpoint.dir)和NameNode中的一样。
2、如果NameNode完全坏掉(没有备用机,也没有NFS),可以快速地从SecondaryNameNode恢复。有可能丢数据
3、如果SecondaryNameNode直接接手NameNode的工作,需要在启动NameNode进程的时候添加-importCheckpoint选项。该选项会让NameNode从由dfs.namenode.checkpoint.dir属性定义的路径中加载最新的checkpoint数据,但是为了防止元数据的覆盖,要求dfs.namenode.name.dir定义的目录中没有内容。
DataNode
存储结构
DataNode不需要显式地格式化;关键文件和目录结构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nW6TQyh0-1617441280677)(media/fedc2642c516021f975dd37895c3239d.png)]
1、HDFS块数据存储于blk_前缀的文件中,包含了被存储文件原始字节数据的一部分。
2、每个block文件都有一个.meta后缀的元数据文件关联。该文件包含了一个版本和类型信息的头部,后接该block中每个部分的校验和。
3、每个block属于一个block池,每个block池有自己的存储目录,该目录名称就是该池子的ID(跟NameNode的VERSION文件中记录的block池ID一样)。
当一个目录中的block达到64个(通过dfs.datanode.numblocks配置)的时候,DataNode会创建一个新的子目录来存放新的block和它们的元数据。这样即使当系统中有大量的block的时候,目录树也不会太深。同时也保证了在每个目录中文件的数量是可管理的,避免了多数操作系统都会碰到的单个目录中的文件个数限制(几十几百上千个)。
如果dfs.datanode.data.dir指定了位于在不同的硬盘驱动器上的多个不同的目录,则会通过轮询的方式向目录中写block数据。需要注意的是block的副本不会在同一个DataNode上复制,而是在不同的DataNode节点之间复制。
存储数据模型(重点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1AFlIOF-1617441280679)(media/73342bd5881fc44c8ab39f2428f8ceb7.GIF)]
1、文件线性切割成块(Block)(按字节切割)
2、Block分散存储在集群节点中
3、单一文件Block大小一致,文件与文件可以不一致
hdfs dfs -D dfs.blocksize=1048576 -D dfs.replication=3 -put hello.txt /
4、Block可以设置副本数,副本分散在不同节点中
a) 副本数不要超过节点数量
b) 承担计算
c) 容错
5、文件上传可以设置Block大小和副本数
6、已上传的文件Block副本数可以调整,大小不变
7、只支持一次写入多次读取,同一时刻只有一个写入者
对同一个文件,一个时刻只有一个写入者
8、可以append追加数据
优势(了解)
- 一个文件的大小可以大于网络中任意一个磁盘的容量
- 使用抽象块而非整个文件作为存储单元,大大简化存储子系统的设计
- 块非常适合用于数据备份进而提供数据容错能力和提高可用性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkrMHX7C-1617441280681)(media/f02c81179087d7f65792cdffea395437.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iZXX6h4D-1617441280682)(media/f39519b2183959f7b40c19e80b0cbb16.jpeg)]数据块副本放置策略
Block的副本放置策略
第一个副本:放置在上传文件的DN;如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点。
第二个副本:放置在于第一个副本不同的 机架的节点上。
第三个副本:与第二个副本相同机架的节点。
更多副本:随机节点
源代码:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7AWDmCVx-1617441280684)(media/c9c1682ab9b3629e705577957b399ced.png)]
HDFS的权限(了解)
1、每个文件和目录都和一个拥有者和组相关联。
2、文件或者目录对与拥有者、同组用户和其他用户拥有独立的权限。
3、对于一个文件,r表示读取的权限,w表示写或者追加的权限。对于目录而言,r表示列出目录内容的权限,w表示创建或者删除文件和目录的权限,x表示访问该目录子项目的权限。
4、默认情况下hadoop运行时安全措施处于停用模式。一个客户端可以在远程系统上通过创建和任意一个合法用户同名的账号来进行访问。
hadoop root
5、安全措施可以防止用户或自动工具及程序意外修改或删除文件系统的重要部分。(dfs.permissions.enabled属性)。防止好人做错事。
6、超级用户是namenode进程的标识。对于超级用户,系统不会执行任何权限检查。
hadoop的安全模式
工作流程(理解)
- 启动NameNode,NameNode加载fsimage到内存,对内存数据执行edits
log日志中的事务操作。 - 文件系统元数据内存镜像加载完毕,进行fsimage和edits
log日志的合并,并创建新的fsimage文件和一个空的edits log日志文件。 - NameNode等待DataNode上传block列表信息,直到副本数满足最小副本条件。
- 当满足了最小副本条件,再过30秒,NameNode就会退出安全模式。最小副本条件指整个文件系统中有99.9%的block达到了最小副本数(默认值是1,可设置)
在NameNode安全模式(safemode)
- 对文件系统元数据进行只读操作
- 当文件的所有block信息具备的情况下,对文件进行只读操作
- 不允许进行文件修改(写,删除或重命名文件)
注意事项
- NameNode不会持久化block位置信息;DataNode保有各自存储的block列表信息。正常操作时,NameNode在内存中有一个block位置的映射信息。
- NameNode在安全模式,NameNode需要给DataNode时间来上传block列表信息到NameNode。如果NameNode不等待DataNode上传这些信息的话,则会在DataNode之间进行block的复制,而这在大多数情况下都是非必须的(因为只需要等待DataNode上传就行了),还会造成资源浪费。
- 在安全模式NameNode不会要求DataNode复制或删除block。
- 新格式化的HDFS不进入安全模式,因为DataNode压根就没有block。
配置信息
属性名称 | 类型 | 默认值 | 描述 |
dfs.namenode.replication.min hdfs-site.xml | Int | 1 | 写文件成功的最小副本数 |
dfs.namenode.safemode.threshold-pct | float | 0.999 | 系统中block达到了最小副本数的比例,之后NameNode会退出安全模式。小于等于0表示不进入安全模式,大于1表示永不退出安全模式 |
dfs.namenode.safemode.extension | int ms | 30000 | 当副本数达到最小副本条件之后安全模式延续的时间。对于小的集群(几十个节点),可以设置为0 |
命令操作(了解)
通过命令查看namenode是否处于安全模式:
$ hdfs dfsadmin -safemode get
Safe mode is ON
HDFS的前端webUI页面也可以查看NameNode是否处于安全模式。
有时候我们希望等待安全模式退出,之后进行文件的读写操作,尤其是在脚本中,此时:
$ hdfs dfsadmin -safemode wait
# your read or write command goes here
管理员有权在任何时间让namenode进入或退出安全模式。进入安全模式:
$ hdfs dfsadmin -safemode enter
Safe mode is ON
这样做可以让namenode一直处于安全模式,也可以设置dfs.namenode.safemode.threshold-pct为1做到这一点。
离开安全模式:
$ hdfs dfsadmin -safemode leave
Safe mode is OFF
HDFS写文件流程(重点)
流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPl0y2GI-1617441280687)(media/cf8a4f842617cdb3710347d3a8c1ec3c.png)]
- 调用客户端的对象DistributedFileSystem的create方法;
- DistributedFileSystem会发起对namenode的一个RPC连接,请求创建一个文件,不包含关于block块的请求。namenode会执行各种各样的检查,确保要创建的文件不存在,并且客户端有创建文件的权限。如果检查通过,namenode会创建一个文件(在edits中,同时更新内存状态),否则创建失败,客户端抛异常IOException。
- DistributedFileSystem返回一个FSDataOutputStream对象给客户端用于写数据。FSDataOutputStream封装了一个DFSOutputStream对象负责客户端跟datanode以及namenode的通信。
- FSDataOutputStream对象将数据切分为小的数据包(64kb,core-default.xml:file.client-write-packet-size默认值65536),并写入到一个内部队列(“数据队列”)。DataStreamer会读取其中内容,并请求namenode返回一个datanode列表来存储当前block副本。列表中的datanode会形成管线,DataStreamer将数据包发送给管线中的第一个datanode,第一个datanode将接收到的数据发送给第二个datanode,第二个发送给第三个。。。
- DFSOoutputStream维护着一个数据包的队列,这的数据包是需要写入到datanode中的,该队列称为确认队列。当一个数据包在管线中所有datanode中写入完成,就从ack队列中移除该数据包。如果在数据写入期间datanode发生故障,则执行以下操作
- 关闭管线,把确认队列中的所有包都添加回数据队列的最前端,以保证故障节点下游的datanode不会漏掉任何一个数据包。
- 为存储在另一正常datanode的当前数据块指定一个新的标志,并将该标志传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块。
- 从管线中删除故障数据节点并且把余下的数据块写入管线中另外两个正常的datanode。namenode在检测到副本数量不足时,会在另一个节点上创建新的副本。
- 后续的数据块继续正常接受处理。
- 在一个块被写入期间可能会有多个datanode同时发生故障,但非常少见。只要设置了dfs.replication.min的副本数(默认为1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标副本数(dfs.replication默认值为3)。
- 如果有多个block,则会反复从步骤4开始执行。
- 当客户端完成了数据的传输,调用数据流的close方法。该方法将数据队列中的剩余数据包写到datanode的管线并等待管线的确认
- 客户端收到管线中所有正常datanode的确认消息后,通知namenode文件写完了。
- namenode已经知道文件由哪些块组成,所以它在返回成功前只需要等待数据块进行最小量的复制。
了解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JgsUNlae-1617441280688)(media/eabe68b983680bb995ca2d0ac7d01457.png)]
64KB数据包包含的头部信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gfSkgJ9c-1617441280689)(media/a60e613688e6482b86f9c708cfc9da09.png)]
packet接收者:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1HCwryWy-1617441280691)(media/2e9cef6918bfaa1e4fa78a84b8384129.png)]
64KB数据包格式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MbikL0Kd-1617441280692)(media/2d337c6209c070886b6c79dd6f295c2f.png)]
HDFS读文件流程(重点)
流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZvhzJnJ-1617441280694)(media/0506c452baabcb08731fe0e746047665.png)]
- 客户端通过FileSystem对象的open方法打开希望读取的文件,DistributedFileSystem对象通过RPC调用namenode,以确保文件起始位置。对于每个block,namenode返回存有该副本的datanode地址。这些datanode根据它们与客户端的距离来排序。如果客户端本身就是一个datanode,并保存有相应block一个副本,会从本地读取这个block数据。
- DistributedFileSystem返回一个FSDataInputStream对象给客户端读取数据。该类封装了DFSInputStream对象,该对象管理着datanode和namenode的I/O,用于给客户端使用。客户端对这个输入调用read方法,存储着文件起始几个block的datanode地址的DFSInputStream连接距离最近的datanode。通过对数据流反复调用read方法,可以将数据从datnaode传输到客户端。到达block的末端时,DFSInputSream关闭与该datanode的连接,然后寻找下一个block的最佳datanode。客户端只需要读取连续的流,并且对于客户端都是透明的。
- 客户端从流中读取数据时,block是按照打开DFSInputStream与datanode新建连接的顺序读取的。它也会根据需要询问namenode来检索下一批数据块的datanode的位置。一旦客户端完成读取,就close掉FSDataInputStream的输入流。
- 在读取数据的时候如果DFSInputStream在与datanode通信时遇到错误,会尝试从这个块的一个最近邻datanode读取数据。它也记住那个故障datanode,保证以后不会反复读取该节点上后续的block。DFSInputStream也会通过校验和确认从datanode发来的数据是否完整。如果发现有损坏的块,就在DFSInputStream试图从其他datanode读取其副本之前通知namenode。
注意
namenode告知客户端每个block中最佳的datanode,并让客户端直接连到datanode检索数据。由于数据流分散在集群中的所有datanode,这样可以使HDFS可扩展到大量的并发客户端。同时,namenode只需要响应block位置的请求,无需响应数据请求,否则namenode会成为瓶颈。
最近邻(了解)
hadoop把网络看作是一棵树,两个节点间的距离是它们到最近共同祖先的距离和。通常可以设置等级:
- 同一个节点上的进程
- 同一机架上的不同节点
- 同一数据中心中不同机架上的节点
- 不同数据中心中的节点
伪分布式搭建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-diFmtPnJ-1617441280695)(media/cdb7f73dbc613324b54368470f7cf8cc.jpeg)]
hadoop官网地址:
中文文档:
http://hadoop.apache.org/docs/r1.0.4/cn
apache老版本软件下载地址:
http://archive.apache.org/hadoop/
上传hadoop的tar包和jdk的rpm包
hadoop-2.6.5.tar.gz
jdkxxx.rpm
安装jdk并配置环境变量
rpm -ivh jdk.rpm vim /etc/profile export JAVA_HOME=/usr/java/default export PATH=$PATH:$JAVA_HOME/bin 关闭vim 执行 source /etc/profile 或者 . /etc/profile |
配置免密钥
ssh-keygen -t dsa -P ‘’ -f ~/.ssh/id_dsa cat ~/.ssh/id_dsa.pub > ~/.ssh/authorized_keys |
解压hadoop-2.6.5.tar.gz到/opt目录
tar -zxf hadoop-2.6.5.tar.gz -C /opt |
添加环境变量
将HADOOP_HOME以及HADOOP_HOME/bin和HADOOP_HOME/sbin添加到环境变量
export HADOOP_HOME=/opt/hadoop-2.6.5 export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin |
hadoop-env.sh配置
$HADOOP_HOME/etc/hadoop
由于通过SSH远程启动进程的时候默认不会加载/etc/profile设置,JAVA_HOME变量就加载不到,需要手动指定。
export JAVA_HOME=/usr/java/jdk1.8.0_221-amd64 |
core-site.xml
<configuration> <!-- 指定访问HDFS的时候路径的默认前缀 / hdfs://node1:9000/ --> <property> <name>fs.defaultFS</name> <value>hdfs://node1:9000</value> </property> <!-- 指定hadoop的临时目录位置,它会给namenode、secondarynamenode以及datanode的存储目录指定前缀 --> <property> <name>hadoop.tmp.dir</name> <value>/var/bjsxt/hadoop/pseudo</value> </property> </configuration> |
hdfs-site.xml
<configuration> <!-- 指定block副本数 --> <property> <name>dfs.replication</name> <value>1</value> </property> <!-- 指定secondarynamenode所在的位置 --> <property> <name>dfs.namenode.secondary.http-address</name> <value>node1:50090</value> </property> </configuration> |
slaves
DataNode所在的节点
node1 |
格式化
hdfs namenode -format |
启动
start-dfs.sh |
查看进程
jps |
上传文件
生成本地文件:
for i in `seq 100000`; do echo “hello bjsxt $i” >> hello.txt; done
hdfs dfs -put /root/hello.txt / hdfs://node1:9000/ |
hdfs dfs -D dfs.blocksize=1048576 -D dfs.replication=1 -put hh.txt /
关闭
stop-dfs.sh |
总结-1
大文件如何存储? 单台服务器放不下,切块,将块打散放在各个datanode中 文件要放进去,还要取出来 文件分了多少块,每个块偏移量是多少,大小是多少 在哪些datanode上。 元数据: 一个文件的元数据放在NameNode的内存中 放内存中应付高并发 元数据很小,可以放内存 方便用户浏览 方便客户端操作 |
start-dfs.sh |
-------------- |
查看进程
jps |
上传文件
生成本地文件:
for i in `seq 100000`; do echo “hello bjsxt $i” >> hello.txt; done
hdfs dfs -put /root/hello.txt / hdfs://node1:9000/ |
hdfs dfs -D dfs.blocksize=1048576 -D dfs.replication=1 -put hh.txt /
关闭
stop-dfs.sh |
总结-1
大文件如何存储? 单台服务器放不下,切块,将块打散放在各个datanode中 文件要放进去,还要取出来 文件分了多少块,每个块偏移量是多少,大小是多少 在哪些datanode上。 元数据: 一个文件的元数据放在NameNode的内存中 放内存中应付高并发 元数据很小,可以放内存 方便用户浏览 方便客户端操作 |