大数据简介
一、大数据特征 - 6V
- 数据体量大,一般从TB级别开始计算
- 数据种类和来源多
- 数据的增长速度越来越快
- 数据的价值密度越来越低,但是这不意味着想要的数据越来越少,相反,想要的数据越来越多的,但是样本总量的增长速度是要高于想要的数据的增长速度的
- 数据的真实性/质量
- 数据的连通性
- 数据的动态性、数据的可视化、合法性
二、概述
- Hadoop是Apache提供的一个开源的、可靠的、可扩展的系统架构,可以利用分布式架构来进行海量数据的存储以及计算
- Hadoop之父:Doug Cutting(道格·卡丁)
- 需要注意的是Hadoop处理的是离线数据,即在数据已知以及不要求实时性的场景下使用
- Hadoop发行版:
a. Apache版本最基本的版本,入门学习较好。原生版本管理相对比较混乱
b. CDH版本是Cloudera提供的商业版本,相对Apache Hadoop更加的稳定和安全
c. Hortonworks文档相对完善友好
三、 版本:
- Hadoop1.0:包含Common,HDFS,和MapReduce ,停止更新
- Hadoop2.0:包含Common,HDFS,和MapReduce,YARN。1.0和2.0完全不兼容,Hadoop2.8之前的不包含ozone
- Hadoop3.0:包含Common,HDFS,和MapReduce,YARN和ozone。
四、模块
- Hadoop Common: 基本模块
- Hadoop Distributed File System (HDFS™): 分布式存储
- Hadoop YARN:进行任务调度和资源管理
- Hadoop MapReduce: 分布式计算
- Hadoop Ozone:对象存储
五、安装方式
- 单机模式:只能启动MapReduce
- 伪分布式:只能启动HDFS,MapReduce和YARN的大部分功能
- 完全分布式:能启动Hadoop的所有功能
HDFS
一、概述
- HDFS是Hadoop提供一套用于进行分布式存储的文件系统
- HDFS根据Google的GFS来进行实现的
特点:
- 能够存储超大文件 - 切块
- 快速的应对和检测故障 - 心跳
- 能够在相对廉价的机器上来进行动态横向扩展
- 不支持低延迟响应
- 不建议存储小文件 - 每一个小文件对应一条元数据,大量的硒筽啊文件就会产生大量的元数据。元数据过多导致内存被大量占用,导致查询效率降低。
- 简化的一致性模型,一次写入多次读取,不允许修改,但允许追加写入。
- 不支持强事务或者不支持事务,在实际开发中,在样本量足够大的前提下,允许存在一定的容量误差
二、基本概念
- HDFS主要包含2类进程:NameNode和DataNode
- 在HDFS中,上传的文件自动的进行切块,每一个数据块称之为一个Block
- HDFS会自动对数据进行备份,每一个备份称之为副本(replication/replicas)默认为3
- HDFS仿照Linux设置一套虚拟的文件系统,根路径/
三、Block
- Block是HDFS中存储数据的基本单位,即在HDFS中所有数据都是以Block形式存储
- Block默认是128M大小,可以通过dfs.blocksize(在hdfs-site.xml,单位是字节)来设置
- 如果一个文件不到一个Block的大小,那么注意,这个文件本身多大block就是多大
- 在HDFS中,会给每一个Block自动分配一个全局递增的Block ID
- 在HDFS中,会给每一个Block分配一个时间戳(Generation Stamp)编号
- 切块的意义
- 为了能够存储超大文件
- 为了能够进行快速备份
四、NameNode
- NameNode是HDFS中的主节点(Master),作用:管理DataNode和记录与元数据(metadata)
- 元数据是描述数据的数据 —在HDFS中,元数据对存储的文件进行描述,主要包含
- 文件的存储路径,例如/txt/a.txt
- 文件的权限
- 上传的用户和用户组
- 文件的大小
- Block的大小
- 文件和BlockID的映射关系
- 副本数量
- BlockID和DataNode的映射关系
- 元数据是存储在内存以及磁盘中
- 维系在内存中的目的是为了快速查询
- 维系在磁盘中的目的是为了崩溃恢复
- 元数据在磁盘中的存储路径由hadoop.tmp.dir(core-site.xml)属性来决定的
- 元数据的记录和fsimage以及edits文件相关
- edits记录写操作
- fsimage:记录元数据。fsimage中的元数据往往是落后于内存中的元数据
- 当NameNode接受到写请求的时候,NameNode会先将这个写请求记录到edits-iprogress中,如果记录成功则修改内存中的元数据。内存中的元数据修改成功之后会给客户端返回一个成功信号。这个过程中fsimage文件中的元数据没有被修改
- 当达到指定条件的时候,触发edits_inprogress文件的滚动,edits_inprogress会滚动生成edits文件,会产生一个新的edits_inprogress。在edits_inprogress滚动过程中,会触发fsimage文件的更新,会根据edits_inprogress中的命令去修改fsimage文件中的元数据
- edits_inprogress文件的滚动条件
- 空间:当edits_inprogress文件达到指定大小(64m通过f s.checkpoint.size,单位是字节 - core-site.xml)的时候,会产生滚动
- 时间:当距离上一次滚动的时间间隔(默认3600s,通过f s.checkpoint.period来调节,默认单位是秒-core site.xml)达到指定大小,会产生滚动
- 重启:当NameNode重启的时候,自动触发edits——inprogress文件的滚动
- 强制滚动:可以利用 hadoop dfsadmin -rollEdits来强制滚动
- NameNode通过心跳机制来管理DataNode, DataNode定时的通过RPC的方式来给NameNode发送心跳。
- 默认情况下是每隔3s给NameNode发送心跳,可以通过dfs.heartbeat.interval来修改,单位是秒 —hdfs site.xml
- NameNode超过10min没有收到DataNode的心跳,就会认为这个DataNode已经Lost(丢失),那么此时NameNode就会讲这个DataNode上的Block备份到其他节点,保证整个集群的副本数量
- 心跳信息
- 当前DataNode的状态(预服役、服役、预退役)
- 当前DataNode存储的Block信息
- clusterid:集群编号。当NameNode被格式化的时候,会自动计算产生一个clusterid,每格式化一次就会重新计算产生,当HDFS集群启动的时候,NameNode会将clusterid分发给每一个DataNode的信息之后,会先校验clusterid是否一致;同样,DataNode收到NameNode的指令的时候也会校验clusterid。DataNode只能接受一次clusterid
- 当NameNode重启的时候,会自动触发edits_inprogress文件的滚动,产生一个新的edits文件和一个新的edits_inprogress文件,同时更新fsimage。当更新完fsimage之后,NameNode就会将fsimage文件中的内容加载到内存中,加载完成后,NameNode等待DataNode的心跳。如果在指定时间内没有收到心跳,则认为节点丢失重新备份。如果收到DataNode的心跳,那么NameNode会校验这个心跳信息,这个过程称之为安全模式。在安全模式中,NameNode如果校验失败,则试图恢复数据,恢复完成之后会重新校验;如果校验成功,则自动退出安全模式。
- 当NameNode重启的时候,自动进入安全模式,实际开发过程中,如果进入安全模式,需要等待NameNode自动退出安全模式,但是在合理的时间内,NameNode没有退出安全模式,就说明数据产生了不可挽回的丢失,此时需要强制退出安全模式(hadoop afsadmin -safemode leave)
- 在安全模式中,HDFS不对外提供写服务
- 正因为有安全模式的存在所以在为分布式中副本数量设置为1;
五、多副本的放置策略
- 第一个副本
- 如果集群内部上传,那么谁上传第一个副本就放在谁身上
- 如果是集群外部上传,NameNode会选择相对较闲的DataNode的节点存储数据
- 第二个副本
- Hadoop2.7之前:第二个副本是放在和第一个副本不同机架的节点上
- Hadoop2.7开始:第二个副本是放在和第一个副本相同机架的节点上
- 第三个副本
- Hadoop2.7之前:第三个副本是放在和第二个副本相同机架的节点上
- Hadoop2.7开始:第三个副本是放在和第二个副本不同机架的节点上
- 更多副本:那个几点相对空闲就放在谁身上
六、 机架感知策略
- 在HDFS中默认没有启用,需要在hadoop-site.xml中配置topology.script.file.name开启机架感知策略
- HDFS的机架感知策略是通过指定的脚本来进行配置,这个脚本可以是python和shell,所谓的机架就是一个映射,只需要将DataNode的主机名或者ip映射到值上就对应了机架
- 机架指的是逻辑机架不是物理机架,允许将一个或几个物理机架上的节点映射到同一个逻辑机架上,但是实际开发中,一般是一个物理机架对应一个逻辑机架
七、DataNode
- DataNode是HDFS中的从节点,作用:存储数据,数据以block的形式来存储
- DataNode会将数据存储在磁盘中,在磁盘上的存储位置由hadoop.tmp.dir属性来决定
- DataNode的状态:预服役,服役,预退役,退役
- DataNode会主动给NameNode发送心跳来进行注册
八、SecondaryNameNode
- SecondaryNameNode并不是NameNode备份,而是辅助NameNode进行edits_inprogress文件的滚动和fsimage的更新
- 在HDFS集群中,如果存在SecondaryNameNode,edits_inprogress文件的滚动和fsimage的更新由SecondaryNameNode来做,如果不存在,上述事情由NameNode自己来做,存活与否不影响集群向外提供服务,只会影响效率
- 在HDFS集群中,支持的结构一般是有两种
- 1个NameNode+1个SecondaryNameNode+多个DataNode
- 2个NameNode+多个DataNode
- 因为在HDFS中,NameNode是核心节点,所以一般要考虑NameNode的备份,那么此时就需要系用双NameNode机制,一个处于active状态,另一个处于备份状态,当active的NameNode宕机后,备份的立即切换为active,在实际工作中以第二方案为主,这样实现了集群的高可用(HA)。
九、回收站机制
- 在HDFS中,回收站机制默认不开启,即删除命令会立即生效,
- 如果要开启回收站机制,要在core-site.xml中配置
十、dfs目录
- dfs目录实际上就是HDFS的数据目录,由hadoop.tmp.dir属性来决定存储路径
- dfs子目录
a. data 对应datanode数据的存储路径
b. name 对应namenode数据的存储路径
c. namesecondary 对应namesecondary数据的存储路径 - 实际开发中,三个子目录应该出现在三个不同的节点上
- in_use.lock用于标记是否已经启动对应的进程
- 每一个blk文件对应一个.meta,这个.meta文件可以认为是对blk的校验
- HDFS在第一次启动的时候,间隔1min之后出发edits_inprogress文件的滚动,之后就按照指定的条件进行滚动
- 在HFDS中,每一次写操作看成一次事务,分配一个全局递增的编号,简称txid
- 文件上传完成之后不能修改
- fsimage_XXXX.md5是利用了md5加密算法对fsimage_xxxx来进行校验
- version文件中包含的主要内容
- clusterID:集群编号 - 本质上是进行校验的
- storageType:节点类型
- blockpooIID:块池编号
Hadoop流程
写流程 -put
- 客户端发起RPC请求到NameNode要求上传文件
- NameNode收到请求之后会进行校验
- 校验上传的路径是否有写入权限
- 检验上传的路径下是否有同名文件
- 如果校验失败,直接报错,如果校验成功,则NameNode会修改edits_inprogress,更新内存中的元数据,最后会给客户端返回一个允许上传的信号。
- 客户端收到信号之后,会给NameNode发送请求,请求获取第一个Block的存储位置
- NameNode收到请求之后,会等待DataNode的心跳,然后选择符合要求的节点(副本放置策略),将节点位置(默认是3个)放入队列中返回给客户端
- 客户端收到队列之后,会从队列中将所有的位置去除,然后选择一个较近的节点将第一个Block的第一个副本写入,客户端同时会告诉第一个副本所在的节点两个副本的存储位置,第一个副本所在的节点就会通过管道(pipeline,本质就是NIO Channel)将第二个副本写入对应的节点同时告诉第二个副本所在的节点最后一个副本的存储位置,第二个副本所在的节点通过管道将第三个副本写入对应的节点;第三个副本写完之后,会给第二个副本所在的节点返回一个ack(确认字符)信号,第二个副本所在的节点会给第一个副本所在的节点返回一个ack;第一个副本所在的节点会给客户端返回一个ack
- 客户端收到ack之后,会向namenode发送请求要下一个Block的存储位置,重复4,5,6三个步骤
- 当写完所有的数据之后,客户端会给NameNode发送信号,请求NameNode关闭文件。文件一旦关闭就不能再修改了。
读流程 -get
- 客户端发起RPC请求到NameNode要求下载指定文件
- NameNode在收到请求之后会查询元数据确定是否有指定的文件,如果没有直接报错,如果有,则给客户端返回一个信号表示允许读取
- 客户端收到信号之后,会再给NameNode发送请求,请求获取这个文件的第一个block的存储位置
- NameNode在收到请求之后,会将第一个Block的存储位置(默认是3个)放到一个队列中返回客户端
- 客户端收到队列之后,会从队列中将block的位置全部取出来,从中选择一个较近(网络拓扑距离)的DataNode来读取第一个Block
- 客户端读取完Block之后,会进行checksum(校验和 - 实际上就是利用.meta文件进行校验)验证,如果校验失败,则客户端会给NameNode发送信号,重新选择节点重新读取;如果校验成功,那么客户端会再向NameNode要下一个Block的地址,重复4,5,6三个步骤
- 当客户端读取完最后一个Block的时候,NameNode就会关闭文件(实际就是关流)
删流程 -rmr
- 客户端发起RPC请求到NameNode要求删除指定的文件
- NameNode收到请求后,先记录edits_inprogress文件,然后修改内存中的元数据,然后NameNode就会给客户端返回一个成功信号,但是这个过程中,注意文件并没有从HDFS上移除而是依然存储在DataNode上
- NameNode等待DataNode的心跳,收到心跳信息之后,NameNode就会校验这个心跳信息(比对元数据和心跳信息中的BlockID是否一致),然后NameNode就会进行心跳响应,要求DataNode删除对应的Block
- DataNode收到心跳响应之后才会删除Block,此时文件才真正的从HDFS上移除