13-Hive分桶优化

Hive数据仓库

Hive参数

hive 参数、变量

  • hive当中的参数、变量,都是以命名空间开头

  • hive 参数设置方式

    • 1、修改配置文件 ${HIVE_HOME}/conf/hive-site.xml

    • 2、启动hive cli时,通过–hiveconf key=value的方式进行设置

      • 例:hive --hiveconf hive.cli.print.header=true
    • 3、进入cli之后,通过使用set命令设置

  • hive set命令

    • 在hive CLI控制台可以通过set对hive中的参数进行查询、设置

    • set设置:

      • set hive.cli.print.header=true;
    • set查看

      • set hive.cli.print.header
    • hive参数初始化配置

      • 当前用户家目录下的.hiverc文件
      • 如: ~/.hiverc
      • 如果没有,可直接创建该文件,将需要设置的参数写到该文件中,hive启动运行时,会加载改文件中的配置。
    • hive历史操作命令集

      • ~/.hivehistory

Hive分桶

分区与分桶区别:

  • 分区控制多级目录
  • 分桶控制多个文件

hive 分桶

  • 分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储
  • 对于hive中每一个表、分区都可以进一步进行分桶
  • 由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中

开启支持分桶

  • set hive.enforce.bucketing=true;
  • 默认:false;设置为true之后,mr运行时会根据bucket的个数自动分配reduce task个数。(用户也可以通过mapred.reduce.tasks自己设置reduce任务个数,但分桶时不推荐使用)
  • 注意:一次作业产生的桶(文件数量)和reduce task个数一致

往分桶表中加载数据

  • insert into table bucket_table select columns from tbl;
  • insert overwrite table bucket_table select columns from tbl;

适用场景:

  • 数据抽样( sampling )

    • 桶表 抽样查询

      • 语句

        • select * from bucket_table tablesample(bucket 1 out of 4 on columns);
      • TABLESAMPLE语法:

        • TABLESAMPLE(BUCKET x OUT OF y)
        • x:表示从哪个bucket开始抽取数据
        • y:必须为该表总bucket数的倍数或因子
      • 例:

        • 当表总bucket数为32时

        • TABLESAMPLE(BUCKET 3 OUT OF 8),抽取哪些数据?

          • 共抽取2(32/16)个bucket的数据,抽取第2、第18(16+2)个bucket的数据
        • TABLESAMPLE(BUCKET 3 OUT OF 256),抽取哪些数据?

      • 实操:

        • 建表

          • CREATE TABLE psn31( id INT, name STRING, age INT)
            ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
        • 测试数据

          • 1,tom,11
            2,cat,22
            3,dog,33
            4,hive,44
            5,hbase,55
            6,mr,66
            7,alice,77
            8,scala,88
        • 创建分桶表

          • CREATE TABLE psnbucket( id INT, name STRING, age INT)
            CLUSTERED BY (age) INTO 4 BUCKETS
            ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
        • 加载数据:

          • insert into table psnbucket select id, name, age from psn31;
        • 抽样

          • select id, name, age from psnbucket tablesample(bucket 2 out of 4 on age);

Hive Lateral View

Lateral View用于和UDTF函数(explode、split)结合来使用

首先通过UDTF函数拆分成多行,再将多行结果组合成一个支持别名的虚拟表

主要解决在select使用UDTF做查询过程中,查询只能包含单个UDTF,不能包含其他字段、以及多个UDTF的问题

语法:

  • LATERAL VIEW udtf(expression) tableAlias AS columnAlias (’,’ columnAlias)

实例:

  • 需求:统计人员表中共有多少种爱好、多少个城市?

  • 数据

  • SQL

    • select count(distinct(myCol1)), count(distinct(myCol2)) from psn2
      LATERAL VIEW explode(likes) myTable1 AS myCol1
      LATERAL VIEW explode(address) myTable2 AS myCol2, myCol3;

Hive 视图

和关系型数据库中的普通视图一样,hive也支持视图

特点:

  • 不支持物化视图
  • 只能查询,不能做加载数据操作
  • 视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询
  • view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行ORDER BY/LIMIT语句操作,view当中定义的优先级更高
  • view支持迭代视图

View语法

  • 创建视图:

    • CREATE VIEW [IF NOT EXISTS] [db_name.]view_name
      [(column_name [COMMENT column_comment], …) ]
      [COMMENT view_comment]
      [TBLPROPERTIES (property_name = property_value, …)]
      AS SELECT … ;
  • 查询视图:

    • select colums from view;
  • 删除视图:

    • DROP VIEW [IF EXISTS] [db_name.]view_name;

Hive 索引

目的:

  • 优化查询以及检索性能

创建索引:

  • create index t1_index on table psn2(name)
    as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’ with deferred rebuild
    in table t1_index_table;

    • as:指定索引器;
    • in table:指定索引表,若不指定默认生成在default__psn2_t1_index__表中
  • create index t1_index on table psn2(name)
    as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’ with deferred rebuild;

查询索引:

  • show index on psn2;

重建索引(建立索引之后必须重建索引才能生效):

  • ALTER INDEX t1_index ON psn REBUILD;

删除索引:

  • DROP INDEX IF EXISTS t1_index ON psn2;

Hive 运行方式

命令行方式cli:控制台模式

  • 与hdfs交互

    • 执行执行dfs命令
    • 例:dfs –ls /
  • 与Linux交互

    • !开头
    • 例: !pwd

脚本运行方式(实际生产环境中用最多)

  • hive -e “”
  • hive -e “”>aaa
  • hive -S -e “”>aaa
  • hive -f file
  • hive -i /home/my/hive-init.sql
  • hive> source file (在hive cli中运行)

JDBC方式:hiveserver2

web GUI接口 (hwi、hue等)

  • web界面安装:

    • 下载源码包apache-hive-*-src.tar.gz

    • 将hwi war包放在$HIVE_HOME/lib/

      • 制作方法:将hwi/web/*里面所有的文件打成war包
      • cd apache-hive-1.2.1-src/hwi/web
      • jar -cvf hive-hwi.war *
    • 复制tools.jar(在jdk的lib目录下)到$HIVE_HOME/lib下

    • 修改hive-site.xml

    hive.hwi.listen.host
    0.0.0.0


    hive.hwi.listen.port
    9999


    hive.hwi.war.file
    lib/hive-hwi.war

    • 启动hwi服务(端口号9999)

      • hive --service hwi
    • 浏览器通过以下链接来访问

      • http://node3:9999/hwi/

Hive 权限管理

Hive 权限管理

  • 三种授权模型:

    • Storage Based Authorization in the Metastore Server

      • 基于存储的授权 - 可以对Metastore中的元数据进行保护,但是没有提供更加细粒度的访问控制(例如:列级别、行级别)
    • SQL Standards Based Authorization in HiveServer2

      • 概要基于SQL标准的Hive授权 - 完全兼容SQL的授权模型,推荐使用该模式。
    • Default Hive Authorization (Legacy Mode)

      • hive默认授权 - 设计目的仅仅只是为了防止用户产生误操作,而不是防止恶意用户访问未经授权的数据。
  • Hive - SQL Standards Based Authorization in HiveServer2

    • 完全兼容SQL的授权模型

    • 除支持对于用户的授权认证,还支持角色role的授权认证

      • role可理解为是一组权限的集合,通过role为用户授权
      • 一个用户可以具有一个或多个角色
      • 默认包含另种角色:public、admin
    • 限制:

      • 1、启用当前认证方式之后,dfs, add, delete, compile, and reset等命令被禁用
      • 2、通过set命令设置hive configuration的方式被限制某些用户使用
      • (可通过修改配置文件hive-site.xml中hive.security.authorization.sqlstd.confwhitelist进行配置)
      • 3、添加、删除函数以及宏的操作,仅为具有admin的用户开放
      • 4、用户自定义函数(开放支持永久的自定义函数),可通过具有admin角色的用户创建,其他用户都可以使用
      • 5、Transform功能被禁用
    • 配置hive-site.xml

    hive.security.authorization.enabled
    true

    -
    hive.server2.enable.doAs
    false

    -
    hive.users.in.admin.role
    root

    -
    hive.security.authorization.manager
    org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory

    -
    hive.security.authenticator.manager
    org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator

    • 角色的添加、删除、查看、设置:

      • CREATE ROLE role_name; – 创建角色
      • DROP ROLE role_name; – 删除角色
      • SET ROLE (role_name|ALL|NONE); – 设置角色
      • SHOW CURRENT ROLES; – 查看当前具有的角色
      • SHOW ROLES; – 查看所有存在的角色
    • 角色的授予、移除、查看

    • 权限:

      • SELECT privilege – gives read access to an object.
      • INSERT privilege – gives ability to add data to an object (table).
      • UPDATE privilege – gives ability to run update queries on an object (table).
      • DELETE privilege – gives ability to delete data in an object (table).
      • ALL PRIVILEGES – gives all privileges (gets translated into all the above privileges).
    • 权限的授予、移除、查看

Hive优化

核心思想:把Hive SQL 当做Mapreduce程序去优化

以下SQL不会转为Mapreduce来执行:

  • select仅查询本表字段
  • where仅对本表字段做条件过滤

Hive抓取策略

  • Hive中对某些情况的查询不需要使用MapReduce计算

  • Set hive.fetch.task.conversion=none/more;

    • none:所有执行MR
    • more:不一定

Explain 显示执行计划

  • EXPLAIN [EXTENDED] query

Hive运行方式:

  • 本地模式

    • 开启本地模式:

      • set hive.exec.mode.local.auto=true;
    • 注意:

      • hive.exec.mode.local.auto.inputbytes.max默认值为128M
      • 表示加载文件的最大值,若大于该配置仍会以集群方式来运行
  • 集群模式(默)

并行计算

  • 通过设置以下参数开启并行模式:

    • set hive.exec.parallel=true;
  • 注意:hive.exec.parallel.thread.number

    • (一次SQL计算中允许并行执行的job个数的最大值)

严格模式

  • 通过设置以下参数开启严格模式:

    • set hive.mapred.mode=strict;
    • (默认为:nonstrict非严格模式)
  • 查询限制:

    • 1、对于分区表,必须添加where对于分区字段的条件过滤;
    • 2、order by语句必须包含limit输出限制;
    • 3、限制执行笛卡尔积的查询。

Hive排序

  • Order By - 对于查询结果做全排序,只允许有一个reduce处理

    • (当数据量较大时,应慎用。严格模式下,必须结合limit来使用)
  • Sort By - 对於单个reduce的数据进行排序

  • Distribute By - 分区排序,经常和Sort By结合使用

  • Cluster By - 相当于 Sort By + Distribute By

    • (Cluster By不能通过asc、desc的方式指定排序规则;
    • 可通过 distribute by column sort by column asc|desc 的方式)

Hive Join

  • Join计算时,将小表(驱动表)放在join的左边

  • Map Join:在Map端完成Join

    • 两种实现方式:

      • 1、SQL方式,在SQL语句中添加MapJoin标记(mapjoin hint)

        • 语法:

          • SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value
            FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
      • 2、开启自动的MapJoin

  • 自动的mapjoin

    • 通过修改以下配置启用自动的mapjoin:

      • set hive.auto.convert.join = true;

        • (该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对小表使用Map join)
  • 相关配置参数:

    • hive.mapjoin.smalltable.filesize;

      • (大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行)
    • hive.ignore.mapjoin.hint;

      • (默认值:true;是否忽略mapjoin hint 即mapjoin标记)
    • hive.auto.convert.join.noconditionaltask;

      • (默认值:true;将普通的join转化为普通的mapjoin时,是否将多个mapjoin转化为一个mapjoin)
    • hive.auto.convert.join.noconditionaltask.size;

      • (将多个mapjoin转化为一个mapjoin时,其表的最大值)
  • 尽可能使用相同的连接键(会转化为一个MapReduce作业)

  • 大表join大表

    • 空key过滤:有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。
    • 空key转换:有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上

Map-Side聚合

  • 通过设置以下参数开启在Map端的聚合:

    • set hive.map.aggr=true;
  • 相关配置参数:

    • hive.groupby.mapaggr.checkinterval:

      • map端group by执行聚合时处理的多少行数据(默认:100000)
    • hive.map.aggr.hash.min.reduction:

      • 进行聚合的最小比例(预先对100000条数据做聚合,若聚合之后的数据量/100000的值大于该配置0.5,则不会聚合)
    • hive.map.aggr.hash.percentmemory:

      • map端聚合使用的内存的最大值
    • hive.map.aggr.hash.force.flush.memory.threshold:

      • map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush
    • hive.groupby.skewindata

      • 是否对GroupBy产生的数据倾斜做优化,默认为false

合并小文件

  • 文件数目小,容易在文件存储端造成压力,给hdfs造成压力,影响效率

  • 设置合并属性

    • 是否合并map输出文件:hive.merge.mapfiles=true
    • 是否合并reduce输出文件:hive.merge.mapredfiles=true;
    • 合并文件的大小:hive.merge.size.per.task=25610001000
  • 去重统计

    • 数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换

控制Hive中Map以及Reduce的数量

  • Map数量相关的参数

    • mapred.max.split.size

      • 一个split的最大值,即每个map处理文件的最大值
    • mapred.min.split.size.per.node

      • 一个节点上split的最小值
    • mapred.min.split.size.per.rack

      • 一个机架上split的最小值
  • Reduce数量相关的参数

    • mapred.reduce.tasks

      • 强制指定reduce任务的数量
    • hive.exec.reducers.bytes.per.reducer

      • 每个reduce任务处理的数据量
    • hive.exec.reducers.max

      • 每个任务最大的reduce数

Hive - JVM重用

  • 适用场景:

    • 1、小文件个数过多
    • 2、task个数过多
  • 通过 set mapred.job.reuse.jvm.num.tasks=n; 来设置

    • (n为task插槽个数)
  • 缺点:设置开启之后,task插槽会一直占用资源,不论是否有task运行,直到所有的task即整个job全部执行完成时,才会释放所有的task插槽资源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章