第四次作业
用图与自己的话,简要描述Hadoop起源与发展阶段
Hadoop:适合大数据的分布式存储和计算平台
Hadoop不是指具体一个框架或者组件,它是Apache软件基金会下用Java语言开发的一个开源分布式计算平台。实现在大量计算机组成的集群中对海量数据进行分布式计算。适合大数据的分布式存储和计算平台。
Hadoop1.x中包括两个核心组件:MapReduce和Hadoop Distributed File System(HDFS)
其中HDFS负责将海量数据进行分布式存储,而MapReduce负责提供对数据的计算结果的汇总
2003-2004年,Google公布了部分GFS和MapReduce思想的细节,受此启发的Doug Cutting等人用2年的业余时间实现了DFS和MapReduce机制,使Nutch性能飙升。然后Yahoo招安Doug Gutting及其项目。
2005年,Hadoop作为Lucene的子项目Nutch的一部分正式引入Apache基金会。
2006年2月被分离出来,成为一套完整独立的软件,起名为Hadoop
Hadoop名字不是一个缩写,而是一个生造出来的词。是Hadoop之父Doug Cutting儿子毛绒玩具象命名的。
Hadoop的成长过程
Lucene–>Nutch—>Hadoop
用图与自己的话,简要描述名称节点、第二名称节点、数据节点的主要功能及相互关系
在HDFS中,名称节点(NameNode)负责管理分布式文件系统的命名空间(Namespace),保存了两个核心的数据结构,即FsImage和EditLog
FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据
操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作
第二名称节点:是HDFS架构中的一个组成部分,它是用来保存名称节点中对HDFS 元数据信息的备份,并减少名称节点重启的时间。
SecondaryNameNode一般是单独运行在一台机器上
DataNode:数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表
3.分别从以下这些方面,梳理清楚HDFS的 结构与运行流程,以图的形式描述。
3个副本机制
(1)2个副本放在本地机架上的不同节点,1个副本放在另外机架上的节点。
(2)1个副本放在本机机架上的节点,2个副本放在另外一个机架上的不同节点。
客户端读
读:
(1)客户端通过调用FIleSystem对象的open()方法来打开希望读取的文件,对于hdfs来说,这个对象是分布式文件系统的一个实例。
(2)DistributedFileSystem通过使用rpc来调用namenode,以确定文件起始块的位置。对于每一个块,namenode返回存有该块副本的datanode的地址。此外,这些datanode根据他们与客户端的距离来排序(机架感应)。如果该客户端本身就是一个datanode(比如,在一个MapReduce任务中),并保存有相应数据块的一个副本时,该节点将从本地datanode中读取数据。
(3)DistributedFileSystem类返回一个FSDataInputStream对象(支持文件定位的输入流)给客户端读取数据。FSDataInput类转而封装DFSInputStream对象,该对象管理着datanode、namenode的I/O。接着,客户端对这个输入流调用read()方法。
(4)存储着文件起始块的datanode地址的DFSInputStream 随即连接距离最近的文件中第一个块所在的datanode。通过对数据流反复调用read()方法,可以将数据从datanode传输到客户端。
(5)到达块的末端时,DFSInputStream 会关闭与该datanode的连接,然后寻找下一个块的最佳datanode。客户端只需要读取连续的流,并且对于客户端都是透明的。客户端从流中读取数据时,块是按照打开DFSInputStream与datanode新建连接的顺序读取的。它根据需要询问namenode来检索下一批所需块的datanode的位置。
(6)一旦客户端读取完成,就对FSDataInputStream调用close()方法,在读取数据的时候,如果DFSInputStream在与datanode通信时遇到错误,它便尝试从这个块的另外一个最邻近的datanode读取数据。它也会记住哪个故障的datanode,以保证以后不会反复读取该节点上后续的块。DFSInputStream也会通过校验和确认从datanode发来的数据是否完整。如果发现一个损坏的块,它就会在DFSInputStream 试图从其他datanode读取一个块的副本,也会将被损坏的块通知给namonode。
这个设计的一个重点是,客户端可以直接连接到datanode检索数据,且namenode告诉客户端每个块中的最佳datanode。由于数据流分散在该集群中所有的datanode,所以这种设计能使HDFS可扩展到大量的并发客户端。同时,namenode仅需要响应快位置的请求(这些信息存储在内存中,因而非常高效),而无需响应数据请求,否则随着客户端数量的增长,namenode很快会成为一个瓶颈。
客户端写
(1)客户端通过对DistributeFileSystem 对象调用create()函数来创建文件。
(2)DistributedFileSystem 对namenode创建一个rpc调用,在文件系统的命名空间中创建一个新文件,但是此时该文件中还没有相应的数据块,namenode执行各个不同的检查以确保这个文件不存在,并且客户端有创建该文件的权限。如果这些检查均通过,namenode就会为创建新文件记录一条记录,否则,文件创建失败并向客户端抛出一个IoException异常。
(3)DistributeFileSystem向客户端返回一个FSDataOutrputStream对象,由此客户端可以开始写入数据。就像读取事件一样,FSDataOutputStream封装一个DFSoutputstream对象,该对象负责处理datanode和namenode之间的通信。在客户端写入数据时,DFSoutputStream将它分成一个个的数据包,并写入内部队列,成为数据队列(data queue)
(4)dataStreamer处理数据队列,它的责任是根据datanode列表来要求namenode分配适合的新块来存储数据备份。这一组datanode构成一个管道(pip管道)---我们假设副本数是3,所以管道中有3个节点。dataStream将数据包流式传输到管道中第一个datanode,该datanode存储数据包之后,并将它发送到管道中第二个datanode中,同样操作,第二个datanode 将数据包存储后给第三个datanode。
(5)DFSOoutputStream也维护着一个内部数据包队列来等待datanode的收到确认回执,称为"确认队列"(ack queue)。当收到管道中所有的datanode确认信息后,该数据包才会从确认队列删除。
如果在数据写入期间,datanode发生故障,则执行以下操作,这对与写入数据的客户端是透明的。首先关闭管道,确认把队列中的任何数据包都添回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包。为存储在另一个正常datanode的当前数据块制定一个新的标识,并将该标识传送给namenode。以便故障datanode在恢复后可以删除存储的部分数据块。从管道中删除故障数据节点并且把余下的数据块写入管道中剩余的两个正常的datanode。namenode注意到块副本量不足时,会在另一个节点上创建一个新的副本。后续的数据块继续正常接受处理。
(6)客户端完成数据的写入后,会对数据流调用close()方法。
(7)该操作将剩余的所有数据包写入datanode管道中,并在联系namenode发送文件写入完成信号之前,等待确认。namenode已经知道文件由哪些块组成(通过DataStreamer询问数据块的分配),所以它在返回成功只需要等待数据块进行最小量的复制。
数据结点与集群
1)HDFS集群分为两大角色:NameNode、DataNode
2)NameNode负责管理整个文件系统的元数据
3)DataNode负责管理用户的文件数据块
4)文件会按照固定的大小(blocksize)切成若干块后分布式存储在若干台datanode上
5)每一个文件块可以有多个副本,并存放在不同的datanode上
6)DataNode会定期向NameNode汇报自身保存的block信息,而namenode则会负责保持文件的副本数量
7)HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过namenode申请来进行
数据结点与名称结点
NameNode和DataNode
-HDFS集群有两种节点类型,Namenodes和Datanodes,它们工作于master-worker模式。一个namenode是master,一组datanodes是workers。namenode管理整个文件系统的namespace。
它维护一棵文件树和所有文件/目录的元信息。这些信息在namenode的本地磁盘上存成两个文件,一个是该namespace的镜像,另一个是编辑日志(edit log)。
namenode也知道每个文件的每个块都存在哪个datanode上了,但这个信息不会被持久化下来,因为每次启动时,这个信息会被重新生成。
-客户端程序通过访问namenode和datanodes来访问HDFS文件系统。但是用户代码根本不知道namenode和datanodes的存在,就像访问POSIX一样(Portable Operating System Interface:便携计算机系统接口)。
Datanodes是干苦力活的。当被客户端或namenode命令时,它存储和检索文件块(blocks)。它还会定期向namenode汇报它们存储的文件块列表。
-没有namenode,整个文件系统就没法用了。如果把namenode移除,整个文件系统里的文件就都丢失了,因为没办法知道如何重新组装存在各个datanodes里的文件块。
因此有必要保证namenode足够可靠,Hadoop提供了两种机制保证namenode里的数据安全。
-第一个机制是备份namenode上的持久化信息。可以配置hadoop,让namenode写持久化信息时写到多个地方,并且这些写操作是串行的并且是原子操作。通常的做法是写到本地磁盘一份,同时写到远程NFS上。
-另一个机制是配一个secondary namenode。虽然名字上叫namenode,但secondary namenode根本不做namenode的工作,它就是定期把namenode上的namespace镜像和编辑日志(edit log)合并到自己身上,以避免编辑日志过大。
secondary namenode通常是一台单独的机器,因为合并工作需要大量的CPU和内存资源。因为它的状态迟于namenode,所以,当namenode发生事故时,肯定是会有数据丢失的。
通常的做法是把namenode在NFS上的metadata文件拷贝到secondary namenode,然后启动这个secondary namenode,让它成为namenode。
名称结点与第二名称结点
这里的第一名称节点类似于数据目录。其主要有两大构件构成,FsImage和Editlog,FsImage用于存储元数据(长时间不更新、Editlog用于更新数据,但是随着时间推移,Editlog内存储的数据越来越多,导致运行速度越来越慢。
所以引入第二名称节点,当第一节点中Editlog到一个临界值时,HDFS会暂停服务,由第二节点将拷贝出Editlog,复制、添加到Fslmage后方并清空原Editlog的内容。这里有一点要注意这种备份是冷备份的形式,即没有实时性,需要停止服务,等数据恢复正常后继续使用。
这是HDFS1.0时候处理名称节点单点故障的方法,因为它是冷备份的,不适用于大数据,所以在2.0时进行了改进。
HA(High Availability)高可用性
HA框架是有两个名称节点,一个是活跃节点一个是待命节点,当活跃节点出现故障时,待命节点直接顶替上去,不需要像1.0的时候那样停止备份再运行。
刚刚知道 名称节点是有Fslmage和Editlog的,那么HA框架是怎么解决待命名称节点Fslmage和Editlog的同步的呢?
活跃节点和待命节点之间存在一个共享存储系统,活跃节点的Editlog文件会实时存放到共享存储系统中,待命节点也会实时的去领取备份。Fslmage是实现管家的功能,在2.0中,数据节点会实时同步的给名称节点和备份名称节点发送数据(例如节点是否存活,正常等),即Fslmage是实时相当的。
数据冗余
每个文件都会有多个副本分散在不同的DataNode上,NameNode时刻监视文件的副本量,如果小于设定的值就找一台DataNode增加副本数。一般至少有3分副本才能保证数据安全,保证某个DataNode在死掉的情况下依然能提供客户端及时获取文件数据
数据存取策略
HDFS支持六种数据存储策略,分别是:
- COLD
- WARM
- HOT
- ONE_SSD
- ALL_SSD
- LAZY_PERSIST
按照ALL_SSD -> ONE_SSD -> HOT -> WARM -> COLD的顺序,面向的数据是越来越冷
HDFS数据错误分三种:名称节点错误、数据节点错误、数据块错误
数据错误与恢复
1、数据节点错误
数据节点周期性发送心跳信息给名称节点,报告数据节点的状态信息。
当数据节点发生故障或者网络故障,名称节点无法收到数据节点的心跳信息,标记该数据节点为“宕机”,节点上的所有数据标记为不可读,名称节点不会像该数据节点发送如何I/O请求。
该数据节点上的数据块的副本数量小于冗余因子。名称节点周期检查这种情况,一旦发现某个数据块的副本数量小于冗余因子,启动数据冗余复制,为它生成新的副本。
2、数据块错误
文件被创建时,客户端会对每一个文件块进行信息摘录,并把这些信息写入同一个路径的隐藏文件里面。
当客户端读取文件的时候,会先读取该信息文件,然后利用该信息我呢间对每个读取的数据块进行校验,如果校验出错,客户端就会请求另外一个数据节点读取该文件块,并向名称节点报告该文件块有错误,名称节点会定期检查并重新复制该数据块。
3、名称节点出错
名称节点保存所有元数据信息,核心数据结构是FsImage和EditLog
HDFS HA机制
Master主服务器的功能
HBase系统基本架构中主服务器Master的作用是主要负责表和Region的管理工作
- master通过zookeeper跟踪region server状态(就是每个节点再zookeeper上建立一个临时node)zookeeper原理
- 如果节点上限,会在zookeeper上的server目录下建立代表自己的文件,并且获取该文件的独占锁。
- master订阅了zookeeper上server目录的变更信息(childrenchanged等),就可以知道server目录下的文件数量变更,从而可以动态感知集群中节点的上线状态
提供一个简单的原语集合,以便于分布式应用可以在它之上构建更高层次的同步服务
设计非常易于编程,它使用的是类似于文件系统那样的树形数据结构
目的就是将分布式服务不再需要由于协作冲突而另外实现协作服务
Client客户端的请求流程
base的Client怎么与Server端进行交互的呢?具体步骤可以分为以下几步
- 首先Client通过访问hbase:meta元数据表找到指定范围row所处的regions,以及对应的RegionServers;
- 在确定region之后,Client不会与Master进行交互,而是直接与RegionServer交互,让其开启对指定region的服务;
- 然后RegionServer开始处理对应的read and write请求;
- 同时Client会将这些region的交互信息缓存在内存中,以保证下次请求服务端就不用再查询hbase:meta重新定位;
- 一旦一个被请求的region被重新负载均衡分配到其它的RegionServer上,那么Client下次查询的时候才会重新访问hbase:meta,并且更新缓存的region信息
Client
1 包含访问hbase的接口,client维护着一些cache来加快对hbase的访问,比如regione的位置信息。
Zookeeper
1 保证任何时候,集群中只有一个master
2 存贮所有Region的寻址入口。
3 实时监控Region Server的状态,将Region server的上线和下线信息实时通知给Master
4 存储Hbase的schema,包括有哪些table,每个table有哪些column family
Master
1 为Region server分配region
2 负责region server的负载均衡
3 发现失效的region server并重新分配其上的region
4 GFS上的垃圾文件回收
5 处理schema更新请求
Region Server
1 Region server维护Master分配给它的region,处理对这些region的IO请求
2 Region server负责切分在运行过程中变得过大的region
可以看到,client访问hbase上数据的过程并不需要master参与(寻址访问zookeeper和region server,数据读写访问regione server),master仅仅维护者table和region的元数据信息,负载很低。
与HDFS的关联
HDFS是GFS的一种实现,他的完整名字是分布式文件系统,类似于FAT32,NTFS,是一种文件格式,是底层的,Hadoop HDFS为HBase提供了高可靠性的底层存储支持。
HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统。
Hadoop 中各模块的作用:
1、Hadoop HDFS为HBase提供了高可靠性的底层存储支持。
2、Hadoop MapReduce为HBase提供了高性能的计算能力。
3、Zookeeper为HBase提供了稳定服务和failover机制。
4、Pig和Hive还为HBase提供了高层语言支持,使得在HBase上进行数据统计处理变得非常简单。
5、Sqoop则为HBase提供了方便的RDBMS(关系型数据库)数据导入功能,使得传统数据库数据向HBase中迁移变得非常方便。
5.理解并描述Hbase表与Region与HDFS的关系。
1. 对于经常需要修改原有的数据的场景使用Hbase进行存储;
2. 对于性能要求不高且只需要支持单条数据查询或者小批量数据进行查询,两者均可;
3. 对于需要经常进行全表扫描进行大批量的查询的选择HDFS;
现在假设我们要从Table2里面查询一条RowKey是RK10000的数据。那么我们应该遵循以下步骤:
1. 从.META.表里面查询哪个Region包含这条数据。
2. 获取管理这个Region的RegionServer地址。
3. 连接这个RegionServer, 查到这条数据。
系统如何找到某个row key (或者某个 row key range)所在的region
bigtable 使用三层类似B+树的结构来保存region位置。
第一层: 保存zookeeper里面的文件,它持有root region的位置。
第二层:root region是.META.表的第一个region其中保存了.META.表其它region的位置。通过root region,我们就可以访问.META.表的数据。
第三层: .META.表它是一个特殊的表,保存了hbase中所有数据表的region 位置信息。
理解并描述Hbase的三级寻址。
说明:
(1) root region永远不会被split,保证了最需要三次跳转,就能定位到任意region 。
(2).META.表每行保存一个region的位置信息,row key 采用表名+表的最后一行编码而成。
(3) 为了加快访问,.META.表的全部region都保存在内存中。
(4) client会将查询过的位置信息保存缓存起来,缓存不会主动失效,因此如果client上的缓存全部失效,则需要进行最多6次网络来回,才能定位到正确的region(其中三次用来发现缓存失效,另外三次用来获取位置信息)。
假设.META.表的每行(一个映射条目)在内存中大约占用1KB,并且每个Region限制为2GB,通过HBase的三级寻址方式,理论上Hbase的数据表最大有多大