hive中怎么实现动态分区和静态分区

hive中怎么实现动态分区和静态分区,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

改则网站建设公司创新互联公司,改则网站设计制作,有大型网站制作公司丰富经验。已为改则上千提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的改则做网站的公司定做!

一、基本概念

  hive中分区表分为:范围分区、列表分区、hash分区、混合分区等。

  分区列:分区列不是表中的一个实际的字段,而是一个或者多个伪列。翻译一下是:“在表的数据文件中实际上并不保存分区列的信息与数据”,这个概念十分重要,要记住,后面是经常用到。

1.1 创建数据表

  下面的语句创建了一个简单的分区表:

hive中怎么实现动态分区和静态分区

create table partition_test(
  member_id string,
  name string
)
partitioned by (
  stat_date string,
  province string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

复制代码

1.2 创建分区

  这个例子中创建了stat_date和province两个字段作为分区列。如果要添加数据,通常情况下我们需要先创建好分区,然后才能使用该分区,例如:

alter table partition_test add partition (stat_date='20141113',province='jilin');

  这样就创建好了一个分区。这时我们会看到hive在HDFS存储中创建了一个相应的文件夹:

hive> dfs -ls /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113;
Found 1 items
drwxr-xr-x   - ticketdev ticketdev          0 2014-11-13 17:50 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=jilin
h

  每一个分区都会有一个独立的文件夹,在这个例子中stat_date是主文件夹,province是子文件夹,如:

hive中怎么实现动态分区和静态分区

hive> alter table partition_test add partition (stat_date='20141113',province='beijing');     
OK
Time taken: 0.119 seconds
hive> dfs -ls /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/;              
Found 2 items
drwxr-xr-x   - ticketdev ticketdev          0 2014-11-13 18:06 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=beijing
drwxr-xr-x   - ticketdev ticketdev          0 2014-11-13 17:50 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=jilin

复制代码

二、静态分区

2.1 数据准备

  基本知识介绍到这里,下面开始插入数据。我使用一个辅助的非分区表partition_test_input准备向partition_test中插入数据:

hive中怎么实现动态分区和静态分区

hive> desc partition_test_input;
OK
stat_date string
member_id string
name string
province string

hive> select * from partition_test_input;
OK20110526 1 liujiannan liaoning20110526 2 wangchaoqun hubei20110728 3 xuhongxing sichuan20110728 4 zhudaoyong henan20110728 5 zhouchengyu heilongjiang

复制代码

2.2 添加数据

  然后我向partition_test的分区中插入数据:

hive中怎么实现动态分区和静态分区

hive> insert overwrite table partition_test partition(stat_date='20110728',province='henan') select member_id,name from partition_test_input where stat_date='20141113' and province='beijing';
Total MapReduce jobs = 2...1 Rows loaded to partition_test
OK

复制代码

  还可以同时向多个分区插入数据:

hive中怎么实现动态分区和静态分区

hive>> from partition_test_input> insert overwrite table partition_test partition (stat_date='20110526',province='liaoning')> select member_id,name where stat_date='20110526' and province='liaoning'> insert overwrite table partition_test partition (stat_date='20110728',province='sichuan')> select member_id,name where stat_date='20110728' and province='sichuan'> insert overwrite table partition_test partition (stat_date='20110728',province='heilongjiang')> select member_id,name where stat_date='20110728' and province='heilongjiang';
Total MapReduce jobs = 4...3 Rows loaded to partition_test
OK

复制代码

  特别要注意,在其他数据库中,一般向分区表中插入数据时系统会校验数据是否符合该分区,如果不符合会报错。而在hive中,向某个分区中插入什么样的数据完全是由人来控制的,因为分区键是伪列,不实际存储在文件中,如:

hive中怎么实现动态分区和静态分区

hive> insert overwrite table partition_test partition(stat_date='20110527',province='liaoning') select member_id,name from partition_test_input;
Total MapReduce jobs = 2...5 Rows loaded to partition_test
OK

hive> select * from partition_test where stat_date='20110527' and province='liaoning';
OK1 liujiannan 20110527 liaoning2 wangchaoqun 20110527 liaoning3 xuhongxing 20110527 liaoning4 zhudaoyong 20110527 liaoning5 zhouchengyu 20110527 liaoning

复制代码

  可以看到在partition_test_input中的5条数据有着不同的stat_date和province,但是在插入到partition(stat_date='20110527',province='liaoning')这个分区后,5条数据的stat_date和province都变成相同的了,因为这两列的数据是根据文件夹的名字读取来的,而不是实际从数据文件中读取来的:

hive中怎么实现动态分区和静态分区

$ hadoop fs -cat /user/hive/warehouse/partition_test/stat_date=20110527/province=liaoning/000000_01,liujiannan2,wangchaoqun3,xuhongxing4,zhudaoyong5,zhouchengyu

复制代码

三、动态分区

  下面介绍一下动态分区,因为按照上面的方法向分区表中插入数据,如果源数据量很大,那么针对一个分区就要写一个insert,非常麻烦。况且在之前的版本中,必须先手动创建好所有的分区后才能插入,这就更麻烦了,你必须先要知道源数据中都有什么样的数据才能创建分区。

  使用动态分区可以很好的解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。

  使用动态分区要先设置hive.exec.dynamic.partition参数值为true,默认值为false,即不允许使用:

hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=false
hive> set hive.exec.dynamic.partition=true;
hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=true

  动态分区的使用方法很简单,假设我想向stat_date='20110728'这个分区下面插入数据,至于province插入到哪个子分区下面让数据库自己来判断,那可以这样写:

hive中怎么实现动态分区和静态分区

hive> insert overwrite table partition_test partition(stat_date='20110728',province)> select member_id,name,province from partition_test_input where stat_date='20110728';
Total MapReduce jobs = 2...3 Rows loaded to partition_test
OK

复制代码

  stat_date叫做静态分区列,province叫做动态分区列。select子句中需要把动态分区列按照分区的顺序写出来,静态分区列不用写出来。这样stat_date='20110728'的所有数据,会根据province的不同分别插入到/user/hive/warehouse/partition_test/stat_date=20110728/下面的不同的子文件夹下,如果源数据对应的province子分区不存在,则会自动创建,非常方便,而且避免了人工控制插入数据与分区的映射关系存在的潜在风险。

  注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区:

hive> insert overwrite table partition_test partition(stat_date,province='liaoning')> select member_id,name,province from partition_test_input where province='liaoning';
FAILED: Error in semantic analysis: Line 1:48 Dynamic partition cannot be the parent of a static partition 'liaoning'

  动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :

hive> set hive.exec.dynamic.partition.mode;
hive.exec.dynamic.partition.mode=strict

  它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。所以我们要设置:

hive> set hive.exec.dynamic.partition.mode=nostrick;

  再介绍3个参数:

  • hive.exec.max.dynamic.partitions.pernode (缺省值100):每一个mapreduce job允许创建的分区的最大数量,如果超过了这个数量就会报错

  • hive.exec.max.dynamic.partitions (缺省值1000):一个dml语句允许创建的所有分区的最大数量

  • hive.exec.max.created.files (缺省值100000):所有的mapreduce job允许创建的文件的最大数量

关于hive中怎么实现动态分区和静态分区问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


网站标题:hive中怎么实现动态分区和静态分区
本文链接:http://myzitong.com/article/igchpo.html