【Python大数据笔记_day10_Hive调优及Hadoop进阶】

hive调优

hive官方配置url: Configuration Properties - Apache Hive - Apache Software Foundation

hive命令和参数配置

hive参数配置的意义: 开发Hive应用/调优时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问题。然而实践中经常遇到的一个问题是,为什么我设定的参数没有起作用?这是对hive参数配置几种方式不了解导致的!
​
hive参数设置范围 : 配置文件参数 >   命令行参数  >   set参数声明
​
hive参数设置优先级: set参数声明  >   命令行参数   >  配置文件参数
​
注意: 一般执行SQL需要指定的参数, 都是通过 set参数声明 方式进行配置,因为它属于当前会话的临时设置,断开后就失效了

1.hive数据压缩

==Hive底层是运行MapReduce,所以Hive支持什么压缩格式本质上取决于MapReduce。==

压缩对比

在后续可能会使用GZ(GZIP), 保证压缩后的数据更小, 同时压缩和解压的速度比较OK的,

但是大部分的选择主要会选择另一种压缩方案, snappy, 此种方案可以保证在合理的压缩比下, 拥有更高的解压缩的速度

snappy | A fast compressor/decompressor On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

开启压缩

开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量. 当Hive将输出写入到表中时,输出内容同样可以进行压缩。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

-- 创建数据库
create database hive05;
-- 使用库
use hive05;
​
​
-- 开启压缩(map阶段或者reduce阶段)
--开启hive支持中间结果的压缩方案
set hive.exec.compress.intermediate; -- 查看默认
set hive.exec.compress.intermediate=true ;
--开启hive支持最终结果压缩
set hive.exec.compress.output; -- 查看默认
set hive.exec.compress.output=true;
​
--开启MR的map端压缩操作
set mapreduce.map.output.compress; -- 查看默认
set mapreduce.map.output.compress=true;
--设置mapper端压缩的方案
set mapreduce.map.output.compress.codec; -- 查看默认
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;
​
-- 开启MR的reduce端的压缩方案
set mapreduce.output.fileoutputformat.compress; -- 查看默认
set mapreduce.output.fileoutputformat.compress=true;
-- 设置reduce端压缩的方案
set mapreduce.output.fileoutputformat.compress.codec; -- 查看默认
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--设置reduce的压缩类型
set mapreduce.output.fileoutputformat.compress.type; -- 查看默认
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

2.hive数据存储[练习]

行列存储原理

行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。
​
行存储: textfile和squencefile优点: 每行数据连续存储              select * from 表名; 查询速度相对较快缺点: 每列类型不一致,空间利用率不高   select 列名 from 表名; 查询速度相对较慢
列存储: orc和parquet优点: 每列数据连续存储         select 列名 from 表名;  查询速度相对较快缺点: 因为每行数据不是连续存储  select * from 表名;查询速度相对较慢注意: ORC文件格式的数据, 默认内置一种压缩算法:zlib , 在实际生产中一般会将ORC压缩算法替换为 snappy使用,格式为: STORED AS orc tblproperties ("orc.compress"="SNAPPY") 

存储压缩比

-- 存储格式应用对比
-- 演示textfile行存储格式: 18.1 m
create table log_text (track_time string,url string,session_id string,referer string,ip string,end_user_id string,city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE ; -- TEXTFILE当前默认的,可以省略
​
-- 查询数据
select * from log_text;
​
​
​
-- 演示orc列存储(默认zlib): 2.78 m
create table log_orc(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc ;-- 默认内置一种压缩算法:ZLIB
​
-- 加载数据(先上传数据文件到根目录)
insert into table log_orc select * from log_text;
-- 查询数据
select * from log_orc;
​
​
-- [重点orc配合snappy]
-- 演示orc列存储(指定snappy): 3.75 m
create table log_orc_snappy(track_time string,url string,session_id string,referer string,ip string,end_user_id string,city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties ("orc.compress"="SNAPPY"); -- 配合SNAPPY压缩
​
-- 加载数据(先上传数据文件到根目录)
insert into table log_orc_snappy select * from log_text;
-- 查询数据
select * from log_orc_snappy;
​
/*ORC文件格式的数据, 默认内置一种压缩算法:ZLIB , 在实际生产中一般会将ORC压缩算法替换为 snappy
格式为: STORED AS orc tblproperties ("orc.compress"="SNAPPY") */
​
​
​
​
-- 演示parquet压缩存储:13.09 m
create table log_parquet(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS PARQUET ;
​
-- 加载数据(先上传数据文件到根目录)
insert into table log_parquet select * from log_text;
-- 查询数据
select * from log_parquet;

拓展dfs -du -h

-- 查看hdfs文件大小除了去页面查看,还可以通过命令
dfs -du -h '/user/hive/warehouse/hive05.db/log_text/log.data' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc_snappy/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_parquet/000000_0' ;

3. fetch抓取

==核心点: 在执行SQL, 能不走MR, 尽量不走MR==

回想, 在之前执行什么样查询的SQL的时候,没有走MR呢?

1) 全表扫描
2) 查询某个列数据
3) 执行一些简答查询操作
4) 执行limit操作

而这些操作, 没有走MR原因, 就是hive默认以及开启本地抓取的策略方案:

hive.fetch.task.conversion:   设置本地抓取策略可选:more (默认值): 可以保证在执行全表扫描, 查询某几个列, 进度limit操作,还有简单条件查询4种情况都不会走MRminimal :  保证执行全表扫描以,查询某几个列,简单limit操作,3种情况可以不走MRnone : 全部的查询的SQL 都执行MR

示例:

-- 默认是more,底层自动调优
set hive.fetch.task.conversion; -- 默认结果是more
set hive.fetch.task.conversion = more;
select * from log_text; -- 不走mr
select url from log_text;-- 不走mr
select url from log_text limit 3;-- 不走mr
select url from log_text where city_id = -1;-- 不走mr
​
-- 可以体验下minimal模式
set hive.fetch.task.conversion = minimal;
select * from log_text;-- 不走mr
select url from log_text;-- 不走mr
select url from log_text limit 3;-- 不走mr
select url from log_text where city_id = -1;-- 走mr
​
-- 还可以体验下none模式
set hive.fetch.task.conversion = none;
select * from log_text;-- 走mr
select url from log_text;-- 走mr
select url from log_text limit 3;-- 走mr
select url from log_text where city_id = -1;-- 走mr

4. 本地模式

==核心点:让MR能走本地模式, 尽量走本地MR(大白话: 小活能自己干就不要麻烦别人)==

如何开启:set hive.exec.mode.local.auto=true;  默认值为: false
​
开启本地模式后, 在什么情况下执行本地MR:   只有当输入的数据满足以下两个特性后, 才会执行本地MRset hive.exec.mode.local.auto.inputbytes.max=51234560;   默认为 128M 设置本地MR最大处理的数据量set hive.exec.mode.local.auto.input.files.max=10; 默认值为4设置本地MR最大处理的文件的数量

示例:

-- 4.开启本地mr(默认false,如果小数据任务进行调优开启,小任务能自己干就自己干)
set hive.exec.mode.local.auto;  -- 默认关闭
set hive.exec.mode.local.auto=false; -- 手动关闭
set hive.exec.mode.local.auto=true; -- 手动开启
​
--设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max;-- 查看
set hive.exec.mode.local.auto.inputbytes.max=134217728;
​
--设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max;-- 查看
set hive.exec.mode.local.auto.input.files.max=4;
​
-- 执行sql语句
-- 没有开启本地执行24秒,开启后1.5秒
select * from log_text order by city_id desc;
​
-- 注意: 有的同学开启本地模式后执行上述sql语句,会报code 2...错误
-- 错误:[08S01][2] Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
-- 如何解决? /export/server/hive/hive-env.sh  修改 export HADOOP_HEAPSIZE=2048
-- 注意: 修改完后需要重启hive服务

5. join的优化操作

思考: 在通过hive执行多表查询的SQL, 最终hive翻译的MR,是如何完成join的工作的呢?

默认的join行为, 基于reduce端的join工作

思考, 请问上述join存在哪些问题?

1) 导致reduce的压力剧增, 所有的数据全部都打向reduce中
2) 当有了多个reduce后, 如果某个join字段的值出现大量的重复, 会导致大量key发往同一个reduce, 从而导致数据倾斜

==那么如何解决reduce端join遇到问题? 可以通过底层map 端 join实现,还可以sql语句join之前提前过滤数据或者转换数据实现==

通过 map join 即可解决掉 reduce join所出现的所有的问题, 也可以这么 mapjoin有解决数据倾斜的作用
​
存在什么弊端: 小表数据需要存储在内存中, 随着mapTask越多, 存储在内存的小表数据份数也会越多当这个小表数据比较大的, 可能无法放置到内存中
​
所以说, mapJoin有一定使用范围: 仅适用于小表 和大表 进行join的情况
  • 1) 大表和小表进行join:

    • 解决方案: map join

    • 如何开启这种操作呢?

      set hive.auto.convert.join = true; -- 默认为true  开启mapJoin支持 
      set hive.mapjoin.smalltable.filesize= 25000000;  设置 小表的最大的数据量  23.84m
    • 在执行SQL, 应该将小表放置前面呢, 还是大表放置在前面呢,还是都可以呢 ?

      (hive1) :  要求 必须将小表在前大表在后 ,只有这样才可能走Map Join
      (hive2):  无所谓, 谁在前, 谁在后, 没有任何的影响, hive会自动判断
  • 3) 大表和大表join

    • 解决方案:

      1) 能在join之前过滤操作, 一定要在join前过滤, 以减少join的数据量, 从而提升效率
      2) 如果join字段上, 有很多的空值null值,获取其他无效数据, 这些值越多 就会导致出现数据倾斜方案一: 提前过滤掉select * from (select * from 表1 where 字段名 is not null) 别名1 join (select * from 表2 where             字段名 is not null) 别名2 on 关联条件;方案二: 将null值替换为随机数, 从而减少数据倾斜影响select * from (select case when 字段名 is null then rand() else 字段名 end  from 表1) 别名1 join             (select case when 字段名 is null then rand() else 字段名 end  from 表2) 别名2 on 关联条件;
      3) 基于分桶表(大文件分为多个小文件)

6. 列裁剪

==Hive在读数据的时候,可以只读取查询中所需要用到的列,而忽略其他列==

例如:

假设有一个表A: a b c d e   5个字段, 请查看以下SQL
select  a,b from A where a=xxx;
​
在这条SQL, 发现没有使用c d e 字段, 在from A表时候, 读取数据, 只需要将a列 和 b列数据读取出来即可, 不需要读取cde列字段, 这样可以减少读取的数据量, 从而提升效率

如何配置呢?

-- 6.列裁剪(只读取sql语句需要的字段,节省读取开销,提升效率)
set hive.optimize.cp=true;  -- 默认就是true  (在hive 2.x中无需在配置了, 直接为固定值: true)

7. 分区裁剪

==执行查询SQL的时候, 能在join之前提前进行条件过滤的操作, 一定要提前过滤, 不要在join后进行过滤操作==

如果操作的表是一张分区表, 那么建议一定要带上分区字段, 以减少扫描的数据量, 从而提升效率,

例如:

select  * from A join B where A.id=xxx;
优化后:
select * from (select * from A where id= xxx) A join B;

如何配置呢?

-- 7.分区裁剪
set hive.optimize.pruner=true; --默认为就是true (在hive 2.x中无需在配置了, 直接为固定值: true)

8. group by 操作

执行分组操作, 翻译后的MR, 分组的字段就是k2的字段, 按照k2进行分组操作, 将相同value合并在同一个集合中, 既然分组的字段就是MR的k2, 那么分区也会按照分组字段进行分区操作, 如果某个组下数据非常的多, 可能出现出现什么问题呢?

此时有可能发生数据倾斜, 因为相同key会发往同一个reduce中
​
所以说: 在hive中出现数据倾斜的主要体现在两个方面:第一个:执行join操作(reduce join)第二个:执行group by 操作

如何在hive中配置:

方案一:  
    --(1)是否在Map端进行聚合,默认为Trueset hive.map.aggr = true;--(2)在Map端进行聚合操作的条目数目set hive.groupby.mapaggr.checkinterval = 100000;
方案二:  官方称为 负载均衡
--(3)有数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata = true;
    第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。
​

9. count(distinct)

说明 : count(distinct) 在数据量比较大的情况下, 效率并不高

思考: 你知道是为什么吗?

原因如下: 请问1: 执行count操作的时候, hive翻译的MR, reduce数量是否可以有多个? 必然不会有多个, 只能有一个, 因为全局求最终结果此时如果执行统计的时候, 需要进行去重,那么去重工作是由reduce执行去重操作,  由于reduce只有一个, 所有的数据都在一个reduce中, 此时reduce的压力比较大希望执行去重工作可能有多个reduce一起来执行操作, 此时可以将SQL优化: 原有:select count(distinct ip) from ip_tab;优化: select count(ip)from(select ip from ip_tab group by ip) tmp;请注意: 这样的做法, 虽然会运行两个MR, 但是当数据量足够庞大的时候, 此操作绝对是值得的, 如果数据量比较少, 此操作效率更低
​
-- count(distinct)优化
set hive.optimize.countdistinct; -- 默认就是true
set hive.optimize.countdistinct = true;
/*
SELECT count(DISTINCT id) FROM 大表;
结果:
SELECT count(id) FROM (SELECT id FROM 大表 GROUP BY id) a;
*/
select count(distinct devicetype) from device1;
select count(devicetype) from (select devicetype from device1 group by devicetype) a;
-- 注意: 小表拆分两个mr反而效率低,以后大表的时候才会真正提升效率

10. 笛卡尔积

什么是笛卡尔积呢? 在进行join的时候, 两个表乘积之后结果就是笛卡尔积的结果

比如: 一个表有5条, 一个表有3条数据, 笛卡尔积结果就有15条数据 , 笛卡尔积中有大量数据都是无用数据

什么时候会产生笛卡尔积呢? 在多表join的时候, 关联条件缺少或者使用错误的关联条件以及将关联条件放置在where中都会导致笛卡尔积

在实际使用中, 建议:

1) 避免join的时候不加on条件,或者无效的on条件
2) 关联条件不要放置在where语句, 因为底层, 先产生笛卡尔积 然后基于where进行过滤 , 建议放置on条件上
3) 如果实际开发中无法确定表与表关联条件 建议与数据管理者重新对接, 避免出现问题

11. 动态分区[练习]

需求: 请将下面的一个分区表数据, 拷贝到另一个分区表, 保证对应区数据放置到另一个表的对应区下

如何配置呢?

作用:  帮助一次性灌入多个分区的数据
参数: set hive.exec.dynamic.partition.mode=nonstrict;  -- 开启非严格模式 默认为 strict(严格模式)set hive.exec.dynamic.partition=true;  -- 开启动态分区支持, 默认就是true可选的参数:set  hive.exec.max.dynamic.partitions=1000; -- 在所有执行MR的节点上,最大一共可以创建多少个动态分区。set hive.exec.max.dynamic.partitions.pernode=100; -- 每个执行MR的节点上,最大可以创建多少个动态分区set hive.exec.max.created.files=100000; -- 整个MR Job中,最大可以创建多少个HDFS文件

示例:

-- 回顾快速创建表
-- 1.根据score.txt数据以及格式创建表
create table score_part(name string,subject string,score int
)partitioned by (year string)
row format delimited fields terminated by '\t'
;
-- 2.上传score.txt到hdfs中
-- 注意: 分区表需要把文件上传到分区目录中,但是一开始没有目录,所以文件上传到任意目录后,等有了分区目录再使用load移动即可
-- 需要使用load方式生成分区目录并且插入数据
load data inpath '/score.txt' into table score_part partition (year='2022');
-- 3.hive根据元数据和分区目录中业务数据映射成表
select * from score_part;
​
​
​
-- 方式1: 先复制表结构再插入数据
-- 复制表结构,原来的是分区表,复制后也是分区表
create table score_part1 like score_part;
-- 不指定分区字段进行动态分区
insert into score_part1 select * from score_part;
-- 方式2: 一步到位
-- 弊端: 但是作为普通表使用了
create table score_part2 as select * from score_part;
​
​
-- 方式3: 动态分区
-- 关闭严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
-- 复制表结构,原来的是分区表,复制后也是分区表
create table score_part3 like score_part;
-- 指定分区字段进行动态分区(必须是非严格模式)
insert into score_part3 partition (year) select * from score_part;

12. 如何调整map和reduce的数量

1>是不是map数越多越好? 答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

2>是不是保证每个map处理接近128m的文件块,就高枕无忧了? 答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

3>是不是reduce数越多越好? 答案是否定的。如果reduce设置的过大,对整个作业会产生一定的影响。 ①过多的启动和初始化reduce也会消耗时间和资源; ②另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

4>在什么情况下, 只能有一个reduce呢?

以下几种, 不管如何设置, 最终翻译后reduce只能有一个 1) 执行order by操作 2) 执行不需要group by直接聚合的操作 3) 执行笛卡尔积

  • 如何调整mapTask数量:

    小文件场景:当input的文件都很小,把小文件进行合并归档,减少map数, 设置map数量:

    -- 每个Map最大输入大小(这个值决定了合并后文件的数量)set mapred.max.split.size=256000000;
    -- 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)set mapred.min.split.size.per.node=1;
    -- 一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)set mapred.min.split.size.per.rack=1;
    -- 执行Map前进行小文件合并默认CombineHiveInputFormatset hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

    大文件场景:当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。

    举例:如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的, 这种情况下,我们要考虑将这一个文件合理的拆分成多个,这样就可以用多个map任务去完成。 set mapred.reduce.tasks=10; create table a_1 as select * from tab_info distribute by rand(123); 这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。

  • 如何reduce的数量:

    -- 查看reduces数量
    -- 该值默认为-1,由hive自己根据任务情况进行判断。
    set mapred.reduce.tasks;
    set mapreduce.job.reduces;
    -- (1)每个Reduce处理的数据量默认是256MB左右
    set hive.exec.reducers.bytes.per.reducer=256000000;
    -- (2)每个任务最大的reduce数,默认为1009;
    set hive.exec.reducers.max=1009;

13.并行执行

在执行一个SQL语句的时候, SQL会被翻译为MR, 一个SQL有可能被翻译成多个MR, 那么在多个MR之间, 有些MR之间可能不存在任何的关联, 此时可以设置让这些没有关联的MR 并行执行, 从而提升效率 , 默认是 一个一个来

如何配置:

set hive.exec.parallel=false;              --打开任务并行执行,默认关闭
set hive.exec.parallel.thread.number=8;  --同一个sql允许最大并行度,默认为8。
​
前提:服务器必须有资源, 如果没有 即使支持并行, 也没有任何作用

案例:

select  * from A ....
union all
select * from B ...;
​
例如:select from (select * from A group by ...) tmp1 join (select * from B group by xxx) on ...

14. 严格模式

hive提供一种严格模式, 主要目的, 是为了限制一些 效率极低的SQL 放置其执行时间过长, 影响其他的操作

屏蔽一下操作:
1) 执行order by 不加 limit
2) 出现笛卡尔积的现象SQL
3) 查询分区表, 不带分区字段
​
前提: 数据量足够大, 如果数据量比较少, 严格模式对此三项内容不生效

如何配置:

set hive.mapred.mode = strict;  --开启严格模式 
set hive.mapred.mode = nostrict; --开启非严格模式   最新默认

15. JVM 重用

此操作, 在hive2.x已经不需要配置了, 默认支持

jvm重用: 默认情况下, container资源容器  只能使用一次,不能重复使用, 开启JVM重用, 运行container容器可以被重复使用,在hive2.x已经默认支持了

16. 推测执行

Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
hadoop中默认两个阶段都开启了推测执行机制。
hive本身也提供了配置项来控制reduce-side的推测执行:
​
set hive.mapred.reduce.tasks.speculative.execution=true;
​
关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。
​

17.执行计划explain

使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。帮助我们了解底层原理,hive调优,排查数据倾斜等有很有帮助 
​
使用示例:explain [...]  sql查询语句;
​
explain sql语句: 查看执行计划的基本信息
​

(1)stage dependencies:各个stage之间的依赖性
包含多个stage阶段,例如 Stage-1和Stage-0,Stage-1 是根stage,Stage-0 依赖 Stage-1,
(2)stage plan:各个stage的执行计划
包含两部分: map端执行计划树和reduce端执行计划树


Hadoop进阶

HDFS

hdfs默认文件配置:https://hadoop.apache.org/docs/r3.3.4/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml

块和副本

block块: HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件。它将每个文件拆分成一系列的数据块进行存储,这个数据块被称为block,除了最后一个,所有的数据块都是同样大小的。
​
block 块大小默认: 128M(134217728字节)     注意: 块同样大小方便统一管理
​
注意: 为了容错,文件的所有block都会有副本。每个文件的数据块大小和副本系数都是可配置的。副本系数默认:  3个       副本好处: 副本为了保证数据安全(用消耗存储资源方式保证安全,导致了大数据瓶颈是数据存储)
​
hdfs默认文件配置:https://hadoop.apache.org/docs/r3.3.4/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
​
如何修改块大小和副本数量呢?可以在hdfs-site.xml中配置如下属性:
<property><name>dfs.blocksize</name><value>134217728</value><description>设置HDFS块大小,单位是b</description>
</property>
​
<property><name>dfs.replication</name><value>3</value>
</property>
​

图解:

块 :默认统一大小128m : 为了方便统一管理

副本: 默认3个的原因: 为了保证数据的安全性

三大机制

副本机制: 为了保证数据安全和效率,block块信息存储多个副本,第一副本保存在客户端所在服务器,第二副本保存在和第一副本不同机架服务器上,第三副本保存在和第二副本相同机架不同服务器
​
负载均衡机制: namenode为了保证不同的datanode中block块信息大体一样,分配存储任务的时候会优先保存在距离近且余量比较大的datanaode上
​
心跳机制: datanode每隔3秒钟向namenode汇报自己的状态信息,如果某个时刻,datanode连续10次不汇报了,namenode会认为datanode有可能宕机了,namenode就会每5分钟(300000毫秒)发送一次确认消息,连续2次没有收到回复,就认定datanode此时一定宕机了(确认datanode宕机总时间3*10+5*2*60=630秒)

写入数据原理[面试]

1.客户端发起写入数据的请求给namenode
2.namenode接收到客户端请求,开始校验(是否有权限,路径是否存在,文件是否存在等),如果校验没问题,就告知客户端可以写入
3.客户端收到消息,开始把文件数据分割成默认的128m大小的的block块,并且把block块数据拆分成64kb的packet数据包,放入传输序列
​
4.客户端携带block块信息再次向namenode发送请求,获取能够存储block块数据的datanode列表
5.namenode查看当前距离上传位置较近且不忙的datanode,放入列表中返回给客户端
6.客户端连接datanode,开始发送packet数据包,第一个datanode接收完后就给客户端ack应答(客户端就可以传入下一个packet数据包),同时第一个datanode开始复制刚才接收到的数据包给node2,node2接收到数据包也复制给node3(复制成功也需要返回ack应答),最终建立了pipeline传输通道以及ack应答通道
7.其他packet数据根据第一个packet数据包经过的传输通道和应答通道,循环传入packet,直到当前block块数据传输完成(存储了block信息的datanode需要把已经存储的块信息定期的同步给namenode)
​
8.其他block块数据存储,循环执行上述4-7步,直到所有block块传输完成,意味着文件数据被写入成功(namenode把该文件的元数据保存上)
9.最后客户端和namenode互相确认文件数据已经保存完成(也会汇报不能使用的datanode)
​
注意: 不要死记硬背,要结合自己的理解,转换为自己的话术

读取数据原理[面试]

1.客户端发送读取文件请求给namenode
​
2.namdnode接收到请求,然后进行一系列校验(路径是否存在,文件是否存在,是否有权限等),如果没有问题,就告知可以读取
3.客户端需要再次和namenode确认当前文件在哪些datanode中存储
4.namenode查看当前距离下载位置较近且不忙的datanode,放入列表中返回给客户端
​
5.客户端找到最近的datanode开始读取文件对应的block块信息(每次传输是以64kb的packet数据包),放到内存缓冲区中
6.接着读取其他block块信息,循环上述3-5步,直到所有block块读取完毕(根据块编号拼接成完整数据)
7.最后从内存缓冲区把数据通过流写入到目标文件中
​
8.最后客户端和namenode互相确认文件数据已经读取完成(也会汇报不能使用的datanode)
​
注意: 不要死记硬背,要结合自己的理解,转换为自己的话术

edits和fsimage文件

namenode管理元数据: 基于edits和FSImage的配合,完成整个文件系统文件的管理。每次对HDFS的操作,均被edits文件记录, edits达到大小上限后,开启新的edits记录,定期进行edits的合并操作如当前没有fsimage文件,  将全部edits合并为第一个fsimage文件如当前已存在fsimage文件,将全部edits和已存在的fsimage进行合并,形成新的fsimage
​edits编辑文件: 记录hdfs每次操作(namenode接收处理的每次客户端请求)fsimage镜像文件: 记录某一个时间节点前的当前文件系统全部文件的状态和信息(namenode所管理的文件系统的一个镜像)
​
SecondaryNameNode辅助合并元数据: SecondaryNameNode会定期从NameNode拉取数据(edits和fsimage)然后合并完成后提供给NameNode使用。对于元数据的合并,是一个定时过程,基于两个条件:dfs.namenode.checkpoint.period:默认3600(秒)即1小时dfs.namenode.checkpoint.txns: 默认1000000,即100W次事务dfs.namenode.checkpoint.check.period: 检查是否达到上述两个条件,默认60秒检查一次,只要有一个达到条件就执行拉取合并

内存/文件元数据

namenode和secondarynamenode:  配合完成对元数据的保存
​
元数据: 内存元数据 和 文件元数据 两种分别在内存和磁盘上
​
内存元数据: namnode运行过程中产生的元数据会先保存在内存中,再保存到文件元数据中。
内存元数据优缺点: 优点: 因为内存处理数据的速度要比磁盘快。  缺点: 内存一断电,数据全部丢失
​
文件元数据: Edits 编辑日志文件和fsimage 镜像文件
Edits编辑日志文件: 存放的是Hadoop文件系统的所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到edits文件中
Fsimage镜像文件: 是元数据的一个持久化的检查点,包含Hadoop文件系统中的所有目录和文件元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,是在 datanode加入集群的时候,namenode询问datanode得到的,并且不间断的更新
​
fsimage和edits关系: 两个文件都是经过序列化的,只有在NameNode启动的时候才会将fsimage文件中的内容加载到内存中,之后NameNode把增删改查等操作记录同步到edits文件中.使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作,也是最完整的元数据。
图解

查看历史编辑文件
命令:  hdfs oev -i edits文件名 -o 自定义文件名.xml
[root@node1 current]# cd /export/data/hadoop/dfs/name/current
[root@node1 current]# hdfs oev -i edits_0000000000000033404-0000000000000033405 -o 405_edit.xml
[root@node1 current]# cat 405_edit.xml
查看镜像文件
命令:  hdfs oiv -i fsimage文件名 -p XML -o 自定义文件名.xml
[root@node1 current]# cd /export/data/hadoop/dfs/name/current
[root@node1 current]# hdfs oiv -i fsimage_0000000000000033405 -p XML -o 405_fsimage.xml
[root@node1 current]# cat 405_fsimage.xml

元数据存储的原理[面试]

注意: 第一次启动namenode的时候是没有编辑日志文件和镜像文件的,下图主要介绍的是第二次及以后访问的时候情况流程

1.namenode第一次启动的时候先把最新的fsimage文件中内容加载到内存中,同时把edits文件中内容也加载到内存中
2.客户端发起指令(增删改查等操作),namenode接收到客户端指令把每次产生的新的指令操作先放到内存中
3.然后把刚才内存中新的指令操作写入到edits_inprogress文件中
4.edits_inprogress文件中数据到了一定阈值的时候,把文件中历史操作记录写入到序列化的edits备份文件中
5.namenode就在上述2-4步中循环操作...
​
6.当secondarynamenode检测到自己距离上一次检查点(checkpoint)已经1小时或者事务数达到100w,就触发secondarynamenode询问namenode是否对edits文件和fsimage文件进行合并操作
7.namenode告知可以进行合并
8.secondarynamenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行合并(这个过程称checkpoint)
9.secondarynamenode把刚才合并后的fsimage.checkpoint文件拷贝给namenode
​
10.namenode把拷贝过来的最新的fsimage.checkpoint文件,重命名为fsimage,覆盖原来的文件
​
注意: 不要死记硬背,要结合自己的理解,转换为自己的话术

安全模式

安全模式: 不允许HDFS客户端进行任何修改文件的操作,包括上传文件,删除文件等操作。

...

#查看安全模式状态:
[root@node1 /]# hdfs dfsadmin -safemode get  
Safe mode is OFF
#开启安全模式:
[root@node1 /]# hdfs dfsadmin -safemode enter
Safe mode is ON
#退出安全模式:
[root@node1 /]# hdfs dfsadmin -safemode leave
Safe mode is OFF

归档机制

归档原因: 每个小文件单独存放到hdfs中(占用一个block块),那么hdfs就需要依次存储每个小文件的元数据信息,相对来说浪费资源

归档格式: hadoop archive -archiveName 归档名.har -p 原始文件的目录 归档文件的存储目录

准备工作: HDFS上准备一个目录binzi,里面存储三个文件 1.txt 2.txt 3.txt ...

[root@node1 /]# hadoop archive -archiveName test.har -p /binzi  /
...
[root@node1 /]# hdfs dfs -ls /test1.har
Found 4 items
-rw-r--r--   3 root supergroup          0 2022-12-27 15:56 /test.har/_SUCCESS
-rw-r--r--   3 root supergroup        254 2022-12-27 15:56 /test.har/_index
-rw-r--r--   3 root supergroup         23 2022-12-27 15:56 /test.har/_masterindex
-rw-r--r--   3 root supergroup         47 2022-12-27 15:56 /test.har/part-0
[root@node1 /]# hdfs dfs -cat /test1.har/part-0
...

归档特性: Hadoop Archives的URI是:har://scheme-hostname:port/路径/归档名.har scheme-hostname格式为hdfs-域名:端口 如果没有提供scheme-hostname,它会使用默认的文件系统: har:///路径/归档名.har

[root@node1 /]# hdfs dfs -ls har:///test.har       
Found 3 items
-rw-r--r--   3 root supergroup         15 2022-12-27 15:55 har:///test.har/1.txt
-rw-r--r--   3 root supergroup         16 2022-12-27 15:55 har:///test.har/2.txt
-rw-r--r--   3 root supergroup         16 2022-12-27 15:55 har:///test.har/3.txt
[root@node1 /]#  hdfs dfs -cat  har:///test.har/1.txt  
...
[root@node1 /]#  hdfs dfs -cat  har:///test.har/2.txt  
...
[root@node1 /]#  hdfs dfs -cat  har:///test.har/3.txt  
...

垃圾桶机制

在虚拟机中rm命令删除文件,默认是永久删除

在虚拟机中需要手动设置才能使用垃圾桶回收: 把删除的内容放到: /user/root/.Trash/Current/ 先关闭服务: 在 node1 中执行 stop-all.sh 新版本不关闭服务也没有问题 再修改文件 core-site.xml : 进入/export/server/hadoop-3.3.0/etc/hadoop目录下进行修改

<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>

其中,1440 表示 1440分钟,也就是 24小时,一天的时间。

设置了垃圾桶机制好处: 文件不会立刻消失,可以去垃圾桶里把文件恢复,继续使用

# 没有开启垃圾桶效果
[root@node1 hadoop]# hdfs dfs -rm /binzi/hello.txt
Deleted /binzi/hello.txt
​
# 开启垃圾桶
[root@node1 ~]#cd /export/server/hadoop-3.3.0/etc/hadoop
[root@node1 hadoop]# vim core-site.xml
# 注意: 放到<configuration>内容</configuration>中间
<property><name>fs.trash.interval</name><value>1440</value>
</property>
​
# 开启垃圾桶效果
[root@node1 hadoop]# hdfs dfs -rm -r /test1.har
2023-05-24 15:07:33,470 INFO fs.TrashPolicyDefault: Moved: 'hdfs://node1.itcast.cn:8020/test1.har' to trash at: hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/test1.har
​
# 开启垃圾桶后并没有真正删除,还可以恢复
[root@node1 hadoop]# hdfs dfs -mv /user/root/.Trash/Current/test1.har  / 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/198063.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 的执行原理(四)

5.5. MySQL 的查询重写规则 对于一些执行起来十分耗费性能的语句&#xff0c;MySQL 还是依据一些规则&#xff0c;竭尽全力的把这个很糟糕的语句转换成某种可以比较高效执行的形式&#xff0c;这个过程也可以 被称作查询重写。 5.5.1. 条件化简 我们编写的查询语句的搜索条件…

git常用命令和参数有哪些?【git看这一篇就够了】

文章目录 前言常用命令有哪些git速查表奉上常用参数后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;git操作相关 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出…

HCIA-综合实验(三)

综合实验&#xff08;三&#xff09; 1 实验拓扑2 IP 规划3 实验需求一、福州思博网络规划如下&#xff1a;二、上海思博网络规划如下&#xff1a;三、福州思博与上海思博网络互联四、网络优化 4 配置思路4.1 福州思博配置在 SW1、SW2、SW3 上配置交换网络SW1、SW2、SW3 运行 S…

记录一些涉及到界的题

文章目录 coppersmith的一些相关知识题1 [N1CTF 2023] e2Wrmup题2 [ACTF 2023] midRSA题3 [qsnctf 2023]浅记一下 coppersmith的一些相关知识 上界 X c e i l ( 1 2 ∗ N β 2 d − ϵ ) X ceil(\frac{1}{2} * N^{\frac{\beta^2}{d} - \epsilon}) Xceil(21​∗Ndβ2​−ϵ) …

贪吃蛇小游戏

一. 准备工作 首先获取贪吃蛇小游戏所需要的头部、身体、食物以及贪吃蛇标题等图片。、 然后&#xff0c;创建贪吃蛇游戏的Java项目命名为snake_game&#xff0c;并在这个项目里创建一个文件夹命名为images&#xff0c;将图片素材导入文件夹。 再在src文件下创建两个包&#…

【Go入门】 Go如何使得Web工作

【Go入门】 Go如何使得Web工作 前面小节介绍了如何通过Go搭建一个Web服务&#xff0c;我们可以看到简单应用一个net/http包就方便的搭建起来了。那么Go在底层到底是怎么做的呢&#xff1f;万变不离其宗&#xff0c;Go的Web服务工作也离不开我们第一小节介绍的Web工作方式。 w…

2023年【G1工业锅炉司炉】报名考试及G1工业锅炉司炉理论考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G1工业锅炉司炉报名考试是安全生产模拟考试一点通生成的&#xff0c;G1工业锅炉司炉证模拟考试题库是根据G1工业锅炉司炉最新版教材汇编出G1工业锅炉司炉仿真模拟考试。2023年【G1工业锅炉司炉】报名考试及G1工业锅炉…

简单聊一聊幂等和防重

大家好&#xff0c;我是G探险者。 每年的双十一&#xff0c;618&#xff0c;电商系统都会面临这超高的流量&#xff0c;如果一个订单被反复提交&#xff0c;那电商系统如何保证这个订单之后执行一次减库存&#xff0c;扣款的操作&#xff1f; 这里就引入两个概念&#xff0c;…

Python数据分析实战① Python实现数据可视化

文章目录 一、数据可视化介绍二、matplotlib和pandas画图1.matplotlib简介和简单使用2.matplotlib常见作图类型3.使用pandas画图4.pandas中绘图与matplotlib结合使用 三、订单数据分析展示四、Titanic灾难数据分析显示 一、数据可视化介绍 数据可视化是指将数据放在可视环境中…

aliyun Rest ful api V3版本身份验证构造

aliyun Rest ful api V3版本身份验证构造 参考官网&#xff1a;https://help.aliyun.com/zh/sdk/product-overview/v3-request-structure-and-signature?spma2c4g.11186623.0.0.787951e7lHcjZb 构造代码 &#xff1a;使用GET请求进行构造&#xff0c;算法使用sha256 使用postm…

动手学深度学习——循环神经网络的从零开始实现(原理解释+代码详解)

文章目录 循环神经网络的从零开始实现1. 独热编码2. 初始化模型参数3. 循环神经网络模型4. 预测5. 梯度裁剪6. 训练 循环神经网络的从零开始实现 从头开始基于循环神经网络实现字符级语言模型。 # 读取数据集 %matplotlib inline import math import torchfrom torch import …

sqli-labs关卡20(基于http头部报错盲注)通关思路

文章目录 前言一、回顾上一关知识点二、靶场第二十关通关思路1、判断注入点2、爆数据库名3、爆数据库表4、爆数据库列5、爆数据库关键信息 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚…

【Linux】安全审计-audit

文章目录 一、audit简介二、开启auditd服务三、相关文件四、审计规则五、审计日志查询及分析附录1&#xff1a;auditctl -h附录2&#xff1a;systemcall 类型 参考文章&#xff1a; 1、安全-linux audit审计使用入门 2、audit详细使用配置 3、Linux-有哪些常见的System Call&a…

golang学习笔记——接口interfaces

文章目录 Go 语言接口例子空接口空接口的定义空接口的应用空接口作为函数的参数空接口作为map的值 类型断言接口值 类型断言例子001类型断言例子002类型断言例子003巩固练习 Go 语言接口 接口&#xff08;interface&#xff09;定义了一个对象的行为规范&#xff0c;只定义规范…

Java面向对象(高级)-- 类的成员之四:代码块

文章目录 一、回顾&#xff08;1&#xff09;三条主线&#xff08;2&#xff09;类中可以声明的结构及作用1.结构2.作用 二、代码块&#xff08;1&#xff09;代码块的修饰与分类1. 代码块的修饰2. 代码块的分类3. 举例 &#xff08;2&#xff09; 静态代码块1. 语法格式2. 静态…

【数据结构】栈与队列面试题(C语言)

我们再用C语言做题时&#xff0c;是比较不方便的&#xff0c;因此我们在用到数据结构中的某些时只能手搓或者Ctrlcv 我们这里用到的栈或队列来自栈与队列的实现 目录 有效的括号解题思路&#xff1a;代码实现&#xff1a; 用队列实现栈解题思路&#xff1a;代码实现&#xff1a…

4月2日-3日·上海 | 3DCC 第二届3D细胞培养与类器官研发峰会携手CGT Asia 重磅来袭

类器官&#xff08;Organoids&#xff09;作为干细胞研究领域最重要的成果之一&#xff0c;在基础医学研究、转化医学及药物研发领域展现出巨大的应用潜力&#xff0c;特别是在精准医疗以及药物安全性和有效性评价等方向凭借其先天优势引起了极大的市场关注&#xff0c;成为各大…

LabVIEW进行MQTT通信及数据解析

需求&#xff1a;一般通过串口的方式进行数据的解析&#xff0c;但有时候硬件的限制&#xff0c;没法预留串口&#xff0c;那么如何通过网络的方式特别是MQTT数据的通信及解析 解决方式&#xff1a; 1.MQTT通信控件&#xff1a; 参考开源的mqtt-LabVIEW https://github.com…

【iOS】——知乎日报第五周总结

文章目录 一、评论区展开与收缩二、FMDB库实现本地持久化FMDB常用类&#xff1a;FMDB的简单使用&#xff1a; 三、点赞和收藏的持久化 一、评论区展开与收缩 有的评论没有被回复评论或者被回复评论过短&#xff0c;这时就不需要展开全文的按钮&#xff0c;所以首先计算被回复评…

量化交易:借助talib使用技术分析指标

什么是技术分析&#xff1f; 所谓股票的技术分析&#xff0c;是相对于基本面分析而言的。基本分析法着重于对一般经济情况以及各个公司的经营管理状况、行业动态等因素进行分析&#xff0c;以此来研究股票的价值&#xff0c;衡量股价的高低。而技术分析则是透过图表或技术指标…