面试之大数据组件工作原理

1、数据加工整体的流向

1.1、业务交互数据 -后端埋点数据
业务流程中产生的登录、订单、用户、商品、支付等数据,通常存储在DB中,MySQL、oracle中

web/app业务交互 - 业务服务器 - mysql业务数据(业务日志数据) - sqoop上传到hdfs

①业务数据上传到mysql数据库中,有些表需要每天进行更新,便于较少数据的增删改查;
②mysql将数据通过sqoop上传到hdfs上,sqoop上传时,运行时间比较长;

1.2、前端埋点用户行为数据
与产品发生交互的数据,用户的曝光,点击,停留,评论等

①埋点数据存储在特定的linux目录中;
②启动flume将数据上传到kafka中的数据,再启动flume消费kafka中的数据;
③通过sink到hdfs的指定目录。

2、hdfs相关

2.1、hdfs的读写
1.hdfs写流程
①block:文件上传需要分块,一般为128M,可以改
	块太小,寻址时间占比过高,块太大,Map任务数太少,作业执行速度变慢
②packet:由client到datanode,是datanode和pipline之间传数据的最小单位,默认64k
③chunk:由client到datanode,是datanode和pipline之间	进行数据校验的基本单位,默认512byte

1)客户端向namenode发出写文件请求
2)检查是否已存在文件、检查权限。若已通过检查,直接先将操作写入EditLog,并返回输出流对象
3)client按照128M划分文件
4)client将namenode返回的分配的可写的DataNode列表Data数据一同发送给最近的第一个namenode节点,此后client端 和namenode分配的多个Datanode构成pipline管道,client端向输出流对象写数据,client每向第一个DataNode写入一个packet,这个packet便会直接在pipeline里传给第二个、第三个…DataNode。
5)每个datanode写完一个块,会返回确认信息
***正确的做法是写完一个block块后, 对packet中的每个chunk校验信息进行汇总
6)写完数据,关闭输出流;
7)发送完成信号给namenode。

***发送完成信号的时机取决于集群是强一致性还是最终一致性,强一致性则需要所有DataNode写完后才向NameNode汇报。最终一致性则其中任意一个DataNode写完后就能单独向NameNode汇报,HDFS一般情况下都是强调强一致性。

2.hdfs读流程

1)client访问NameNode,查询元数据信息,获得这个文件的数据块位置列表,返回输入流对象。
2)就近挑选一台datanode服务器,请求建立输入流 。
3)DataNode向输入流中中写数据,以packet为单位来校验。
4)关闭输入流

3.hdfs的体系结构
主要由四部分组成,分别为HDFS Client,NameNode,DataName和Secondary NameNode

1)client客户端:访问HDFS的程序和HDFS shell命令,通过与 NameNode和DataNode 交互访问HDFS中的文件,
HDFS客户端就是用来访问这个hadoop文件系统的机器,它可以是装有hadoop的机器,也可以是没有装hadoop的机器。

2)Namenode就是HDFS的master架构,管理节点,存储并管理元数据,主要负责HDFS文件系统的管理工作,包括名称空间管理,文件Block管理。
①名称空间管理:文件系统树(filesystem tree)以及文件树中所有的文件和文件夹的元数据(metadata);
②文件Block管理:每个文件中各个块所在的数据节点的位置信息。

3)DataNode
负责存储数据的组件,一个数 据块Block会在多个DataNode中进行冗余备份;一个DataNode对于一个块最多只包含一个备份

4)Secondary NameNode
从NameNode获得fsimage和edits后把两者重新合并发给NameNode,这样,既能减轻NameNode的负担又能安全地备份,一旦HDFS的Master架构失效,就可以借助Secondary NameNode进行数据恢复。

2.2、mapjoin的原理
通常用于一个很小的表和一个大表的连接

①map阶段进行表之间的连接,map阶段直接拿另外一个表的数据和内存中表的数据匹配
②不需要到reduce阶段才进行连接,节省了shuffle阶段时要进行的大量数据传输。

2.3、hadoop的shuffle的原理
2.4、工作中的hadoop的小文件处理,结合项目进行说明
小文件:文件大小要比一个hdfs块大小小很多的文件,一般块=128M
2.4.1、负面影响
①小文件的存在占用大量NameNode内存,从而影响HDFS的横向扩展能力
②MapReduce任务处理小文件,每个Map会处理一个HDFS块,导致程序启动大量mqp来处理这些任务
③HDFS上每个文件都要在NameNode上建立一个索引,这个索引的大小约为150byte,这样当小文件比较多的时候,就会产生很多的索引文件,一方面会大量占用NameNode的内存空间,另一方面就是索引文件过大使得索引速度变慢。
2.4.2、HDFS自带的小文件处理

①文件归档存储

将文件再次进行整理和保存,通过二层索引文件查找,进行最终目录的读取
归档文件不可修改

②使用序列文件存储

由一系列的二进制对组成,key为文件名,value为文件内容
写一个程序将小文件放入单一的序列文件中。

③合并小文件输入

将一个目录作为一个map的输入,而不是一个文件进行输入
从指定目录下的多个文件进行分片,不同文件可以放入不同的poll,一个分片只能包含一个pool中的文件。

--每个map最大输入大小
set mapred.max.split.size = 256000000

--一个节点上split的至少大小
set mapred.min.split.size.per.node = 10000000

--一个交换机split至少的大小
set mapred.min.split.size.per.rack

--执行map前进行小文件的合并
hive.input.format = org.apache。Hadoop.hive.ql.io.CombineHiveInputFormat

2.8、优化
2.8.1、数据输入

① 合并小文件:在执行MR任务前将小文件进行合并,大量的小文件会产生大量的Map任务,增大Map任务装载次数,而任务的装载比较耗时,从而导致MR运行较慢。
② 采用CombineTextImputFormat来作为输入,解决输入端大量小文件场景。

2.8.2、Map阶段

① 减少溢写(Spill)次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO。
② 减少合并(Merge)次数:通过调整io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。
③ 在Map之后,不影响业务逻辑前提下,先进行Combine处理,减少I/O。

2.8.3、Reduce阶段

① q合理设置Map和Reduce数:两个都不能设置太少,也不能设置太多。太少,会导致Task等待,延长处理时间;太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。
(2)设置Map、Reduce共存:调整slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。
(3)规避使用Reduce:因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。
(4)合理设置Reduce端的Buffer:默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有的数据。也就是说,Buffer和Reduce是没有直接关联的,中间多次写磁盘>读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得Buffer中的一部分数据可以直接输送到Reduce,从而减少IO开销:mapreduce.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来,设置Buffer需要内存,读取数据需要内存,Reduce计算也要内存,所以要根据作业的运行情况进行调整。

2.8.4、I/O传输

(1)采用数据压缩的方式,减少网络IO的的时间。安装smappy和LZO压缩编码器。
(2)使用SequenceFile二进制文件。

2.8.5、常用的调优参数

(1)以下参数是在用户自己的MR应用程序中配置就可以生效(mapred-default.xml)

mapreduce.map.memory.mb一个MapTask可使用的资源上限(单位:MB),默认为1024。如果MapTask实际使用的资源量超过该值,则会被强制杀死。
mapreduce.reduce.memory.mb 一个ReduceTask可使用的资源上限(单位:MB),默认为1024。如果ReduceTask实际使用的资源量超过该值,则会被强制杀死。
mapreduce.map.cpu.vcores 每个MapTask可使用的最多cpu core数目,默认值: 1
mapreduce.reduce.cpu.vcores 每个ReduceTask可使用的最多cpu core数目,默认值: 1
mapreduce.reduce.shuffle.parallelcopies 每个Reduce去Map中取数据的并行数。默认值是5
mapreduce.reduce.shuffle.merge.percent Buffer中的数据达到多少比例开始写入磁盘。默认值0.66
mapreduce.reduce.shuffle.input.buffer.percent Buffer大小占Reduce可用内存的比例。默认值0.7
mapreduce.reduce.input.buffer.percent 指定多少比例的内存用来存放Buffer中的数据,默认值是0.0

(2)应该在YARN启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)

yarn.scheduler.minimum-allocation-mb 给应用程序Container分配的最小内存,默认值:1024
yarn.scheduler.maximum-allocation-mb 给应用程序Container分配的最大内存,默认值:8192
yarn.scheduler.minimum-allocation-vcores 每个Container申请的最小CPU核数,默认值:1
yarn.scheduler.maximum-allocation-vcores 每个Container申请的最大CPU核数,默认值:32
yarn.nodemanager.resource.memory-mb 给Containers分配的最大物理内存,默认值:8192

(3)Shuffle性能优化的关键参数,应在YARN启动之前就配置好(mapred-default.xml)
mapreduce.task.io.sort.mb Shuffle的环形缓冲区大小,默认100m
mapreduce.map.sort.spill.percent 环形缓冲区溢出的阈值,默认80%

3、hive相关

3.1、hive的架构

Hive:由Facebook开源用于解决海量结构化日志的数据统计。
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。

1)Hive的数据存储在hdfs上,简单的说hive就是hdfs的简单一种映射,比如:hive的一张表映射hdfs上的一个文件,hive的一个数据库就映射为hdfs上的文件夹

2)Hive是一个计算框架,他是MapReduce的一种封装,实际上他的底层还是MR,Hive就是用人们熟悉的sql对数据进行分析的

3)Hive执行程序是运行在Yarn上的

3.2、hive怎么解析成mr的

① Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
② 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
③ 遍历QueryBlock,翻译为执行操作树OperatorTree
④ 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
⑤ 遍历OperatorTree,翻译为MapReduce任务
⑥ 物理层优化器进行MapReduce任务的变换,生成最终的执行计划

3.3、hive和数据库比较,有哪些区别
3.3.1 查询语言

由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive的特性设计了类SQL的查询语言HQL。熟悉SQL开发的开发者可以很方便的使用Hive进行开发。

3.3.2 数据存储位置

Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的。而数据库则可以将数据保存在块设备或者本地文件系统中。

3.3.3 数据更新

由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET修改数据。

3.3.4 索引

Hive没有索引,在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key建立索引。Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询。

3.3.5 执行

Hive中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的。而数据库通常有自己的执行引擎。

3.3.6 执行延迟

Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce框架。由于MapReduce 本身具有较高的延迟,因此在利用MapReduce 执行Hive查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。

3.3.7 可扩展性

由于Hive是建立在Hadoop之上的,因此Hive的可扩展性是和Hadoop的可扩展性是一致的(世界上最大的Hadoop 集群在 Yahoo!,2009年的规模在4000 台节点左右)。而数据库由于 ACID 语义的严格限制,扩展行非常有限。目前最先进的并行数据库 Oracle 在理论上的扩展能力也只有100台左右。

3.3.8 数据规模

由于Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。

3.4、hive的优化,分区,分桶
3.4.1、分区

我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。

3.4.2、分桶

分桶将整个数据内容安装某列属性值得hash值进行区分

3.5、hive工作中常用的函数

1)窗口函数
① 排序

-- 自然序号排序,不跳数,不重复
ROW_NUMBER() over(partition by name order by c) c1,
-- 排序相同,中间会跳数,总数不变
RANK() over(partition by name order by c) c2,
-- 排序相同,中间不会跳数,总数会减少
DENSE_RANK() over(partition by name order by c) c3

② 切片

-- 将组内数据分成1片
ntile(1) over(partition by name order by orderdate) c1,
-- 将组内数据分成2片
ntile(2) over(partition by name order by orderdate) c2,
-- 将组内数据分成3片
ntile(3) over(partition by name order by orderdate) c3,
-- 将组内数据分成4片
ntile(4) over(partition by name order by orderdate) c4

③ lag和lead

-- 分组内当前行,往后第一行的值(不包括当前行)
lead(cost) over(partition by name order by cost) c1,
-- 分组内当前行,往后第二行的值(不包括当前行)
lead(cost,2) over(partition by name order by cost) c2,
-- 分组内当前行,往后第二行的值(不包括当前行),如果为null,则用9999代替
lead(cost,2,9999) over(partition by name order by cost) c3,
-- 分组内当前行,往前第一行的值(不包括当前行)
lag(cost) over(partition by name order by cost) c4,
-- 分组内当前行,往前第二行的值(不包括当前行)
lag(cost,2) over(partition by name order by cost) c5,
-- 分组内当前行,往前第二行的值(不包括当前行),如果为null,则用-1代替
lag(cost,2,-1) over(partition by name order by cost) c6

④ 聚合函数

count():统计行数
sum(col1):统计指定列和
avg(col1):统计指定列平均值
min(col1):返回指定列最小值
max(col1):返回指定列最大值

⑤条件函数

if(boolean,t1,t2):若布尔值成立,则返回t1,反正返回t2。如if(1>2,100,200)返回200
case when boolean then t1 else t2 end:若布尔值成立,则t1,否则t2,可加多重判断
coalesce(v0,v1,v2):返回参数中的第一个非空值,若所有值均为null,则返回null。如coalesce(null,1,2)返回1
isnull(a):若a为null则返回true,否则返回false

⑥字符串函数

length(string1):返回字符串长度
concat(string1,string2):返回拼接string1及string2后的字符串
concat_ws(sep,string1,string2):返回按指定分隔符拼接的字符串
lower(string1):返回小写字符串,同lcase(string1)。upper()/ucase():返回大写字符串
trim(string1):去字符串左右空格,ltrim(string1):去字符串左空格。rtrim(string1):去字符串右空格
repeat(string1,int1):返回重复string1字符串int1次后的字符串
reverse(string1):返回string1反转后的字符串。如reverse('abc')返回'cba'
rpad(string1,len1,pad1):以pad1字符右填充string1字符串,至len1长度。如rpad('abc',5,'1')返回'abc11'。lpad():左填充
split(string1,pat1):以pat1正则分隔字符串string1,返回数组。如split('a,b,c',',')返回["a","b","c"]
substr(string1,index1,int1):以index位置起截取int1个字符。如substr('abcde',1,2)返回'ab'

⑦时间函数

to_date(string timestamp):返回时间字符串中的日期部分,如to_date('1970-01-01 00:00:00')='1970-01-01'
current_date:返回当前日期
year(date):返回日期date的年,类型为intyear('2019-01-01')=2019
month(date):返回日期date的月,类型为int,month('2019-01-01')=1
day(date):  返回日期date的天,类型为int,day('2019-01-01')=1
weekofyear(date1):返回日期date1位于该年第几周。如weekofyear('2019-03-06')=10
datediff(date1,date2):返回日期date1与date2相差的天数,如datediff('2019-03-06','2019-03-05')=1
date_add(date1,int1):返回日期date1加上int1的日期,如date_add('2019-03-06',1)='2019-03-07'
date_sub(date1,int1):返回日期date1减去int1的日期,如date_sub('2019-03-06',1)='2019-03-05'
months_between(date1,date2):返回date1与date2相差月份,如months_between('2019-03-06','2019-01-01')=2
add_months(date1,int1):返回date1加上int1个月的日期,int1可为负数。如add_months('2019-02-11',-1)='2019-01-11'
last_day(date1):返回date1所在月份最后一天。如last_day('2019-02-01')='2019-02-28'
next_day(date1,day1):返回日期date1的下个星期day1的日期。day1为星期X的英文前两字母如next_day('2019-03-06','MO') 返回'2019-03-11'
trunc(date1,string1):返回日期最开始年份或月份。string1可为年(YYYY/YY/YEAR)或月(MONTH/MON/MM)。如trunc('2019-03-06','MM')='2019-03-01',trunc('2019-03-06','YYYY')='2019-01-01'
unix_timestamp():返回当前时间的unix时间戳,可指定日期格式。如unix_timestamp('2019-03-06','yyyy-mm-dd')=1546704180
from_unixtime():返回unix时间戳的日期,可指定格式。如select from_unixtime(unix_timestamp('2019-03-06','yyyy-mm-dd'),'yyyymmdd')='20190306'

⑧解析url函数
parse_url

⑨自定义函数

Hive使用python编写的自定义函数UDF进行ETL

Ⅰ、使用python脚本实现UDF函数

# -*- coding: utf-8 -*-
import sys
for line in sys.stdin:
    detail = line.strip().split("\n")
    detail_str = line.strip()
    detail_list = detail_str.split("&")
    detail_list = detail_list[4].split("=")
    #print(detail_list)
    data_key = 'spuid'
    for item in detail_list:
        #print(type(item))
        if data_key in item:
            item = item.replace('}','')
            item = item[7:]
            print("\n".join(item)) 

Ⅱ、将python脚本上传到集群
Ⅲ、使用UDF函数

ADD file /data/wcdstat_luna/udf/supid2/supid2.py;

insert overwrite table mtt_search.t_ed_mtt_search_test partition(ds=%YYYYMMDD%)
select   
    transform(targeturl) USING 'python supid2.py' as supid
from mtt_search.t_od_search_page_work_behavior
where ds=20210124
and targeturl like 'qb://wxapp/%' 
and action in ('click','expose')
and guid rlike '^[a-z0-9]{32}$' and guid not rlike '^0{32}$'
and pagename='search_result' --是自建结果页
and platform_lc in ('android','iphone','android-ff','iphone-ff')
and moduletype='module'
and restypeid in ('841','842','843','844','846','847','8410','8420','8430','8440','8460','8470');
and targeturl = 'qb://wxapp/?appid=wx4cbd6b7f04b166ac&source=100004&sceneid=resultPage&c_sceneid=841&ext={entryScene:001,jump_from:2,spuid:102}&path=pages/searchExpress/index&need_backup=1'
3.6、hive导入/导出数据的方式
3.6.1、hive导出数据
EXPORT TABLE tablename [PARTITION (part_column="value"[, ...])]
  TO 'export_target_path' [ FOR replication('eventid') ]
eg:
bin/hive -e "EXPORT TABLE emp    TO '/user/hive/exp/emp';
3.6.2、hive导入数据
IMPORT [[EXTERNAL] TABLE new_or_original_tablename [PARTITION (part_column="value"[, ...])]]
  FROM 'source_path'  [LOCATION 'import_target_path']
  
eg:
IMPORT  TABLE db_hive.emp from '/user/hive/exp/emp/';  
3.8、4个排序的区别
3.8.1、order by

对输出的结果进行全局排序,这就意味着只有一个reduce task时才能实现(多个reducer无法保证全局有序)但是当数据量过大的时候,效率就很低,速度会很慢。可以指定升序asc 降序desc

3.8.2、sort by

局部排序,只保证了每个reduce task中数据按照指定字段和排序方式有序排列。排序列必须出现在select column列表中,reduce task 的数量可以通过 set mapred.reduce.tasks=[num] 来设置,当reducer task数量设置为1时,相当于order by排序

3.8.3、distribute by

照指定的字段进行划分,将数据分到不同的输出reduce task中,通常与sort by一起使用,使用时distribute by必须放在前面。数据通过hash算法分到不同的task中。

-----先分组再排序
分组个数由reduce个数决定分组内有序,但是不能保证分组外有序,可以指定升序还是降序

3.8.4、cluster by

cluster by 可以看做是一个特殊的distribute by+sort by,它具备二者的功能,但是只能实现正序排序的方式,不能指定排序方式

4、flume相关

	Flume 是一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统。
4.1、flume的组件
4.1.1、source

数据源,负责将数据捕获后进行特殊的格式化,然后再封装在Event中,再将数据推入到Channel中

event是最小的数据单元,由header和body组成
4.1.2、channel

连接source和sink的组件,可以理解为数据缓冲区(数据队列),可以将event暂存在内存上,也可以持久化到本地磁盘上,直到sink消费完。

channel 中的数据直到进入到下一个channel中或者进入终端才会被删除。当 sink 写入失败后,可以自动重启,不会造成数据丢失,因此很可靠。

4.1.3、sink

数据下沉。从channel中取出数据后,分发到别的地方,比如HDFS或者HBase等,也可以是其他Agent的source。当日志数据量小的时候,可以将数据存在文件系统中,并设定一定的时间间隔来存储数据。

4.2、flume怎么采集数据的
4.2.1、埋点

①全埋点
前端的一种埋点方式,在产品中嵌入SDK

②代码埋点
1)前端代码埋点
前端埋点类似于全埋点,也需要嵌入SDK,不同的是对于每个事件行为都需要调用SDK代码,传入必要的事件名,属性参数等等,然后发到后台数据服务器

2)后端代码埋点
后端埋点则将事件、属性通过后端模块调用SDK接口方式发送到后台服务器

4.2.2、实时的埋点数据采集

直接触发的日志发送到指定的HTTP端口,写入kafka,然后Flume消费kafka到HDFS

用户访问日志落磁盘,在对应的主机上部署flume agent,采集日志目录下的文件,发送到kafka,然后在云端部署flume消费kafka数据到HDFS

4.3、flume自定义拦截器
对较为敏感的数据进行MD5加密处理。
4.4、flume的数据积压,怎么解决?
4.4.1、数据挤压原因
启动flume之前,积压的数据过多,所以,source读得很快,而sink写hdfs速度有限,会导致反压

反压从下游传递到上游,上游的flume的运行日志中会不断报:channel已满,source重试。

4.4.2、解决方案

a. 如果资源允许,可以增加写入hdfs的agent机器数,通过负载均衡来提高整体吞吐量

b. 如果资源不允许,可以适当增大batchSize,来提高写入hdfs的效率

c. 如果资源不允许,可以配置数据压缩,来降低写入hdfs的数据流量

d. 如果source的数据流量不是恒定大于sink的写出速度,可以提高channel的缓存容量,来削峰

4.5、flume采集数据是否会丢失?
不会,Channel存储可以存储在File中,数据传输自身有事务。
4.6、HDFS sink小文件处理
4.6.1、HDFS存入大量小文件,有什么影响?

元数据层面:每个小文件都有一份元数据,其中包括文件路径,文件名,所有者,所属组,权限,创建时间等,这些信息都保存在Namenode内存中。所以小文件过多,会占用Namenode服务器大量内存,影响Namenode性能和使用寿命
计算层面:默认情况下MR会对每个小文件启用一个Map任务计算,非常影响计算性能。同时也影响磁盘寻址时间。

4.6.2、HDFS小文件处理

官方默认的这三个参数配置写入HDFS后会产生小文件,hdfs.rollInterval、hdfs.rollSize、hdfs.rollCount
基于以上hdfs.rollInterval=3600,hdfs.rollSize=134217728,hdfs.rollCount =0,hdfs.roundValue=10,hdfs.roundUnit= second几个参数综合作用,效果如下:
(1)tmp文件在达到128M时会滚动生成正式文件
(2)tmp文件创建超10秒时会滚动生成正式文件

5、MapReduce相关

5.1、MapReduce原理
5.2、

6、yarn相关

6.1、yarn概述
6.1.1、yarn是集群中的资源管理模块,为各类计算框架提供资源的管理和调度
①用于管理集群资源(服务器硬件,包括CPU,内存,磁盘,网络IO等);
②调度运行在yarn上的各种任务
***总而言之:调度资源,管理任务
6.1.2、核心出发点:分离资源管理和作业监控**
①全局资源管理 - RM
②每个应用程序对应一个应用资源管理 - AM
6.1.3、调度层级
①一级调度管理
	计算资源管理(CPU,内存,磁盘,IO)
②二级调度管理
任务内部的计算模型管理(Appmaster的任务精细化管理)

在这里插入图片描述

6.1.4、整体调度流程

①client向RM提交计算任务
②RM的appilcations manager向nodemanager传递任务
③nodemanager启动第一个container,启动APPmaster
④APPmaster向appmanage注册appmaster编号,同时向scheduler申请资源
⑤scheduler以container形式回复资源列表,比如node2的centainer列表
⑥appmaster让node2分配资源,包括maptask的contenier和reducetask的contenier
⑦同时node执行计算任务,并向appmaster汇报任务情况,appmaster向appmanager汇报任务情况

6.2、相关概念

6.2.1、ResourceManager
①调度器:根据容量、队列等条件,将系统中的资源分配给各个正在运行的应用程序。

②应用程序管理器:监控管理整个系统中所有应用程序,跟踪分给的container的进度、状态。
6.2.2、NodeManager
每个节点上的资源和任务管理器
①定时向ResourceManager汇报节点上的资源使用情况和各个container的运行状态
②接受处理Appmaster的container的启动/停止请求er
6.2.3、Appmaster
用户请教的程序均包含一个Appmaster,负责应用的监控,跟踪应用状态,重启是失败任务。
6.2.4、Container
资源抽象,包含内存,CPU,磁盘,网络等

***当Appmaster向Resource申请资源时,Resourcemanager为Appmaster返回的资源便用container表示。

6.3、调度器的种类

6.3.1、队列调度
任务提交的顺序排成队列,资源分配时,先进先出
***大任务导致占用集群资源,导致其他任务被阻塞

在这里插入图片描述
job进入队列,先进先出,仅能支持第一个job

6.3.2、容量调度器
--apache默认版本
多个组织共享集群,每个组织获得集群一部分计算能力,为每个组织分配专门的队列,然后为每个队列分配一部分集群资源。
在一个队列内部,先进先出

在这里插入图片描述

6.3.3、公平调度器
--CDH默认版本
为所有应用分配公平资源,公平调度可在多个队列工作。

①假设有两个A和B,他们分别拥有一个队列;
②当A启动一个job,而B没有job,A会获得全部集群资源;
③当B启动一个job后,A的job会继续运行,不过一会之后两个任务各自会获得一半的集群资源;
④若B再启动第二个job且其他job还在运行,则它将会和B的第一个job共享B这个队列的资源,
B两个job会各自使用集群的四分之一的资源,而A的job仍然会用集群一半的资源,结果就是资源最终在两个用户之间的平等共享。

6.4、相关参数

在yarn-site.xml文件中进行参数设置

①设置container分配最小内存

②设置container分配最大内存

③设置每个container的最小虚拟内核个数

④设置每个container的最大虚拟内存个数

⑤设置NodeManager可以分配的内存大小

⑥定义每台机器的内存使用大小

⑦定义交换区间可使用的大小

6.5、yarn查看日志
6.5.1、Kill Command 卡住数分钟没有日志输出
提交Hive查询任务,作业状态running,日志提示:Kill Command 卡住数分钟没有日志输出,该如何处理?

在这里插入图片描述

YarnApplicationState字段为当前作业状态,Queue为当前运行集群队列

查看该任务运行状态为waitting,即等待资源运行状态,由于用户使用的队列为root.default,该队列为公用队列,资源吃紧时会出现等待的情况。

解决方案:有申请集群单独队列的应用组,需排查队列是否有批量任务启动,导致资源队列吃紧。核查正常使用导致的资源不足,建议用户申请资源队列扩容,解决问题。

7、sqoop相关

7.1、sqoop是什么?
“Hadoop和关系数据库服务器之间传送数据”的工具。

导入数据:MySQL,Oracle导入数据到Hadoop的HDFS、HIVE、HBASE等数据存储系统;

导出数据:从Hadoop的文件系统中导出数据到关系数据库mysql等。

7.2、导入数据

①导入表到HDFS指定目录

bin/sqoop import \
--connect jdbc:mysql://hdp-node-01:3306/test \
--username root \
--password root \
--target-dir /queryresult \指定目录
--fields-terminated-by ‘\001’ \指定分隔符
--table emp 
--split-by id
--m 1

如果设置了 --m 1,则意味着只会启动一个maptask执行数据导入;
如果不设置 --m 1,则默认为启动4个map task执行数据导入,则需要指定一个列来作为划分map task任务的依据。

②导入关系表到HIVE

bin/sqoop import 
--connect jdbc:mysql://hdp-node-01:3306/test 
--username root 
--password root 
--table emp 
--hive-import  \增加导入hive声明
--split-by id  
--m 1

③增量导入
1)基于递增列的增量数据导入

bin/sqoop import \
--connect jdbc:mysql://hdp-node-01:3306/test \
--username root \
--password root \
--table emp \
--m 1 \
--incremental append \    --基于递增列的增量导入
--check-column id \       --递增列
--last-value 1208         --阈值(将递增列值大于阈值的所有数据增量导入Hadoop)

2)基于时间列的增量数据导入

# 将时间列大于等于阈值的数据增量导入HDFS
 sqoop import \
   --connect jdbc:mysql://192.168.xxx.xxx:3316/testdb \
   --username root \
   --password transwarp \
   --query “select order_id, name from order_table where \$CONDITIONS” \
   --target-dir /user/root/order_all \ 
   --split-by id \
   -m 4  \
   --incremental lastmodified \     --基于时间列的增量导
   --merge-key order_id \           --合并列(主键,合并主键相同的记录)
   --check-column time \            --时间列
   # remember this date !!!
   --last-value “2014-11-09 21:00:00”   --阈值(将时间列大于等于阈值的所有数据增量导入Hadoop)

③并发导入参数
-m 参数能够设置导入数据的 map 任务数量,即指定了 -m 即表示导入方式为并发导入,
这时我们必须同时指定 - -split-by 参数指定根据哪一列来实现m哈希分片,从而将不同分片的数据分发到不同 map 任务上去跑,避免数据倾斜。

重要 tip
1)生产环境中,为了防止主库被Sqoop抽崩,我们一般从备库中抽取数据。
2)一般RDBMS的导出速度控制在60到80m/s,每个 map 任务的处理速度5~10mb/s 估算,即 -m 参数一般设置4到8,表示启动4到8个map任务进行抽取

7.2、导出数据
 1.格式:
bin/sqoop export \
      --connect jdbc:mysql://IP:3306/数据库名 \
      --username MySQL用户名 \
      --password MySQL密码 \
      --table MySQL数据库表名 \
      --export-dir /hive中的文件夹名(数据导出目录) 
2.例子:
   1.cd /root/sqoop
   2.命令:
       bin/sqoop export \
       --connect jdbc:mysql://192.168.25.100:3306/userdb \
       --username root \
       --password admin \
       --table employee \
       --export-dir /emp_data

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随缘清风殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值