看完此文你将理解:
1、静态分区
2、动态分区
3、spark 怎么动态分区
静态分区
静态分区是指人为的指定分区名。向分区插入数据的时候也要写明写入那个分区。
创建分区的时候使用Partitioned by 关键字定义。
创建静态分区
create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';
静态分区,插入的时候必须首先要知道有什么分区类型,而且每个分区写一个loaddata。
load data local inpath '/opt/aaa' overwrite into table par_tab partition (sex='m');
动态分区
动态分区可以允许所有的分区列都是动态分区列。
使用动态分区可解决以静态分区必须每次指定字段值load数据的问题,其可以根据查询得到的数据动态分配到分区里。
简单点理解就是静态分区是由手动指定目录,而动态分区是hive自动帮我们指定目录。
动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。这是因为hive的分区数据是元数据的一部分,由hdfs的namenode进行管理,hive 启动后,会缓存在内存中,一级分区过多会影响集群性能。
假如动态分区作为一级分区,那必将产生非常多的分区目录,即一级目录。这样子一级目录过多就会给namenode 产生过大的压力,影响hdfs集群性能。
动态分区几个参数:
hive.exec.dynamic.partition 默认值:false 是否开启动态分区功能,默认false关闭。 使用动态分区时候,该参数必须设置成true。
hive.exec.dynamic.partition.mode 动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。 一般需要设置为nonstrict 。
hive.exec.max.dynamic.partitions.pernode 在每个执行MR的节点上,最大可以创建多少个动态分区。 该参数需要根据实际的数据来设定。 比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。
hive.exec.max.dynamic.partitions 默认值:1000 在所有执行MR的节点上,最大一共可以创建多少个动态分区。
hive.exec.max.created.files 默认值:100000 整个MR Job中,最大可以创建多少个HDFS文件。
hive.error.on.empty.partition 默认值:false 当有空分区生成时,是否抛出异常。 一般不需要设置。
spark 方式进行动态分区
dataframe模式
conf = SparkConf().setAppName(app).set('spark.sql.sources.partitionOverwriteMode','dynamic') df_table=hive_ctx.createDataFrame(table_rdd, table_schema) df_table.write.saveAsTable(database + '.' + a_table, format=format,mode='overwrite', partitionBy='data_date', path=output_path) //data_date 为分区时间
sql 模式
a_table_view=a_table+"_view" df_table.createOrReplaceTempView(a_table_view) ## 创建视图 hive_ctx.sql("set hive.exec.dynamic.partition.mode = nonstrict") hive_ctx.sql("set hive.exec.dynamic.partition = true") hive_ctx.sql("use " + database).show() ## 转换表 sql="insert overwrite table %s partition(data_date) select * from %s " % (a_table,a_table_view) ## 进行分区增量覆盖 hive_ctx.sql(sql)
sql 模式通过创建一个视图,然后用sql insert overwrite 实现。其中partition(data_date) 指定的分区。