hive分区字段含中文导致的报错

hive创建动态分区的时候,如果分区中有中文名会报如下错误:

Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.io.InterruptedIOException: Call interrupted
        at org.apache.hadoop.hive.ql.metadata.Hive.needToCopy(Hive.java:3073)
        at org.apache.hadoop.hive.ql.metadata.Hive.moveFile(Hive.java:2905)

原因是分区表的编码和全局编码不相同造成的
方案一:修改MySQL配置
临时修改:进入MySQL中设置参数

set character_set_client = utf8;
set character_set_connection = utf8;
set character_set_results = utf8;
 
SET collation_server = utf8_general_ci
SET collation_database = utf8_general_ci

永久修改:修改mysql配置文件后重启

[root@ambari03 etc] vim /etc/my.cnf
# [client]下添加如下内容
[client]
default-character-set=utf8
# [mysqld]下添加如下内容
[mysqld]
default-character-set=utf8
init_connect='SET NAMES utf8'
# [mysql]下添加如下内容
[mysql]
default-character-set=utf8

方案二:修改mysql中Hive元数据库各个表的编码
进入mysql后,执行以下语句修改hive元数据表的编码信息

alter database hive_meta default character set utf8;
alter table BUCKETING_COLS default character set utf8;
alter table CDS default character set utf8;
alter table COLUMNS_V2 default character set utf8;
alter table DATABASE_PARAMS default character set utf8;
alter table DBS default character set utf8;
alter table FUNCS default character set utf8;
alter table FUNC_RU default character set utf8;
alter table GLOBAL_PRIVS default character set utf8;
alter table PARTITIONS default character set utf8;
alter table PARTITION_KEYS default character set utf8;
alter table PARTITION_KEY_VALS default character set utf8;
alter table PARTITION_PARAMS default character set utf8;
-- alter table PART_COL_STATS default character set utf8;
alter table ROLES default character set utf8;
alter table SDS default character set utf8;
alter table SD_PARAMS default character set utf8;
alter table SEQUENCE_TABLE default character set utf8;
alter table SERDES default character set utf8;
alter table SERDE_PARAMS default character set utf8;
alter table SKEWED_COL_NAMES default character set utf8;
alter table SKEWED_COL_VALUE_LOC_MAP default character set utf8;
alter table SKEWED_STRING_LIST default character set utf8;
alter table SKEWED_STRING_LIST_VALUES default character set utf8;
alter table SKEWED_VALUES default character set utf8;
alter table SORT_COLS default character set utf8;
alter table TABLE_PARAMS default character set utf8;
alter table TAB_COL_STATS default character set utf8;
alter table TBLS default character set utf8;
alter table VERSION default character set utf8;
alter table BUCKETING_COLS convert to character set utf8;
alter table CDS convert to character set utf8;
alter table COLUMNS_V2 convert to character set utf8;
alter table DATABASE_PARAMS convert to character set utf8;
alter table DBS convert to character set utf8;
alter table FUNCS convert to character set utf8;
alter table FUNC_RU convert to character set utf8;
alter table GLOBAL_PRIVS convert to character set utf8;
alter table PARTITIONS convert to character set utf8;
alter table PARTITION_KEYS convert to character set utf8;
alter table PARTITION_KEY_VALS convert to character set utf8;
alter table PARTITION_PARAMS convert to character set utf8;
-- alter table PART_COL_STATS convert to character set utf8;
alter table ROLES convert to character set utf8;
alter table SDS convert to character set utf8;
alter table SD_PARAMS convert to character set utf8;
alter table SEQUENCE_TABLE convert to character set utf8;
alter table SERDES convert to character set utf8;
alter table SERDE_PARAMS convert to character set utf8;
alter table SKEWED_COL_NAMES convert to character set utf8;
alter table SKEWED_COL_VALUE_LOC_MAP convert to character set utf8;
alter table SKEWED_STRING_LIST convert to character set utf8;
alter table SKEWED_STRING_LIST_VALUES convert to character set utf8;
alter table SKEWED_VALUES convert to character set utf8;
alter table SORT_COLS convert to character set utf8;
alter table TABLE_PARAMS convert to character set utf8;
alter table TAB_COL_STATS convert to character set utf8;
alter table TBLS convert to character set utf8;
alter table VERSION convert to character set utf8;
-- alter table PART_COL_STATS convert to character set utf8;
SET character_set_client = utf8 ;
-- SET character_set_connection = utf8 ;
 
-- alter table PART_COL_STATS convert to character set utf8;
SET character_set_database = utf8 ;
SET character_set_results = utf8 ;
SET character_set_server = utf8 ;
-- SET collation_connection = utf8 ;
-- SET collation_database = utf8 ;
-- SET collation_server = utf8 ;
SET NAMES 'utf8';

修改后能够插入带有中文分区的表格,但是插入后虽然可以查询到数据已经插入,Hive仍然会报错

查看日志后定位到如下错误

2021-02-23T10:54:26,249 ERROR [HiveServer2-Background-Pool: Thread-248] exec.StatsTask: Failed to run stats task
org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(message:Insert of object "org.apache.hadoop.hive.metastore.model.MPartitionColumnStatistics@710c136f" using statement "INSERT INTO `PART_COL_STATS` (`CS_ID`,`AVG_COL_LEN`,`BIT_VECTOR`,`CAT_NAME`,`COLUMN_NAME`,`COLUMN_TYPE`,`DB_NAME`,`BIG_DECIMAL_HIGH_VALUE`,`BIG_DECIMAL_LOW_VALUE`,`DOUBLE_HIGH_VALUE`,`DOUBLE_LOW_VALUE`,`LAST_ANALYZED`,`LONG_HIGH_VALUE`,`LONG_LOW_VALUE`,`MAX_COL_LEN`,`NUM_DISTINCTS`,`NUM_FALSES`,`NUM_NULLS`,`NUM_TRUES`,`PART_ID`,`PARTITION_NAME`,`TABLE_NAME`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" failed : Incorrect string value: '\xE6\xB9\x96\xE5\x8C\x97' for column 'PARTITION_NAME' at row 1)

Mysql中查看metastore库的ART_COL_STATS表

use metastore;
-- show create table PART_COL_STATS;
show full columns from PART_COL_STATS;

部分字段结果如下
在这里插入图片描述
可以看到需要PARTITION_NAME字段编码仍然为latin1,因此需要将PARTITION_NAME字段编码修改为utf8

use metastore;
alter table PART_COL_STATS modify column PARTITION_NAME varchar(500) character set utf8;

修改后重新插入带有中文分区的表格,可以正常运行

参考案例如下

create database mydb;
use mydb;
-- ① 创建不带分区的stu表
create table stu
(
    name string,
    age  int
) row format delimited fields terminated by '\t';

-- ② 上传数据到hdfs对应目录

-- ③ 创建分区表emp
create table emp
(
    name string,
    age  int
)
    partitioned by (provice string)
    row format delimited fields terminated by '\t';

-- ④ 插入数据含有中文分区的emp表中
insert into emp partition(provice = "湖北")
select * from stu;

方案三:若中文分区是不规范的,可以在脚本中直接用正则过滤掉中文

where  not regexp(t.event_app,'[\\u4E00-\\u9FFF]+') -- 过滤中文字符
### 回答1: Hive分区字段并不是随便取的,应该根据数据特点和业务需求来选择合适的字段作为分区键。一般来说,分区字段应该是数据中具有代表性的列,例如日期、地理位置、产品类别等。选择合适的分区字段可以提高查询效率和数据管理的灵活性。 ### 回答2: 对于Hive分区字段的选择,并没有固定的规定,可以根据具体的业务需求和数据特点来灵活选择。 Hive分区字段应当选择在数据存储中具有较高的区分度,并且在查询操作中有较高的使用频率。一般来说,根据业务需求和查询场景,可以选择具有时间、地域、类别等信息的字段作为分区键。例如,对于销售数据的分析,可以选择按照日期作为分区字段,以便实现按照时间范围快速查询数据。对于用户数据的分析,可以选择按照地域或用户类型作为分区字段,以便可以快速按照地域或用户类型进行数据统计。 在选择分区字段时,还需要考虑到分区的数量和数据均衡性。如果分区数量太多,会增加元数据的管理复杂度,并且可能导致查询性能下降;如果分区数量太少,可能导致数据不均匀分布,影响查询性能。 总之,Hive分区字段的选择需要综合考虑业务需求、查询频率、数据特点和性能等因素,灵活选取适合的字段来作为分区键。 ### 回答3: Hive分区字段的选择需要遵循一定的规则和原则,而不能随意取。分区字段的选择应当根据数据的特点和业务需求进行合理的设计。 首先,分区字段应当选择能够更有效地提高查询性能和数据过滤能力的字段。通常情况下,我们会选择与业务关联程度较高、查询频率较高的字段作为分区字段,以便在查询过程中能够通过精确的条件过滤减少不必要的数据扫描和计算,提高查询效率。 其次,分区字段应当选择具备较好的可扩展性和可维护性的字段。在设计分区字段时,需要考虑数据的数量、增长趋势以及数据层次结构。选择合适的字段可以确保数据的划分更加均匀,减少数据倾斜和数据倒挤的问题,避免因为数据量过大而导致查询性能下降或分区管理困难。 最后,分区字段的选择应当符合分区命名的规范。分区字段的命名应尽量遵循规范和易于理解,以方便管理和维护。推荐使用具有明确意义和易于识别的字段命名方式,如日期、地域、类别等。 总之,Hive分区字段的选择应当遵循合理性、可扩展性和规范性原则,并根据具体的业务需求进行设计,以优化查询性能和提高分区的管理效率。因此,分区字段的选择并不是随意的,而是需要经过合理的考量和设计的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值