hive查看存储格式
❶ hive存储parquet表
parquet格式的表在生产环境中经常被使用到,具有列式存储和压缩等特点,我们怎么在hive中存储parquet格式的表呢。
这里使用oracle的emp表
加载本地数据到hive表
执行查询
发现报错
emp使用parquet格式存储,其中imputFormat和outputFormat都是parquet的相关的,也前册就是我的imputFormat是parquent的,但是你传过来的是text,我不认识
我们看一下emp的相关信息,可以看到这里的都是parquet的format的,这是导致这次错误的原因。
这就导致了我们需要每次都先把text文件转化为parquet的文件,然后parquent表进行加载才可以,下面介绍官方推荐的使用方法。
查看emp_tmp的表的信息,这里可以看到,默认的是TextImputFormat和TextOutputFormat的。
然后加载数据到emp_tmp,查看数据,是正常显示的
然后现在把之前的emp里面的数据给删除
然后把emp_tmp表里面的数据加载到emp
查询一下,数据滑谈正常显示,这个方式使用起来还行,就是每次都需要对临时表进行操作,还是比较麻烦的。
感觉这个问题是经常出现,为什么会这样呢。这个和hive的版本有一定的关系。
可以看出hive官方将inputformat和outputformat进行了整合,这样使信悔碰用起来也是比较方便的。
但是可能有人想,那我修改inputformat不就行了,下面我介绍一下,看是否可以
创建emp2表,是parquet的存储格式的
修改inputformat 和serde,这里inputFormat是TextInputFormat,SEDE使用的是LazySimpleSerDe,Outputformat任然是Parquet的,这里需要带上。
查看emp2表的信息,如下图表示修改成功
加载数据到emp2
查询数据,执行成功
到这里,修改inputformat和serde的方法也介绍完成了,我们以为成功了,但是上hdfs上一看,文件还是txt格式的,所以通过修改inputformat和serde的方法不行。
肯定有人想使用这个方法
这个方法我也尝试了,但是返回的值全都是null
在仅仅使用hive的时候,如果想把txt文件里面的数据保存到parquet表里面的话,可以使用建立临时表的方法,这个方法也是比较好操作的。
但是其实如果使用spark,flink等分布式计算引擎的话,是可以直接的读取txt数据保存到parquet表里面的,框架帮我们做了转化。这种方式也是我们在工作中经常使用的。
上面也介绍了修改inputformat和ser的方式,秀给inputformat是可以让txt文件里面的数据被读进来的,如果同时还修改了serde为lazysimpleserde的话,这个是把数据保存为text格式的,已经完全和parquet没有关系了,保存的文件还是txt格式的。仅修改inputformat,但是使用的serde是parquet的,但是数据进出不一致,也是有问题的。
❷ Hive优化之Hive的配置参数优化
Hive是大数据领域常用的组件之一,主要用于大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的一个点,因此掌握一些Hive调优是必不可少的一项技能。影响Hive效率的主要因素有数据倾斜、数据冗余、job的IO以及不同底层引擎配置情况和Hive本身参数和HiveSQL的执行等。本文主要从建表配置参数方面对Hive优化进行讲解。
1. 创建一个普通表
table test_user1(id int, name string,code string,code_id string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
2. 查看这张表的信息
DESCRIBE FORMATTED test_user1;
我们从该表的描述信息介绍建表时的一些可优化点。
2.1 表的文件数
numFiles表示表中含有的文件数,当文件数过多时可能意味着该表的小文件过多,这时候我们可以针对小文件的问题进行一些优化,HDFS本身提供了解决方案:
(1)Hadoop Archive/HAR:将小文件打包成大文件。
(2)SEQUENCEFILE格式:将大量小文件压缩成一个SEQUENCEFILE文件。
(3)CombineFileInputFormat:在map和rece处理之前组合小文件。
(4)HDFS Federation:HDFS联盟,使用多个namenode节点管理文件。
除此之外,我们还可以通过设置hive的参数来合并小文件。
(1)输入阶段合并
需要更改Hive的输入文件格式,即参数hive.input.format,默认值是org.apache.hadoop.hive.ql.io.HiveInputFormat,我们改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。这样比起上面对mapper数的调整,会多出两个参数,分别是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含义是单节点和单机架上的最小split大小。如果发现有split大小小于这两个值(默认都是100MB),则会进行合并。具体逻辑可以参看Hive源码中的对应类。
(2)输出阶段合并
直接将hive.merge.mapfiles和hive.merge.mapredfiles都设为true即可,前者表示将map-only任务的输出合并,后者表示将map-rece任务的输出合并,Hive会额外启动一个mr作业将输出的小文件合并成大文件。另外,hive.merge.size.per.task可以指定每个task输出后合并文件大小的期望值,hive.merge.size.smallfiles.avgsize可以指定所有输出文件大小的均值阈值,默认值都是1GB。如果平均大小不足的话,就会另外启动一个任务来进行合并。
2.2 表的存储格式
通过InputFormat和OutputFormat可以看出表的存储格式是TEXT类型,Hive支持TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文件格式,可以通过两种方式指定表的文件格式:
(1)CREATE TABLE ... STORE AS <file_format>:在建表时指定文件格式,默认是TEXTFILE
(2)ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <file_format>:修改具体表的文件格式
如果要改变创建表的默认文件格式,可以使用set
hive.default.fileformat=<file_format>进行配置,适用于所有表。同时也可以使用set
hive.default.fileformat.managed = <file_format>进行配置,仅适用于内部表或外部表。
扩展:不同存储方式的情况
TEXT,
SEQUENCE和
AVRO文件是面向行的文件存储格式,不是最佳的文件格式,因为即便只查询一列数据,使用这些存储格式的表也需要读取完整的一行数据。另一方面,面向列的存储格式(RCFILE,
ORC, PARQUET)可以很好地解决上面的问题。关于每种文件格式的说明,如下:
(1)TEXTFILE
创建表时的默认文件格式,数据被存储成文本格式。文本文件可以被分割和并行处理,也可以使用压缩,比如GZip、LZO或者Snappy。然而大部分的压缩文件不支持分割和并行处理,会造成一个作业只有一个mapper去处理数据,使用压缩的文本文件要确保文件不要过大,一般接近两个HDFS块的大小。
(2)SEQUENCEFILE
key/value对的二进制存储格式,sequence文件的优势是比文本格式更好压缩,sequence文件可以被压缩成块级别的记录,块级别的压缩是一个很好的压缩比例。如果使用块压缩,需要使用下面的配置:set
hive.exec.compress.output=true; set io.seqfile.compression.type=BLOCK
(3)AVRO
二进制格式文件,除此之外,avro也是一个序列化和反序列化的框架。avro提供了具体的数据schema。
(4)RCFILE
全称是Record Columnar File,首先将表分为几个行组,对每个行组内的数据进行按列存储,每一列的数据都是分开存储,即先水平划分,再垂直划分。
(5)ORC
全称是Optimized Row Columnar,从hive0.11版本开始支持,ORC格式是RCFILE格式的一种优化的格式,提供了更大的默认块(256M)
(6)PARQUET
另外一种列式存储的文件格式,与ORC非常类似,与ORC相比,Parquet格式支持的生态更广,比如低版本的impala不支持ORC格式。
配置同样数据同样字段的两张表,以常见的TEXT行存储和ORC列存储两种存储方式为例,对比执行速度。
TEXT存储方式
总结: 从上图中可以看出列存储在对指定列进行查询时,速度更快, 建议在建表时设置列存储的存储方式 。
2.3 表的压缩
对Hive表进行压缩是常见的优化手段,一些存储方式自带压缩选择,比如SEQUENCEFILE支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩;
ORC支持三种压缩选择:NONE,ZLIB,SNAPPY。我们以TEXT存储方式和ORC存储方式为例,查看表的压缩情况。
配置同样数据同样字段的四张表,一张TEXT存储方式,另外三张分别是默认压缩方式的ORC存储、SNAPPY压缩方式的ORC存储和NONE压缩方式的ORC存储,查看在hdfs上的存储情况:
TEXT存储方式
默认压缩ORC存储方式
SNAPPY压缩的ORC存储方式
NONE压缩的ORC存储方式
总结 :可以看到ORC存储方式将数据存放为两个block,默认压缩大小加起来134.69M,SNAPPY压缩大小加起来196.67M,NONE压缩大小加起来247.55M,TEXT存储方式的文件大小为366.58M,且默认block两种存储方式分别为256M和128M,ORC默认的压缩方式比SNAPPY压缩得到的文件还小,原因是ORZ默认的ZLIB压缩方式采用的是deflate压缩算法,比Snappy压缩算法得到的压缩比高,压缩的文件更小。 ORC不同压缩方式之间的执行速度,经过多次测试发现三种压缩方式的执行速度差不多,所以建议采用ORC默认的存储方式进行存储数据。
2.4 分桶分区
Num Buckets表示桶的数量,我们可以通过分桶和分区操作对Hive表进行优化:
对于一张较大的表,可以将它设计成分区表,如果不设置成分区表,数据是全盘扫描的,设置成分区表后,查询时只在指定的分区中进行数据扫描,提升查询效率。要注意尽量避免多级分区,一般二级分区足够使用。常见的分区字段:
(1)日期或者时间,比如year、month、day或者hour,当表中存在时间或者日期字段时,可以使用些字段。
(2)地理位置,比如国家、省份、城市等
(3)业务逻辑,比如部门、销售区域、客户等等
与分区表类似,分桶表的组织方式是将HDFS上的一张大表文件分割成多个文件。分桶是相对分区进行更细粒度的划分,分桶将整个数据内容按照分桶字段属性值得hash值进行区分,分桶可以加快数据采样,也可以提升join的性能(join的字段是分桶字段),因为分桶可以确保某个key对应的数据在一个特定的桶内(文件),所以巧妙地选择分桶字段可以大幅度提升join的性能。通常情况下,分桶字段可以选择经常用在过滤操作或者join操作的字段。
创建分桶表
create
table test_user_bucket(id int, name string,code string,code_id string )
clustered by(id) into 3 buckets ROW FORMAT DELIMITED FIELDS TERMINATED
BY ',';
查看描述信息
DESCRIBE FORMATTED test_user_bucket
多出了如下信息
查看该表的hdfs
同样的数据查看普通表和分桶表查询效率
普通表
分桶表
普通表是全表扫描,分桶表在按照分桶字段的hash值分桶后,根据join字段或者where过滤字段在特定的桶中进行扫描,效率提升。
本文首发于: 数栈研习社
数栈是云原生—站式数据中台PaaS,我们在github上有一个有趣的开源项目: FlinkX
FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,比如MySQL,HDFS等,也可以采集实时变化的数据,比如MySQL
binlog,Kafka等,是全域、异构、批流一体的数据同步引擎,大家如果有兴趣,欢迎来github社区找我们玩~
❸ 【大数据-数仓】HIVE下的文件存储遇到的一个问题(TEXTFILE、RCFILE)
问题:
Failed with exception Wrong file format. Please check the file's format.
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.MoveTask
解决:
当遇到这个肆激问题时,可以肯定一点的是,文件的格式和建表时指定的存储格式是不一致的。
由此可以定位到问题出在纳雹宴哪里了。
1.确定数洞银据源的格式:
一般都是txt/csv文件
2.确定建表时指定的存储格式
show create table table_name;
然后查看:
STORED AS INPUTFORMAT #指定的存储格式
3.重新建表并修改指定的存储格式
❹ Hive支持的数据类型
#整型
TINYINT — 微整型,只占用1个字节,只能存储0-255的整数。
SMALLINT– 小整型液卖,占用2个字节,存储范围–32768 到 32767。
INT– 整型,占用4个字节,存储范围-2147483648到2147483647。
BIGINT– 长整型,占用8个字节,存储范围-2^63到2^63-1。
#布尔型
BOOLEAN — TRUE/FALSE
#浮点型
FLOAT– 单精度浮点数。
DOUBLE– 双精度浮点数。
#字符串型
STRING– 不设定长度。
Structs:一组由任意数据类型组成的结构。比如,定义一个字段C的类型为STRUCT {a INT; b STRING},则可以使用a和C.b来获取其中的元素值;
Maps:和Java中的Map相同,即存储K-V对的;
Arrays:数组;
复杂数据类型的声明必须使用尖括号指明其中数肢颤据字段的类型。定义三列,每列对应一种复杂的数据类型,如下所示。
TEXTFILE //文本,默认值
SEQUENCEFILE // 二进制序列文件
RCFILE //列式存储格式文件 Hive0.6以后开始支历埋败持
ORC //列式存储格式文件,比RCFILE有更高的压缩比和读写效率,Hive0.11以后开始支持
PARQUET //列出存储格式文件,Hive0.13以后开始支持
#参考博客:
http://lxw1234.com/archives/2015/06/238.htm
http://www.cnblogs.com/zlslch/p/5659714.html
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
#
❺ hive的数据存储
首先,Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。
其次,Hive 中所有的数据都存储在 HDFS 中,Hive 中包含以下数据模型:表(Table),外部表(External Table),分区(Partition),桶(Bucket)。
Hive 中的 Table 和数据库中的 Table 在概念上是类似的,每一个 Table 在 Hive 中都有一个相应的目录存储数据。例如,一个表 pvs,它在 HDFS 中的路径为:/wh/pvs,其中,wh 是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的数据仓库的目录,所有的 Table 数据(不包括 External Table)都保存在这个目录中。
Partition 对应于数据库中的 Partition 列的密集索引,但是 Hive 中 Partition 的组织方式和数据库中的很不相同。在 Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中。例如:pvs 表中包含 ds 和 city 两个 Partition,则对应于 ds = 20090801, ctry = US 的 HDFS 子目录为:/wh/pvs/ds=20090801/ctry=US;对应于 ds = 20090801, ctry = CA 的 HDFS 子目录为;/wh/pvs/ds=20090801/ctry=CA
Buckets 对指定列计算 hash,根据 hash 值切分数据,目的是为了并行,每一个 Bucket 对应一个文件。将 user 列分散至 32 个 bucket,首先对 user 列的值计算 hash,对应 hash 值为 0 的 HDFS 目录为:/wh/pvs/ds=20090801/ctry=US/part-00000;hash 值为 20 的 HDFS 目录为:/wh/pvs/ds=20090801/ctry=US/part-00020
External Table 指向已经在 HDFS 中存在的数据,可以创建 Partition。它和 Table 在元数据的组织上是相同的,而实际数据的存储则有较大的差异。
Table 的创建过程和数据加载过程(这两个过程可以在同一个语句中完成),在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。 External Table 只有一个过程,加载数据和创建表同时完成(CREATE EXTERNAL TABLE ……LOCATION),实际数据是存储在 LOCATION 后面指定的 HDFS 路径中,并不会移动到数据仓库目录中。当删除一个 External Table 时,仅删除元数据,表中的数据不会真正被删除。