Hive简介
hive是基于Hadoop的一个数据仓库工具 ,可以结构化映射成一张表 ,提供SQL查询功能
Hive的三种底层引擎
Hive引擎包括: 默认MapReduce ,Tez ,Spark
MapReduce是一种编程模式 ,用于大规模数据集(大于1TB)的并行计算
Tez是对mapreduce进行进一步的查分 ,还是基于mapreduce的
Spark和Tez比较
- 使用场景: spark号称比Mr快100倍 ,而Tez也号称比Mr快100倍 ,二者性能都远超Mr
- spark与Tez都是以DAG方式处理数据
- spark更像是一个通用的计算引擎 ,提供内存计算 ,实时流处理 ,机器学习下等多种计算范式 ,适合迭代计算
- Tez作为一个框架工具 ,特定为hive和pig提供批量计算
弊端:
- spark属于内存计算 ,支持多种运行么模式 ,可以跑在Standalone ,yarn上 ;而Tez只能跑在yarn上 ,虽然spark和yarn兼容 ,但是spark不适合和yarn的其他应用跑在一起
- tez能够及时的释放资源 ,重用container ,节省调度时间 ,对内存的资源要求率不高 ;而spark如果存在迭代计算 ,就会一直占用资源
总结:
tez和spark两者并不矛盾 ,不存在冲突 ,在实际生产中 ,如果数据需要快速处理而且资源充足的情况下 ,则可以选择Spark ,如果资源是瓶颈 ,则可以使用Tez; 可以根据不同的场景不同数据层次做出选择;这个总结同样也适合Spark和mr的比较
Hive的各种存储方式区别
hive包含的文件存储格式: TextFile ,SequenceFile ,RcFile ,ORCfile ,Parquet
TextFile:
- Hive默认的文件格式 ,行存储
- 优点: 最简单的数据存储格式 ,便于和其他工具(pig ,grep ,awk)共享数据 ,便于查看和编辑 ,加载快
- 缺点: 存储空间占用较大 ,I/O性能较低 ,不可UI的数据进行切割 ,合并 ,不能进行并行操作
- 场景: 适用于小型查询 ,测试操作等
RCFile:
- 行列式存储 ,先将数据按行分块 ,每一块数据转换成一个Record对象 ,避免读取一条数据需要读取多个block ,然后块数据按列存储
- 数据按行进行分块 ,按照列存储 ,结合了行存储和列存储的优点
- 优点: 可压缩 ,高效的列存储 ,查询速度较快
- 缺点: 加载时性能消耗较大 ,全量数据读取性能较低
ORCFile:
优化后的RCFile ,优缺点于RCFile类似 ,查询效率最高 ,适用于Hive中大型的存储和查询
Parquet:
- 列存储
- 优点: 更高效的压缩和编码 ,不与任何数据处理绑定 ,可用于多种数据处理框架
- 缺点: 不支持update ,insert ,delete ,ACID(博主不知道什么是ACID)
- 适用于字段非常多 ,无更新 ,只读取部分列数据
sequqnceFIle:
- 键值对形式的二进制文件格式 ,行存储
- 优点: 可压缩 ,可分割 ,优化I/O性能 ,可并行操作
- 缺点: 存储空间占用最大 ,只局限于Hadoop生态使用
- 适用于小数据 ,大部分都是列查询
Join的种类
- CROSS JOIN: 交叉连接 ,计算笛卡尔积
- INNER JOIN: 内连接 ,返回满足条件的记录
- OUTER JOIN
- LEFT: 返回左表所有行 ,右表不存在补NULL
- RIGHT: 返回右表所有行 ,左表不存在补NULL
- FULL: 返回左表和右表的并集 ,不存在补NULL
- SELF JOIN: 自连接 ,将表查询时候命名不同的别名
Hive中Order by ,Sort by ,Distribute by和Cluster by的区别
- order by: 对数据进行全局排序 ,只有一个reduce工作
- sort by: 每个mapreduce中排序 ,一般和distribute by使用 ,且distribute by写在sort by前面 ,当mapreduce.reduce.task=1时,和order的效果一样
- distribute by: 类似于MR的Partition ,对key进行分区 ,结合sort by实现分区排序
- cluster by: 当distribute by和sort by的字段相同时 ,可以使用cluster代替 ,但是cluster by只能升序 ,不能自定义排序
生产环境中使用order by较少 ,容易造成内存溢出(OOM)
生产环境中distribute by和sort by用的比较多
HIve中row_number() ,rank() 和dense_rank()的区别
row_number(): 根据查询结果的顺序计算排序 ,多用于分页查询 123456
rank(): 相同排序时序号重复 ,总序数不变 1 1 3 4 5 5 7
dense_rank(): 排序相同序号重复时 ,总序数减少 1 1 2 3 4 5 5 6
Hive与传统数据的区别
- 存储位置: hive存储在HDFS ,数据库保存在块设备或本地文件系统
- 数据更新: hvie不建议经常修改 ,数据库通常㤇经常改写
- 执行引擎: hive通过mr/spark来实现 ,数据库使用自己的引擎实现
- 执行速度: hive的延迟比较高 ,但处理的数据规模较大 ,数据库查询快 ,但是数据规模比较小
- 数据规模: hive数据规模大 ,数据库数据规模较小
- 扩展性: hive建立在hadoop上 ,随Hadoop进行扩展 ,数据库由于ACID语义 ,扩展有限
Hive分区作用
优化查询效率 ,防止全表扫描
Hive数据倾斜
原因:
- key分布不均匀
- 数据本身存在问题
- 建表没有考虑周全
- 某些SQL本身就会有数据倾斜
解决方法:
- 参数调节:hive.map.aggr = true
- SQL调节
- group by()采用sum()group by的方式来替换count(distinct)完成计算
- mapjoin: 如果不指定MapJoin或者不符合MapJoin的条件 ,那么Hive解析器会将Join操作转换为Common join 既: 在reduce阶段完成join容易发生数据倾斜 ,可以用mapjoin把要join的小表加载到内存在map端完成join ,避免reduce端处理
- 开启数据倾斜时负载均衡: hive.groupby.skewindata = true
- 控制空值分布: 将为空的key转变为空字符串加随机数或随机数 ,将因空值而造成切斜的数据分到不同的reduce. 注意: 对于异常值如果不需要的话 ,最好的是提前通过SQL中的where条件过滤掉 ,这样可以使计算量大大减少 ,实践中可以使用case when对控制赋上最极致 ,此方法比直接写is not null更好 ,前者的job为1 后者的job为2
(补充: 数据倾斜有很多 ,可以通过度娘细细咀嚼)
UDF和UDTF
UDF用于解决公共字段 ,UDTF用于解析事件字段
UDF: 继承UDF ,重写evaluate方法
UDTF: 继承GenericUDTF方法 ,重写三个方法 ,分别是initialize()自定输入的列名和类型 ,
设置输入和输出类型 ,process()将结果返回forward(result) ,close()关闭
- UDF: 一对一
- UDAF: 多对一
- UDTF: 一对多
Hive有哪些存储元数据 ,特点是什么
元数据存储于derby数据库 ,但是只能开启一个hive客户端 ,不推荐使用
元数据存储于mysql数据库 ,可以开启多个客户端进行连接 ,推荐使用
Hive的内部表和外部表
内部表(管理表): 当我们删除一个管理表时 ,Hive会删除元数据和表中数据 ,不适合和其他工具共享数据
外部表: 删除表只是删除表的元数据 ,不会删除表中数据
hive优化
- MpaJoin
- 在Reduce阶段完成join. 容易发生数据倾斜, 可以用Mapjoin把小表全部加载到内存中再map端进行join, 避免Reduce处理
- 行列过滤:
- 列处理: 在select中 ,只需要拿到需要的列 ,尽量使用分区过滤 ,防止全表扫描影响性能 ,少用Select *
- 行处理: 在分区裁剪中 ,使用外表关联的时候 ,如果将副表的关联条件写在where后面 ,那么就会先进行全表关联 ,之后再过滤
- 采用分区技术
- 合理设置map数量
- map的主要决定因素在于input的文件总个数 ,input的文件大小 ,集群设置的文件块大小
- map的数量不是越多越好 ,如果有很多小文件,一个文件会有一个map任务 ,map的启动和初始化的时间远远大于逻辑处理时间 ,就会造成很大的资源浪费
- 不是保证每个文件都是128MB就可以高枕无忧 ,如果这个文件只有一个或者两个字段 ,有着几千万的记录 ,如果map的逻辑还比较复杂 ,用一个map任务去做的话肯定耗时
- 针对2 3的情况 ,我们的方法就是减少map和增加map数量
- 合理设置reduce
- 过多的reduce数量 ,会和map出现一样的情况 ,启动和初始化的reduce消耗时间和资源
- 有多少个reduce数量 ,就会输出多个少个文件 ,如果这些小文件作为下一个任务的输入 ,那就会出现小文件过多的问题
- 在设置reduce数量的时候保持两个原子: 处理数据量利用合适的reduce数量 ,单个reduce任务处理的数据量大小要合适
- 压缩(选择快的): 设置map端输出 ,中间结果压缩 (不完全是解决数据倾斜问题 ,也会解决I/O读写和网络传输 ,能提高很多效率)
- 开启map端的combiner(不营销业务逻辑): set hive.map.aggr = true
- 开启JVM重用
- 常用参数 输出合并小文件
set hive.merge.mapfiles = true //默认true 在map-only任务结束时候合并小文件
set hive.merge.mapredfiles = true //默认false 在map-reduce任务结束合并小文件
set hive.merge.size.per.task = 268435456 //默认256M
set hive.erge.smallfiles.avgsize = 1677216 //当输出文件的平均大小小于16M的时候 ,启动一个独立的map-reduce任务进行文件合并