1,hive架构
1)client,客户端
2)Driver:驱动器
3)解析器,编译器,优化器,执行器
4)底层默认使用mr作为数据处理引擎
5)元数据,通常配置mysql来存储,这样支持多个客户端的访问
2,hive和传统数据库的比较
相同之处:都拥有类似的查询语言
不同之处:
1)数据存储位置不同
hive数据存储在hdfs上,而数据库的数据存储在块设备或本地文件系统中
2)数据更新
hive不建议对数据改写。而数据库通常是需要对数据进行更新操作的。
3)执行延迟
hive的执行延迟较高,而数据库的执行比较快,但是是基于数据量不大的基础上,当数据量过大,数据库的处理能力会骤降,而此时hive的分布式处理的优势就得到了体现。
4)数据规模
hive可支持大规模的数据计算,而数据支持的数据规模较小。
3,hive的内部表和外部表
内部表,删除时,会把元数据和数据一起删除,不适合和其它工具共享数据。
外部表,删除时,只会删除元数据,而不会删除掉数据。
4,4个by的区别
sort by :分区内排序。
order by : 全局有序,最后只有一个reducer。
distrbute by : 类似于mr中的分区,根据指定的属性分区,结合sort by 使用,在指定的数据分区中排序。
cluser by : 当distrbute by 和 sort by 字段一致时,就可以使用 cluster by方式。但是排序只能是升序。
5,窗口函数
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
1)OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
2)CURRENT ROW:当前行
3)n PRECEDING:往前 n 行数据
4) n FOLLOWING:往后 n 行数据
5 ) UNBOUNDED : 起 点 , UNBOUNDED PRECEDING 表 示 从 前 面 的 起 点 ,UNBOUNDED FOLLOWING 表示到后面的终点
6) LAG(col,n):往前第 n 行数据
7)LEAD(col,n):往后第 n 行数据
8) NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。
6,自定义UDF、UDTF
UDF:
继承UDF,重写evaluate 方法
UDTF:
继承GenericUDTF,实现3个方法,initialize方法(定义输出的列名和类型),process方法(执行逻辑,返回结果),close方法
有时候即使hive自带的函数可以满足我们的需求,但是也需要自定义函数,是为了我们的可以方便的添加日志,方便后续的异常处理。
7,hive优化
1)MapJoin
能使用mapJoin,就不要使用common join,把小表全部加载到内存中,在map端进行join,避免了reducer处理。
2,行列过滤
列处理:不要使用select * ,而需要什么列就只拿什么列
行处理:不要在join之后才在where中写副表的过滤条件。这样会先做全表关联,才过滤。
3,分区技术
4,分桶技术
5,合理设置map数
map数不是越多越好,通常情况下,map数由文件个数,文件大小,块大小决定,如果小文件个数太多,则默认会启动过多的map任务,此时需要减少map数,可以使用CombinaHiveImputFormat
有时候,一个文件小于128M,可能存在几千万条记录,如果map的逻辑处理比较复杂,则用一个map处理,就比较耗时,此时可以考虑增加map数。
6,合理设置reduce数
过多的启动reduce会消耗时间和资源
一个reduce会产生一个输出文件,如果reduce过多,会产生很多小文件,对于下级的任务来说,就会出现过多小文件的问题。
当我们在设置reduce个数时,要考虑以上2个问题,设置合理的reduce数量
7,常用参数设置
set hive.merge.mapfiles = true 当只有map任务时,map任务输出的文件合并小文件
set hive.merge.mapredfiles = true 在map-reduce任务结束后合并小文件
8,开启map端的conbiner ,前提是不影响最终结果
9,压缩,在map输出端,选择速度块的压缩方式,snappy压缩,这样可以减少io
8,hive数据倾斜的解决办法
1)group by
纬度过小时,某值数量过多,处理某值的reduce非常耗时,使用sum() group by 来替换count(distinct)
2)mapJoin
3)不同数据类型关联产生的数据倾斜,在关联时把类型统一
4)开启数据倾斜时负载均衡
set hive.groupby.skewindata = true
就是采用2阶段的mapreduce,第一阶段的mr,给key加入随机前缀,把数据均匀分配到reduce中,在第二阶段的mr把随机前缀去除,在聚合。
5,控制控制分布