第一章 生态圈概述
1.Hadoop版本区别:
Hadoop1.0:HDFS+MapReduce
Hadoop2.0:HDFS+YARN+(MapReduce+Others)
2.分布式存储系统HDFS(Hadoop Distributed File System):提供高可靠性、高扩展性、高吞吐率的数据存储服务。
3.资源管理系统YARN(YetAnother Resource Negotiator):集群资源的统一管理和调度,是的多个计算架构可以运行在一个集群中。
4.分布式计算框架MapReduce:易编程、高容错性、高扩展性,高吞吐量低性能,处理离线数据。
5.HDFS基本原理:讲文件分成等大的数据块,冗余的存放到多台机器上,将数据切分、容错、负责均衡封装,可将HDFS看成一个容量巨大、高容错性的磁盘。
6.除MR以外的其他计算架构:
7.MapReduce工作流程:
7.Hive:基于MR的数据仓库,解决海量结构化日志数据的统计,定义了一种类SQL查询的语言HQL,通常用于离线数据处理,可以认为HQL->MR的语言翻译器。
8.PIG和HIVE大致原理和功能一样:PIG定义了PigLatin流语言,HIVE是类SQL的HQL。
9.Mahout:基于机器学习和数据挖掘的计算库。
10.Hbase:多维数据库。
11.Zookeeper:解决分布式环境下的数据管理问题:统一命名、状态同步、配置同步、集群管理。
12.Sqoop:连接Hadoop与传统数据库之间的桥梁。
13.Flume:日志手机工具。
14.Oozie:作业流调度系统。
第二章HDFS概述
1.HDFS:
①.易于扩展的分布式文件系统–通过增加机器线性的扩充存储能力。
②.可运行在大量普通廉价机器上,提供容错能力。
2.优点:
①.高容错性:数据自动保存多个副本,副本丢失后自动恢复。
②.适合批处理:移动计算而非数据,数据位置暴露给计算框架。
③.适合大数据处理:GB\TB\甚至PB。
④.流式文件访问:一次性写入不能修改,可重新写入修改后数据。
⑤.可构建在廉价的机器上:通过多副本提高可靠性,提供容错和恢复机制。
3.缺点:
①.不适合低延迟的数据访问(非实时)。
②.不适合小文件存取。
③.不适合并发写入、文件随机修改(只有一个写入操作,不支持追加修改)。
4.HDFS的思想:把数据文件切分成大小等大的BLOCK块,把BLOCK块以多副本的行式存放在多个DATANODE上,在NAMENODE上保存数据文件与BLOCK块的映射和BLOCK块和DATANODE的映射,读取时从多个DATANODE上读取使负载均衡。
5.NAMENODE作用:管理HDFS的名称空间、管理数据块映射信息、处理读写请求。
注:2.0中有两个NAMENODE:Active Namenode 、Standby Namenode其中Active Namenode正常运行,Standby Namenode为其的一个热备,如果故障,则切换到Standby Namenode上正常运行。
6.DATANODE作用:存储实际的数据块,执行数据块的读写。
7.Client作用:切分数据块、与NAMENODE交互,获取文件信息、与DATANODE交互,读取或写入数据。
8.BLOCK:默认数据块大小为64MB(可配置),如不足64MB则单独存成一个BLOCK,默认情况下每个BLOCK有三个副本(可配置)。
9.HDFS写入流程:
HDFS client 通过distributed FileSystem(类)请求NameNode写入操作领取写入的地址,通过FSData OutputStream(类)访问DataNode,将BLOCK块切分成更小的package后写入第一个DataNode,第一个DataNode会把已写入的package传输给第二个DataNode,同时向FSData OutputStream(类)申请第二个切分的package,依此类推写入全部的BLOCK。
10.HDFS读流程:
11.HDFS副本放置策略:第一个副本放置在同client的节点上,第二个副本放置在不同机架的某个节点,第三个副本放置在第二个副本的机架的不同与第二个的节点,其他副本随机。
12.常见的三种错误情况及HDFS容错处理:
①.文件损坏:读取前进行校验,如不成功认定损坏则读取副本。
②.网络或者机器宕机:DataNode定期向NameNode发heartbeat,如长时间未发送heartbeat则NameNode认定其损坏,在其他DataNode上重构损坏节点的数据文件。
③.NameNode宕机:多分存储元信息、主备实时切换。
13.HDFS不适合存储小文件的原因:一个Namenode的内存是有限的,一个BLOCK元信息消耗150B内存,不足64MB的BLOCK也会消耗其内存。
14.与HDFS的交互:shell命令、JAVA API、REST API、FUSE、C/C++、PYTHON、PHP等。
15.2.0的新特性:可多个NameNode管理多个DataNode、一个节点中可存在多种异构的存储介质(异构层级存储结构)、HDFS快照、HDFS权限管理机制ACL。
第三章YARN概述
1.架构:
2.yarn的产生背景:资源利用不平衡,其产生提高其利用率,并可兼容各种计算架构,将多个计算框架集成在一个集群中,并使其数据共享。
3.ResourManager:整个集群只有一个,负责集群资源的统一管理和调度(已基于ZK实现高可用,有多个ResourManager),包含schedule(分配资源)和Applicationmanger(应用的管理与监控)。
4.NodeManager:有多个,负责单节点资源管理和使用。
5.ApplicationMaster:每个应用有一个,负责应用程序的管理。
6.Container:任务的运行环境。
7.运行过程:
(1).client向RM提交应用程序,其中包括启动该应用的ApplicationMaster的必须信息,例如ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
(2).ResourceManager启动一个container用于运行ApplicationMaster。
(3).启动中的ApplicationMaster向ResourceManager注册自己,启动成功后与RM保持心跳。
(4).ApplicationMaster向ResourceManager发送请求,申请相应数目的container。
(5).申请成功的container,由ApplicationMaster进行初始化,container的启动信息初始化后,AM与对应的NodeManager通信,要求NM启动container。
(6).NM启动启动container。
(7).container运行期间,ApplicationMaster对container进行监控。container通过RPC协议向对应的AM汇报自己的进度和状态等信息。
(8).应用运行结束后,ApplicationMaster向ResourceManager注销自己,并允许属于它的container被收回。
8.任务在NM运行失败后通过心跳反馈给RM,RM会将失败的任务告诉AM,AM决定如何处理失败的任务;RM负责重启AM,AM会保存已经运行完成的任务,重启后无需重新运行。
9.YARN的双层调度框架:RM将资源分配给AM,AM将资源进一步分配给各个TASK。
10.YARN的基于资源预留的调度策略:资源不够时会为TASK预留,直到资源充足。
11.YARN的资源调度器:目前支持CPU和内存两种资源,并提供多种资源调度器。
12.Yarn有三种调度方式:
(1).先进先出:优先提交的,优先执行,后面提交的等待。
(2.)容量调度:允许创建多个任务对列,每个队列使用所有资源的一部分。多个任务对列可以同时执行。但是一个队列内部还是先进先出。CDH默认的调度器。
(3).公平调度:第一个程序在启动时可以占用其他对列的资源(100%占用),当其他对列有任务提交时,占用资源的对列需要将资源还给该任务。还资源的时候,效率比较慢。
第四章MapReduce
1.适合PB级以上的海量数据的离线处理,易于编程,有良好的扩展性,有高容错性。
2.不适合:实时计算、流式计算、DAG依赖计算。
3.MapReduce将整个作业运行过程分为两个阶段:Map阶段和Reduce阶段;Map阶段由一定数量的Map Task组成,Reduce阶段由一定数量的Reduce Task组成。
4.Block是HDFS种最小的数据存储单元,Spit是MR种最小的计算单元,默认是与Block一一对应(可调整)。
5.MR运行过程和YARN运行过程相似,MR运行在YARN的基础上。
第五章Hbase
1.HBase是构建在HDFS上的分布式列存储系统,主要用于海量结构化数据的存储。
2.HBase的数据类型都为字符串,对于NULL列不占存储空间,每个单元中的数据可以有多个版本,每行都有一个可排序的主键和任意多的列,同一张表中可以有截然不同的列。
3.以列存储,rowkey、colunm family、colunm 定位一个单元。
4.所有操作均基于Rowkey,支持CRUD(CREATE\READ\UPDATE\DELETE)和SCAN(扫描),单行操作(PUT\GET\SCAN),多行操作(SCAN\MULTIPUT),无内置JION操作。
5.每个colunm family存储在HDFS上的一个单独文件中,KEY和版本号在每个colunm family中均有一份,空值不会被保存(不占用存储空间)。
6.Region是HBase中分布式存储和负责均衡的最小单元,不同region分布在不同的region Servers上。
7.在行的方向上按大小分割成多个Region,每个表开始只有一个,随着数据增多,region不断增大,当达到一个阀值值,region就会分成两个等大的新region。
8.Region是分布式存储的最小单元,但不是存储的最小单元,其由一个或多个store组成,每个store保存一个colunm family,每个store又由一个memstore和0至多个storeFile组成,memstore存储在内存中,storeFile存储在HDFS上,当一个memstore满了后会FLASH一个storeFile存在磁盘上,在FLASH之前如果宕机也会丢失数据,所以数据也会同时先写入HLOG中,其也是HDFS中的文件(由LOG FLUSHER \LOG ROLLER对LOG文件进行切分和删除),当数据FLASH成具体的storeFile后则LOG文件中备份的数据会被删除。
9.HBaes架构:
Zookeeper:保证集群中只有一个Master,存储所有region的寻址入口,监控region server并实时通知Master。
Master:为region server分配region,负责region server的负载均衡,发现失效的region server并重新分配其上的region,管理用户对table的操作。
region server:维护region,处理IO请求,切分region,一个region server可以有多个表的region,一个region只能被一个region server加载。
一个表被分成多个region存储,其rowkey是连续的且不重合的,一个region保存多个列族的数据,每个列族都是单独存储,列族的数据可以保存在不同的storeFile中。
10.HBase依赖Zookeeper,Master和regionserver启动时会向Zookeeper注册,当master挂掉后Zookeeper会重新推举新的Master。
11.对HBase进行操作时,会在regionserver上先写入日志(LOG),成功后再操作数据。
12.启动HBase:service hbase -master/regionserver start
13.先进入hbase shell:hbase shell 可输入help 查看相关关键字使用
14.建表:create ‘表名’,’列族名’
查看表:list 或list
插入数据:put ‘表名’,’row_key’,’列族名:列名’,’value’
查询数据:get ‘表名’,’row_key’
扫描表:scan ‘表名’
删除数据:delete ‘表名’,’row_key’,’列族名:列名’,时间戳
修改表之前需要把表标记为disable状态,修改后需要enable
15.ROOT表保存META表的region位置信息,META表保存用户表的region位置信息,ROOT表的信息保存在zookeeper。
16.META表信息存储为:rowkey为表名+具体的regionID,列为:info:regioninfo 存表名+regionID+STARTKEY+ENDKEY;info:server 存regionserver的域名:端口号;info:serverstartcode 存regionserver的启动时间。
第六章Zookeeper
1.Zookeeper是一个针对大型分布式系统的可靠的协调系统,封装好复杂易出错的关键服务,将简单易用的接口和性能高效稳定的系统提供给用户,是HADOOP生态系统中的基础组件。
2.Zookeeper启动时,会推举一个Leader Server(Paxos协议),Leader负责处理数据更新等操作(Zab协议)。
3.Zookeeper中的角色:
①.领导者(Leader):负责更新系统状态,发起投票(数据是否更新成功,大多数成功则认为成功)。
②.跟随者(Follower):接收客户请求,反馈结果,在选主过程中参与投票。
观察者(ObServer):3.3.0版本新增,接收客户端连接,将请求转发给Leader,不参加投票过程,只同步Leader的状态,目的为了扩展系统,提高读写速度。
③.客户端(Client):请求发起方。
4.Zookeeper写流程:客户端发起请求给S1,S1将请求传给领导者,领导者给各个S节点广播写请求(写入操作,包含领导者节点),各个节点反馈请求结果给领导者,多数成功则成功,领导者发布成功结果给各个S节点,S1节点反馈给客户端。
5.每个节点在Zookeeper中叫做znode,并且其有一个唯一的路径标识,节点znode可以包含数据和子节点(ephemeral类型的节点不能有子节点),znode节点中数据可以有多个版本,比如某个路径下存多个数据版本,查询数据需要带版本号,客户端应用可以在节点上设置监视器(Watcher),某个节点发生变化时客户端可知道并做操作,节点不支持部分读写,必须一次性完整读写(要么成功要么失败)。
6.Znode有两种类型:短暂的(ephemeral)和持久的(persistent),在创建时确定并不可修改;短暂的节点在客户端断开连接后自动删除,持久的节点不会(指定删除)。
7.可将配置信息写入Zookeeper的一个znode上,各个节点监听此节点,一旦其中的数据被修改,Zookeeper将通知各个节点。
8.分布式锁:Zookeeper是强一致性的(同时创建相同的znode,只有一个创建成功)。
第七章数据收集和入库
1.数据收集系统:Flume、Kafka、Scribe
2.传统数据库与Hadoop同步:Sqoop
3.Flume分OG和NG版本,OG是老版本,由agent\collector\master等组件构成;NG比较新,由Agent\Client等组件构成。
4.将agent分布在产生数据的机器上,用作采集数据,将数据传输给collector,collector将agent的数据汇总导入到HDFS上,Master负责配置及通信管理,是集群的控制器。
5.Agent用于采集数据,由source和sink两部分,source用于获取数据(可从文本文件、日志、HTTP等获取);sink将其获取的数据进一步传输给collector。
6.不同的数据源可以使用不同的source及sink,Flume自带了很多:
如:syslogTcp(5140)|agentSink(‘’localhost’’,35853)—监听某个端口
tail(‘’/etc/services’’)|agentSink(‘’localhost’’,35853)—监听某个文件
7.collector汇总多个agent结果,将汇总结果导入后端存储系统,如HDFS、Hbase
如:collectorSource(35853)|collectorSink(“hdfs://namenode/user/flume/”,”syslog”)
8.collector的source和对应的agent的sink的数据格式是对应的,agent和collector的对应关系可以手动指定也可以自动匹配,每个agent可以配置多个collector(主从关系)。
9.Sqoop是连接关系型数据库和Hadoop的桥梁,批处理方式进行数据传输。
10.将数据从关系型数据库导入Hadoop:命令 Sqoop import
①.Sqoop与数据库通信,获取数据库表的元数据信息。
②.Sqoop启动一个MR作业,利用元数据信息并行将数据写入Hadoop。
11.将数据从Hadoop导入关系型数据库中:命令 Sqoop export
①.Sqoop与数据库通信,获取数据库表的元数据信息。
②.并行导入数据,将Hadoop上的文件划分成若干个split,每个split由一个Map Task进行数据导入。
12.sqoop可以与HIVE\HBASE等结合,需要在sqoop-env.sh中增加HBASE_HOME、HIVE_HOME等环境变量。
第八章HIVE与PIG
1.HIVE是构建在Hadoop之上的数据仓库,数据计算使用MR,存储使用HDFS,其定义了一种类SQL语言HQL,通常用于离线处理,可认为是HQL-》MR的语言翻译器。
2.HIVE组成:
①.用户接口:CLI,JDBC\ODBC,WebUI。
②.元数据存储(metastore):默认存储在自带的数据库derby中,使用时一般换成Mysql。
③.驱动器(Driver):解释器、编译器、优化器、执行器
④.Hadoop:用MR计算,用HDFS存储。
3.PIG是Hadoop上的数据流执行引擎,利用HDFS存储数据,MR处理数据,使用Pig Latin语言表达数据流(与HQL)一致。
4.PIG与HIVE都运行在Hadoop之上,解决数据分析问题;HIVE要求待处理数据必须有Schema,而PIG不需;HIVE有server需要安装,PIG不需要安装。
5.作业流调度引擎(Oozie\Azkaban)Hadoop自带的调度引擎:Oozie。
6.HIVE架构:
META STORE:存储元数据信息,即数据存放在HDFS或MYSQL的位置信息。
SQL Parser解析器:校验SQL语法问题。
Physical Plan编译器:将HQL翻译成MR任务。
Query Optimizer优化器:起优化作用。
Execution执行器:提交任务。
7.HQL:
(1).创建内部表:
Create table 表名 (z int, a string, no double)
partitioned by (分区列 类型,分区列 类型) —分区,就在分文件夹,分区字段不为某列,但是创建分区后便成为列(新字段)。
row format delimited fields terminated by ‘,’ --指定分隔符
location ‘/user/hive/warehouse/表名’;–指定HDFS上文件位置
(2).创建外部表:
Create external table 表名 (z int, a string, no double)
row format delimited fields terminated by ‘,’;
区别:删除数据的时候外部表仅删除表结构的元信息,不删除数据文件。
(3).加载本地数据:
Load data local inpath ‘路径’ [overwrite] into table default.表名 partition(分区列=’’,分区列=’’);
HDFS加载数据:
Load data inpath ‘路径’ [overwrite] into table default.表名 partition(分区列=’’,分区列=’’);
(4).针对某分区查询:select * from tab where 分区列=’’;
新增/删除分区:alter table 表名 add/drop partition(分区列=’’) partition(分区列=’’);
查看分区:show partitions tb;
查看分区结构:show formatted tb;
数据也可通过HDFS直接上传数据文件到分区文件夹下。
(5).重命名表:alter table tb rename to newtb;
(6).创建表一般预留字段,后期修改列:alter table tb change colum old new 列类型;(不修改类型也需写)
(7).删除表:drop table tb;
(8).插入数据:
①.insert overwrite table student
partition(month=‘201708’)
select id, name from student where month=‘201709’;
②.建表插入:create table if not exists student3
as select id, name from student;
③.导入数据: import table student2 partition(month=‘201709’)
from ‘/user/hive/warehouse/export/student’;
导出格式化数据到指定目录:insert overwrite local directory —导出到HDFS上无local
‘/opt/module/datas/export/student’
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’
select * from student;
或者
export table default.student to
‘/user/hive/warehouse/export/student’;
(9).删除数据:truncate table student;
(10).LIMIT 子句用于限制返回的行数:elect * from emp limit 5;
(11).排序:
①.Order By:全局排序,结果只有一个 Reduce文件
②.Sort By:每个 Reduce 内部进行排序,对全局结果集来说不是排序。
设置 reduce 个数:set mapreduce.job.reduces=3;
查看设置 reduce 个数:set mapreduce.job.reduces;
结果有3个reduce文件,每个文件内部排序,随机分配数据
③.Distribute By:类似 MR 中 partition进行分区,结合 sort by 使用,写在 SORT BY 语句之前
④.Cluster By:当 distribute by 和 sorts by 字段相同时,可以使用 cluster by 方式。
cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC。
(12).分桶:分区针对的是数据的存储路径;分桶针对的是数据文件,是将数据集分解成更容易管理的若干部分的另一个技术。
create table stu_buck(id int, name string)
clustered by(id) into 4 buckets
row format delimited fields terminated by ‘\t’;
针对分桶表直接LOAD数据是不行的,需要走MR任务,普通表INSERT分桶表。
使用分桶表之前需开启分桶功能:set hive.enforce.bucketing=true;
不需要指定reduce个数:set mapreduce.job.reduces=-1;
查询表结构: desc formatted TB;
多用于抽样查询:
select * from tb tablesample(bucket x out of y on 列);
注:tablesample 是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)
x代表从第几个桶开始抽,桶数/y为抽几个桶的数据
如4个桶,x=1,y=4,表示从第一个桶开始抽,抽4/4=1个桶
x=1,y=8,表示从第一个桶开始抽,抽4/8=1/2个桶(一个桶一半的数据)
(13).时间函数: 不同与Oracle 不加dual
select date_format(‘2019-06-29’,‘yyyy-MM-dd’);—格式化时间
select date_add(‘2019-06-29’,5);—时间加
select datediff(‘2019-06-29’,‘2019-06-24’);–两时间减
(14).列转行:concat(‘hive’,rand()) 拼接hive和随机数
把星座和血型一样的人放在一起,用|隔开。
字段:name ,constellation, blood_type 名字、星座、血型
select t1.base,concat_ws(’|’, collect_set(t1.name)) name
from(select name, concat(constellation, “,”, blood_type) base
from person_info) t1
group byt1.base;
(15).行转列:
select
movie,
category_name
from
tb lateral view explode(列名) table_tmp as
category_name;
其他函数OVER(),rank()与Oracle一致。
(16).根据用户自定义函数类别分为以下三种:
①.UDF(User-Defined-Function)
一进一出
②.UDAF(User-Defined Aggregation Function)
聚集函数,多进一出
类似于:count/max/min
③.UDTF(User-Defined Table-Generating Functions)
一进多出
如 lateral view explore()
(17).配置Hadoop Snappy 压缩在Hadoop目录下lib文件夹,替换目录下所有文件。
Hadoop支持 Snappy 压缩:
查看是否已支持Snappy压缩(hadoop下运行):hadoop checknative
1.开启 Map 输出阶段压缩:
①.开启 hive 中间传输数据压缩功能
hive (default)>set hive.exec.compress.intermediate=true;
②.开启 mapreduce 中 map 输出压缩功能
hive (default)>set mapreduce.map.output.compress=true;
③.设置 mapreduce 中 map 输出数据的压缩方式
hive (default)>set mapreduce.map.output.compress.codec=
org.apache.hadoop.io.compress.SnappyCodec;
④.执行查询语句
hive (default)> select count(ename) name from emp;
2.开启 Reduce 输出阶段压缩:
用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为 true,来开启输出结果压缩功能。
①.开启 hive 最终输出数据压缩功能
hive (default)>set hive.exec.compress.output=true;
②.开启 mapreduce 最终输出数据压缩
hive (default)>set
mapreduce.output.fileoutputformat.compress=true;
③.设置 mapreduce 最终数据输出压缩方式
hive (default)> set
mapreduce.output.fileoutputformat.compress.codec =
org.apache.hadoop.io.compress.SnappyCodec;
④.设置 mapreduce 最终数据输出压缩为块压缩,默认为行压缩
hive (default)> set
mapreduce.output.fileoutputformat.compress.type=BLOCK;
⑤.测试一下输出结果是否是压缩文件
hive (default)> insert overwrite local directory
‘/opt/module/datas/distribute-result’ select * from emp
distribute by deptno sort by empno desc;
(18).Hive 支持的存储数的格式主要有:TEXT 、SEQUENCEFILE、ORC、PARQUET。
TEXTFILE 和 SEQUENCEFILE 的存储格式都是基于行存储的;ORC 和 PARQUET 是基于列式存储的。
①.TextFile 格式 :默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合 Gzip、Bzip2 使用,但使用 Gzip 这种方式,hive 不会对数据进行切分,从而无法对数据进行并行操作。
②.Orc 格式:Orc (Optimized Row Columnar)是 Hive 0.11 版里引入的新的存储格式。
每个 Orc 文件由 1 个或多个 stripe 组成,每个 stripe250MB 大小,Stripe 里有三部分组成,分别是:
1.Index Data:默认是每隔 1W 行做一个索引
2.Row Data:存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个 Stream 来存储。
3.Stripe Footer:存的是各个 Stream 的类型,长度等信息。
Parquet 格式:Parquet 文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此 Parquet 格式文件是自解析的。
在实际的项目开发当中,hive 表的数据存储格式一般选择:orc 或 parquet。压缩方式一般选择 snappy,lzo。
创建一个 SNAPPY 压缩的 ORC 存储方式:
create table log_orc_snappy(
track_time string)
row format delimited fields terminated by ‘\t’
stored as orc tblproperties (“orc.compress”=“SNAPPY”);
(19).优化:
①.Fetch 抓取:Hive 中对某些情况的查询可以不必使用 MapReduce 计算
②.本地模式:Hive 可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。
③.小表、大表 Join:将 key 相对分散,并且数据量小的表放在 join 的左边,这样可以有效减少内存溢出错误发生的几率
新版的 hive 已经对小表 JOIN 大表和大表 JOIN 小表进行了优化。小表放在左边和右边已经没有明显区别。
④.空 key 过滤
⑤.空 key 转换:不能过滤空key ,可以随机赋值,使得数据随机均匀地分不到不同的 reducer 上,解决数据倾斜数据倾斜。
⑥.MapJoin:如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么 Hive 解析器会将 Join 操作转换成 Common Join,即:在 Reduce 阶段完成 join。容易发生数据倾斜。可以用 MapJoin 把小表全部加载到内存在 map 端进行 join,避免在reducer 处理。
⑦.Map 端聚合参数Group By:默认情况下,Map 阶段同一 Key 数据分发给一个 reduce,当一个 key 数据过大时就倾斜了,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
⑧.Count(Distinct) 去重统计:数据量小的时候无所谓,数据量大的情况下,由于 COUNT DISTINCT 操作需要用一个Reduce Task 来完成,这一个 Reduce 需要处理的数据量太大,就会导致整个 Job 很难完成,一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替换。
⑨.开启动态分区:hive.exec.dynamic.partition=true
⑩.分桶及分区优化
第九章 Flink
1.Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算,并且 Flink 提供了数据分布、容错机制以及资源管理等核心功能。Flink提供了诸多高抽象层的API以便用户编写分布式任务:
①.DataSet API:将静态数据抽象成分布式的数据集,对静态数据进行批处理操作。
②.DataStream API:将流式的数据抽象成分布式的数据流对数据流进行流处理操作。
③.Table API:将结构化数据抽象成关系表,并通过类SQL的DSL对关系表进行各种查询操作。
2.Flink两种在yarn上运行的模式:
①.Session-cluster 模式:
Session-Cluster模式需要先启动集群,然后再提交作业,接着会向yarn申请一块空间后,资源永远保持不变。如果资源满了,下一个作业就无法提交,只能等到yarn中的其中一个作业执行完成后,释放了资源,下个作业才会正常提交。所有作业共享Dispatcher和ResourceManager;共享资源;适合规模小执行时间短的作业。
②.Per-Job-Cluster 模式:
一个Job会对应一个集群,每提交一个作业会根据自身的情况,都会单独向yarn申请资源,直到作业执行完成,一个作业的失败与否并不会影响下一个作业的正常提交和运行。独享Dispatcher和ResourceManager,按需接受资源申请;适合规模大长时间运行的作业。
3.Flink运行时架构主要包括四个不同的组件:
①.作业管理器(JobManager):
控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的JobManager所控制执行。JobManager会先接收到要执行的应用程序,这个应用程序会包括:作业图(JobGraph)、逻辑数据流图(logical dataflow graph)和打包了所有的类、库和其它资源的JAR包。JobManager会把JobGraph转换成一个物理层面的数据流图,这个图被叫做“执行图”(ExecutionGraph),包含了所有可以并发执行的任务。JobManager会向资源管理器(ResourceManager)请求执行任务必要的资源,也就是任务管理器(TaskManager)上的插槽(slot)。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的TaskManager上。而在运行过程中,JobManager会负责所有需要中央协调的操作,比如说检查点(checkpoints)的协调。
②.资源管理器(ResourceManager):
主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManger插槽是Flink中定义的处理资源单元。Flink为不同的环境和资源管理工具提供了不同资源管理器。当JobManager申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给JobManager。如果ResourceManager没有足够的插槽来满足JobManager的请求,它还可以向资源提供平台发起会话,以提供启动TaskManager进程的容器。另外,ResourceManager还负责终止空闲的TaskManager,释放计算资源。
③.任务管理器(TaskManager)
Flink中的工作进程。通常在Flink中会有多个TaskManager运行,每一个TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了TaskManager能够执行的任务数量。启动之后,TaskManager会向资源管理器注册它的插槽;收到资源管理器的指令后,TaskManager就会将一个或者多个插槽提供给JobManager调用。JobManager就可以向插槽分配任务(tasks)来执行了。在执行过程中,一个TaskManager可以跟其它运行同一应用程序的TaskManager交换数据。
④.分发器(Dispatcher):
可以跨作业运行,它为应用提交提供了REST接口。当一个应用被提交执行时,分发器就会启动并将应用移交给一个JobManager。由于是REST接口,所以Dispatcher可以作为集群的一个HTTP接入点,这样就能够不受防火墙阻挡。Dispatcher也会启动一个Web UI,用来方便地展示和监控作业执行的信息。Dispatcher在架构中可能并不是必需的,这取决于应用提交运行的方式。
4.任务提交流程图:
Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知满足运行环境的NodeManager启动ApplicationMaster,ApplicationMaster启动后加载Flink的Jar包和配置构建环境,然后启动JobManager,之后ApplicationMaster向ResourceManager申请其他资源来启动TaskManager,ResourceManager分配Container资源后,由ApplicationMaster通知满足启动TaskManager资源的所在节点的NodeManager启动TaskManager,此NodeManager在加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后向JobManager发送心跳包,JobManager生成优化后的执行计划,并以 Task 的单元调度到各个 TaskManager 去执行,TaskManager接收需要部署的 Task部署并启动后,与自己的上游建立连接,接收数据并处理。
5.所有的Flink程序都是由三部分组成的:Source 、Transformation和Sink。
Source负责读取数据源,Transformation利用各种算子进行处理加工,Sink负责输出。
6.Spark和Flink对比:
在spark的世界观中,一切都是由批次组成的,离线数据是一个大批次,而实时数据是由一个一个无限的小批次组成的(微批处理:攒够批次在进行数据处理)。
而在flink的世界观中,一切都是由流组成的,离线数据是有界限的流,实时数据是一个没有界限的流,这就是所谓的有界流和无界流(流处理)。主要考虑的是flink的低延迟、高吞吐量和对流式数据应用场景更好的支持;另外,flink可以很好地处理乱序数据,而且可以保证exactly-once的状态一致性。
7.Flink 的 checkpoint 可存在内存,文件系统,或者 RocksDB。
8.Flink 状态机制:
Flink内置的很多算子,包括源source,数据存储sink都是有状态的。在Flink中,状态始终与特定算子相关联。Flink会以checkpoint的形式对各个任务的状态进行快照,用于保证故障恢复时的状态一致性。Flink通过状态后端来管理状态和checkpoint的存储,状态后端可以有不同的配置选择。
9.常用的算子:
最常用的常用算子包括:Map:DataStream → DataStream,输入一个参数产生一个参数,map的功能是对输入的参数进行转换操作。Filter:过滤掉指定条件的数据。KeyBy:按照指定的key进行分组。Reduce:用来进行结果汇总合并。Window:窗口函数,根据某些特性将每个key的数据进行分组(例如:在5s内到达的数据)。
10.Watermark机制:
Watermark是用于处理乱序事件的,用Watermark机制结合window来实现,可以理解成一个延迟触发机制,我们可以设置Watermark的延时时长t,每次系统会校验已经到达的数据中最大的maxEventTime,然后认定eventTime小于maxEventTime - t的所有数据都已经到达,如果有窗口的停止时间等于maxEventTime – t,那么这个窗口被触发执行
11.exactly-once: 这指的是系统保证在发生故障后得到的计数结果与正确值一致。
12.Flink 三种时间语义:
①.Event Time:是事件创建的时间。
②.Processing Time:是每一个执行基于时间操作的算子的本地系统时间。
③.Ingestion Time:是数据进入Flink的时间。
13. slot与parallelism:
Task Slot是静态的概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置;而并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。
第十章KAFKA
1.Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。
2.发布/订阅模式(一对多,消费者消费数据之后不会清除消息):
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。
3.KAFKA组成:
①.Broker:一台kafka服务器就是一个broker。一个集群由多个broker组成。
②.Topic:数据主题,根据业务系统将不同的数据存放在不同的topic中,一个大的Topic可以分布式存储在多个broker中,Topic可以类比为数据库中的库。
③.Partition:每个topic可以有多个分区,通过分区的设计,topic可以不断进行扩展,即一个Topic的多个分区分布式存储在多个broker,此外通过分区还可以让一个topic被多个consumer进行消费,达到并行处理,分区可以类比为数据库中的表,kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
④.Producer:消息生产者,就是向kafka broker发消息的客户端。生产者负责将记录分配到topic的指定 partition(分区)中
⑤.Consumer:消息消费者,向kafka broker取消息的客户端。每个消费者都要维护自己读取数据的offset。低版本0.9之前将offset保存在Zookeeper中,0.9及之后保存在Kafka的“__consumer_offsets”主题中。
⑥.Consumer Group :每个消费者都会使用一个消费组名称来进行标识。同一个组中的不同的消费者实例,可以分布在多个进程或多个机器上。
4.基础架构:
5.文件存储机制:
6.ISR机制:
Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给follower发送ack。如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障之后,就会从ISR中选举新的leader。