Google发表的三篇论文:HFS ,MapReduce,bigtable
和传统的单机操作相比,大数据解决的就是大数据的存储和大数据的计算问题
Hadoop是一个分布式基础架构,具有4高的特点:
高可靠性:副本机制
高扩展性:随时横向增加计算机,扩大集群
高效性:多个数据节点可以同时并行工作,提高效率
高容错性:能够将失败的任务重新分配
Hadoop从广义上来说是只hadoop生态圈,从狭义上来说,就是HDFS,Yarn,MapReduce
【重点:hadoop 1.x V.S Hadoop 2.x 的区别?】
在hadoop 1.x 时代,mapreduce同时负责任务的调度计算和计算所需要的资源(cpu,内存等)的调度,任务较重。而在hadoop2.x 之后引入了yarn,至此mapreduce只负责计算,yarn负责资源的调度。(yarn非常重要,后面由于发展的需要,衍生了不同的分布式集群,当不同的集群都基于HDFS,想用HDFS的数据来查看,计算,都要yarn进行调度。怎么理解呢,HDFS负责存储数据资源。我们把HDFS集群中的计算机比喻成一个一个的工人,每个工作组都有任务要让这些工人做,各个工作组的负责人并不知道这些工人目前是什么状态,手上有多少工作,是不是闲着,有没有能力完成这些工作,这个时候就需要一个总的指挥者yarn,他知道这些所有人的状态,所以各个工作组需要向yarn申请工人,yarn就根据各个工作组的任务量大小,合理分配工人给他们)
HDFS
HDFS(Hadoop Distribution File System)hadoop分布式文件系统,通过目录树定位文件。
一、HDF设计原则
1、解决单机无法存储非常大的文件:几百G,TB,PB级别的文件,一台电脑装不来,就多找几台电脑来张,甚至成百上千台电脑。
2、适合一次写入多次访问的情况:HDFS基于这样的假设,有效数据一次录入,工作中多次从数据源读取数据,进行查找分析。
3、 运用于商业硬件上:hadoop集群不需要特别贵,特别可靠的机器,普通商用机器即可(也可从不同厂家购置)。
二、HDFS核心概念
1、 Blocks
物理磁盘的最小单元是‘块’,读写操作均以块为单位,一般是512Byte。分布式文件系统在物理磁盘‘块’的基础之上抽象出block概念,以HDFS为基础的集群,读写操作都是在block级别上进行操作。
HDFS的block一般为128M(也可根据业务更改)。HDFS分布式文件系统中的文件均以‘block’为独立单元存储在不同的机器上。但是比block小的文件不会占用整个block,只会占据实际大小。例如一个300M的文件上传至HDFS系统,被拆成3个block,分别是128M+128M+44M,最后一个block只占用实际44M空间,而不是128M。
block的拆分,使得实际文件可以大于整个磁盘的容量,这样实际文件可以拆分出来,存储在不同的机器磁盘上。Hadoop的高容错也是以block为单元进行复制的。
【面试重点】block文件大小如何定?
思考:为什么block不能定太大或或者太小
答:如果太小,会增加寻址时间,程序一直在找块的开始位置
如果太大,从磁盘传输数据的时间会大于定位这个block开始位置所需要的时间,导致程序处理这个block数据会非常慢。
总结:HDFS快的大小设置取决于磁盘传输速率。
2、 NameNode和DataNode
NameNode和DataNode构成了HDFS集群的一主(master)多从(slave)模式。NameNode负责管理原数据,DataNode负责存储,读写工作
Namenode:集群中active的NameNode只有一个,部署在单独一台计算机。保存元数据和操作日志,元数据就是指文件名,文件长度,文件所属用户组,文件存储位置等。在HDFS中,在HA(High Availability高可用性)中,如果namenode出现单点故障,会启动另一个热备(hot standby)作为新的acitive NameNode。
Datanode:集群多台计算机,这些计算机提供硬盘空间用于存储数据(一般不要提供系统盘)。Datanode负责读写操作,这些操作请求可能来自于namenode,也可能来自于client
3、SecondaryNameNode
SecondaryNameNode:一般部署在一台配置和NameNode相当的计算机上,因为SecondaryNameNode:每隔一段时间需要将edit logs和fsimage读到自己的内存中,将新生成的edit日志信息合并到fsimage中,所有内存至少要和NameNode一样。
三、HDFS读写流程
- 写流程
目标:client要将一个200M的文件ss.avi写入HDFS,流程如下:
- 客户端通过distributed filesystem 模块想namenode请求上传文件
- Namenode检查目标文件是否存在,父目录是否存在,并向客户端返回相应:可以上传文件
- 客户端将文件按照128M的标准拆分文件,再次向namenode发送请求,上传第一个block,询问上传至哪几个datanode的服务器
- Namenode返回3个datanode节点,假设取名为dn1,dn2,dn3
- 客户端得到节点信息后,通过FSDataOutputStream模块向其中最近的服务器dn1(这里的近指通过交换机最少的那个)请求上传数据,dn1收到请求后会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成
- dn1,dn2,dn3逐级应应答客户端
- 客户端开始往dn1上传第一个block(先从磁盘读取数据放到本地缓存),以packet为单位,dn1收到第一个packet会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答
- 当第一个block上传完成后,客户端再次向namenode请求上传第二个block,重复执行2-7步骤。
【补充副本节点选择】
(1)第一个副本放在客户端相同的机器上,如果机器在集群之外,随机选择一个(但是会尽可能选择容量不是太慢或者当前操作太繁忙的)
(2)第二个副本随机放在不同于第一个副本的机架上。
(3)第三个副本放在跟第二个副本同一机架上,但是不同的节点上,满足条件的节点中随机选择。
- 读流程
- 客户端通过Distributed FileSystem模块向NameNode请求下载文件
- Namenode通过查询元数据,检查权限等系列操作,返回文件所在datanode的地址(所有block和副本地址)
- 根据就近原则,从中随机挑选一台datanode的服务器,请求读取数据
- Datanode接收请求,为客户端传输数据(从磁盘读取数据输入流,以packet为单位校验),
- 客户端以packet为单位接收,现在本地缓存,然后写入目标文件。
Yarn
专注分布式框架中运算资源的分配和调度,主从结构,一主(ResourceManager),多从(NodeManager)
如何理解yarn,上图
这个一个本地的资源管理器界面,每个程序都有使用的cpu,内存,磁盘等,yarn的工作就是为客户端提交的各个应用程度调度资源,让程序顺利实现。
或者将大数据集群理解为一个大的资源池,每个运算程序都需要资源,yarn负责从资源池中取一部分资源执行任务,任务结束后这个资源还要释放回到那个大的资源池。举例:一台机器64核,64G内存,10台这样的机器组成一个集群,那么10x64=640核,10x64=640G就组成了这个集群的资源池。假设某个运算程序需要10核,8G内存的资源,运算持续5min,yarn就从大的资源池中拿出10核+8G资源占用5min。
一、yarn核心组件
ResourceManager、NodeManager、Applicationmaster、Container
二、Yarn运行机制
- 在客户端写下程序,例如main:() job.submit(): yarnrunner…,客户端向ResourceManager申请一个应用程序的id
- ResourceManager接收到请求后,向客户端返回资源提交的路径HDFS:// …/staging和一个application id
- 客户端就会将该程序执行所需要的临时文件提交到该路径下的文件夹中HDFS:// …/staging/application_id,这个application文件夹中可能包含这些临时文件job.split, job.xml, wc,jar,这些临时文件都是在job.submit提价后生成的。
- 临时文件提交后,客户端会告诉ResourceManager,临时文件已经提价完毕,申请运行mrAppMaster负责跟进任务
- ResourceManager将用户请求初始化成一个task(所有的资源申请到ResourceManager都会生成一个task)。task生成以后,resoucemanager将task放到FIFO调度列队中(可能ResourceManager会同时受到多个用户程序,resoucemanager有自己的调度规则,哪个task先执行,哪task后执行),轮到该task执行时,它就找一个NodeManager接收该任务
- NodeManager启动一个container执行这个appMaster,appMaster就是以任务为己任,把那些临时文件下到本地,根据job.split的切片信息,向resoucemanager申请相应数量的map task,这个申请进入resoucemanager后进入调度,等待分配。(为什么要有这一步,而不是ResourceManager根据程序直接分配几个map task,几个NodeManager直接开始执行任务,这是因为resoucemanager不管跑的是什么任务,用的什么数据,数据从哪里来,它只负责分配调度资源。
- 轮到该资源申请(appMaster向resoucemanager申请的资源)的时候,resoucemanager会处理这个申请,启动NodeManager,NodeManager会启动相应数量的container执行task(这里注意,NodeManager的数量和task不是一一对等的,container才是,就是resourcemananger可能会让nodeM1执行两个task,让nodeM1执行一个task,只要还是根据节点的状态,资源是否够用,是否空闲)
- 假设该任务切成了两片,启动了两个container执行map task,appMaster会把自己下载的jar包和启动脚本发给这两个container,执行结束,得到输出文件,container回收。在container执行的过程中, resoucemanager和NodeManager是不管任务执行情况,appMaster会不断询问任务的执行情况。
- 当appMaster接收到map task任务执行结束的消息后,appMaster会根据程序写reduce数量,想RM请求对应数量的task 容器,重复上述队列等待,RM处理分配,NM 启动相应数量的container,进行reduce Task。处理结束后结果写回HDFS。AppMaster得到任务执行结束的信息,想RM申请注销自己
HIVE:
Hive是基于hadoop的数据仓库工具,将底层HDFS的结构化数据映射为一张表,通过类sql语句进行查找分析。就是说Hive的数据存储在HDFS上,Hive的表只保存元数据(包括表的拥有者,列/分区字段,表的类型,表的数据所在目录),其本质是将sql语句转化为mapreduce程序。
一、Hive架构
二、Hive中的核心概念
1、 client客户端
CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)
2、元数据
元数据包括:①表名、②表所属的数据库(默认是default)、③表的拥有者、④列/分区字段、⑤表的类型(是否是外部表)、⑥表的数据所在目录等;
默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore
3、驱动器Driver
(1) 解析器:将SQL字符串转换成抽象语法树AST;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
(2) 编译器:将AST编译生成逻辑执行计划
(3) 优化器:我们写的sql语句顺序不一定是最优化的,到这里优化器会调整顺序优化逻辑执行计划
(4) 执行器:将逻辑执行计划转化为物理执行计划(即mapreduce)
四、Hive运行机制
1、 Hive给用户提供了系列交互接口,接收用户的类sql指令。
2、 Hive使用driver将用户的类sql指令解析转化为mapreduce计划,提交到hadoop中执行,再将结果返回交互窗口。
五、Hive中的表
1、 管理表:hive中的表有内部表(管理表)和外部表,默认创建的是内部表,表的数据存储在会存储在由配置项hive.metastore.warehouse.dir所定义的目录子目录下(例如:/usr/local/hive/warehouse)。如果删除一个内部表,hive也会删除这个表中数据
2、 外部表:hive认为它并不完全拥有这份数据,因此删除表的时候并不会删除掉这份数据,不会表述表的元数据信息会被删除掉。
3、 内,外部表使用场景
每天收集的网站日志信息定期存入HDFS分布式文件系统,使用外部表做大量的统计分析,中间的重要结果或者最后的结果使用内部表存储(补充:使用select insert 语句将结果存入内部表)
4、 分区表:对应的是HDFS文件系统中的独立文件夹,该文件夹下是该分区中的所有数据文件,hive中存的就是分区目录,这样查询是通过where可以指定分区,提高查询系效率。
5、 分桶表:对于每一个表或者是分区,Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive是针对某一列进行分桶,比如针对事件列,可以再次分桶为2019年6月,2019年7月等不同的桶。
HBase
概念:收到bigtable思想启发而生,支持非结构化数据存储
HBase是基于HDFS分布式文件系统而构建的,其数据也是存储在HDFS上,那这两者有什么区别呢?HDFS是文件系统,HBase是数据库,可以把HBase当做Mysql,HDFS当做磁盘来理解。
HBase叫分布式存储数据库,听起来也是分布式,也是存储数据,我们已经有了HDFS,为什么还有HBase?HDFS是分布式文件系统,主要存储文件,不管文件里面的数据,也就是说文件中的数据可能是杂乱无章的额,这样实际处理业务就不太方便。那mysql可以存储数据,为什么还有HBase。
比如我们有一张mysql表
我们都知道mysql是以行存储数据,也就是说第一行数据(1,zhangsan,20,xxx)是存储在磁盘的一个区域中,我们查找数据的时候一定是把这一整行数据全都查出来,如果我的表不止name,age,email,后面还有几百个字段,那我查这一行数据会非常慢。有人可能会说,我用select age from table,只去age不就行了,实际是你只是让系统显示了age,但实际查数据还是所有数据都查出来了。这样导致查询效率低下。从统计分析角度,mysql也不合适,比如我要统计表中这些人的年龄平均值,由于每一行数据都存在一个地方,我要统计年龄的平均值,就要去每个地方找到年龄,再进行计算,所以效率很低。面向列存储就是把zhangsan,lisi,wangwu,zhooliu存在一个地方,把20,30,40,20存在一个地方,这样只要把年龄这个地址拿到,计算统计即可。
一、HBase核心概念
1.列式存储:每个列单独拿出来,然后关联id,以key-value形式存在
2.HBase数据表
在HBase表中,定位一行数据有一个唯一的值,行键—RowKey
HBase的列(column)都归属不同的列族(column family),在HBase中用列修饰(column qualifier)标识不同列,就是先有族,后有列。可以把列族理解为列的属性类别。上一张图,清晰明了。
把案例具体到这张表就是
这张表有两个列族Userinfo和Orderinfo, 在UserInfo下有两个列,分别是UserInfo:name和UserInfo:age,在OrderInfo下有两个列,分别是OrderInfo:orderId和OrderInfo:money。
UserInfo:name的值为:三歪。UserInfo:age的值为24。OrderInfo:orderId的值为23333。OrderInfo:money的值为30。这些数据的主键(RowKey)为1
HBase每一行的列都很灵活,行与行之间的列不需要相同。这样一个列族下可以随时增加列,不受限制。
数据写到HBase的时候都会被记录一个时间戳,这个时间戳被我们当做一个版本。比如说,我们修改或者删除某一条的时候,本质上是往里边新增一条数据,记录的版本加一了而已。
比如现在我们有一条记录:
现在要把这条记录的值改为40,实际上就是多添加一条记录,在读的时候按照时间戳读最新的记录。在外界「看起来」就是把这条记录改了。
二、HBase架构
HBase有HDFS,client,zookeeper等组成。
HBase依赖HDFS,zookeeper第三方框架,所以在使用HBase前要先把这两个框架启动。
启动HBase,要启动两大进程,分别是Hmaster和HRegionServer
Hamster负责DDL相关的操作,就是创建数据库,数据表的工作,hregionserver负责DML的工作,就是增删改查。
三、HBase运行机制
- 读数据
- 找zookeeper(zookeeper中有个节点里面存储了HBase表的元数据信息),获取meta表所在服务器的节点
- Zookeeper将存meta的服务器地址(比如是RS1)信息返回给client
- Client根据得到的信息向那个服务器RS1请求查询数据(比如是1001)1001数据的所在节点
- 服务器RS1返回1001数据所在节点信息,1001在服务器RS4上
- 客户端想服务器RS4发送请求查询1001数据
- RS4返回查询结果。RS4先从内存(mem store)中找数据,如果没有再到磁盘上找数据(如果是从磁盘找到的数据,也是先写入缓冲区,再返给客户端)
- 总结:HBase读取数据要经过很多步骤,所以查询数据效率不高,有延迟
- 写数据
HBase分布式的,所以有多台服务器(hregionserver),每个服务器上也有多个region,每个region中的一个store就是一个列族数据,写数据就是写入store中。现在客户端要写数据,并不能直接写入,因为客户端不知道应该写入哪台服务器的哪个region中,所以还要接祖zookeeper中的meta。根据meta能确定放到哪台服务器上,然后根数据的key值就能确定放到服务器的哪个region中(因为Hregionserver中的不同region就是不同分区)。Rowkey决定了放哪个分区(region),当然放到哪个store也是知道的,根据列族。
Store里面的数据放在哪里了呢?
我们知道HBase也是基于HDFS的。store中有个Hfile,就是hadoop的抽象,Hfile其实就是指向底层的HDFS(所以数据存到hfile中一定涉及IO,还涉及网络传输),这样会非常慢,所以实际HBase不是这样做的。所以store中还有一个mem store,也就是说缓冲。但是为了避免缓冲区的数据还没来得及读入HFile,出现问题导致数据丢失,这里还有一个步骤,预写日志(write head log)。所以client会同时写一份日志HLog和men store缓存(日志也是保存在HDFS中)。如果mem store出现问题,就用Hlog恢复。
Spark
Spark core
Spark sql
Spark ml
出现spark的原因,
- mapreduce计算太慢:mapreduce过程太多次IO交换,因此效率很低。
- 表达形式单一:并不是所有程序都能转化为map和reduce阶段,而且map阶段任务未结束之前,reduce阶段任务不能开始,难以胜任负责的多阶段的计算任务。
Spark特点::
- 基于内存计算,速度快
- 支持多种语言,r,scala,python,java
- 丰富的库,提供了强大的技术栈,包括sql查询,ml机器算法,还有图像算法等组件。
Spark Core:实现了Spark的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。
Spark SQL:是Spark用来操作结构化数据的程序包。通过Spark SQL,我们可以使用 SQL来查询数据。Spark SQL支持多种数据源,比如Hive表、Parquet以及JSON等。
Spark Streaming:是Spark提供的对实时数据进行流式计算的组件。提供了用来操作数据流的API,并且与Spark Core中的 RDD API高度对应。
Spark MLlib:提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据 导入等额外的支持功能。
Spark可以独立运行,自带一个独立调度器,当然也支持在各种集群管理器(Cluster Manager)上运行,包括Hadoop YARN、Apache Mesos 。
一、Spark核心组件
Driver(驱动器)
Spark中的driver是执行客户端程序中的main方法的一个进程,负责执行以下操作:创建sparkContext 、创建RDD、rdd的transform和actor操作。比如你启动spark shell,实际上后台就自动启动了一个spark驱动程序,预加载了一个sparkcontext对象,如果程序终止,spark应用也就结束。他主要负责
1)把用户程序转为作业(JOB)
2)跟踪Executor的运行状况
3)为执行器节点调度任务
4)UI展示应用运行状况
Executor(执行器)
执行器也是一个进程,负责在spark中运行任务。Spark应用启动时,执行器节点同时别启动,主要负责:
1)负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;
2)通过自身的块管理器(Block Manager)为用户程序中要求缓存的RDD提供内存式存储。RDD是直接缓存在Executor进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
二、Yarn模式下的spark运行机制
Spark客户端直接连接Yarn,不需要额外构建Spark集群。有yarn-client和yarn-cluster两种模式,主要区别在于:Driver程序的运行节点。
yarn-client:Driver程序运行在客户端,适用于交互、调试,希望立即看到app的输出
yarn-cluster:Driver程序运行在由RM(ResourceManager)启动的AP(APPMaster)中,适用于生产环境。
和hadoop的yarn相比,流程类似,只是把container中的mapreduce计算框架换成yarn的计算框架。
- spark client向yarn集群中的resourcemananger提交计算申请(例如:bin/spark-submit -master yarn /user/examples/spark-example_2.11-2.1.1.jar…)
- rm选择一个NodeManager启动一个Application Master,application master解析任务,看看客户端的任务需要多少资源,然后向RM申请资源
- application向rm申请资源
- rm返回资源列表
- application master根据规则,选择执行任务的服务器nm1
- AM向nm1发送任务请求,要求nm1创建执行器对象—executor
- Nm1的执行器对象创建好以后,向am做一个’反向注册’,告诉am,executor已经创建好,可以发送任务了。
- AM将任务分解好,发给各个executor。