Hive-存储-文件格式

一、前言

数据存储是Hive的基础,选择合适的底层数据存储格式,可以在不改变Hql的前提下得到大的性能提升。类似mysql选择适合场景的存储引擎。

Hive支持的存储格式有

        文本格式(TextFile)

        二进制序列化文件 (SequenceFile)

        行列式文件(RCFile)

        优化的行列式文件(ORCFile)

        Apache Parquet

其中,ORCFile和Apache Parquet,以其高效的数据存储和数据处理性能得以在实际的生产环境中大量运用。

创建表时可以使用 row format 参数说明SerDe(Serializer/Deserializer 序列化和反序列化的类型

二、文本格式(TextFile

Hive的默认格式,数据不做压缩,可以直接使用命令查看,磁盘开销大,数据解析开销大。可以使用Gzip、Bzip2进行压缩,Hive会自动进行解压解析。但是压缩后的文件不在进行分割,一个压缩文件只能由一个Mapper任务处理。且需要解压缩后一个一个字符读取判断是否是换行符。一般不对TextFile进行压缩。

TextFile文件可以直接使用load方式加载数据,其它格式则不能使用load直接导入数据,因为需要借助mapreduce的压缩方式实现。所以TextFile的加载速度是最高的。

三、二进制序列化文件 (SequenceFile)

SequenceFile是HadoopAPI提供的一种二进制文件支持 

源码类:org.apache.hadoop.io.SequenceFile


/** * SequenceFiles是由二进制键/值*对组成的平面文件* * SequenceFile提供了{@link SequenceFile.Writer},{@link SequenceFile.Reader}和 *{@link-Sorter}类用于写入、分别读取和排序。* * 基于用于压缩键/值对的压缩类型,有三种写的方式*   1、Writer : 不压缩*   2、记录压缩Writer : 记录压缩的文件,仅压缩值*   3、块压缩Writer : Block-compressed 文件, 键和值都收集在“块”中:分别压缩。“块”的大小是*      可配置的。* * 用于压缩键和/或值的实际压缩算法可以通过使用适当的{@link CompressionCodec}来指定* * 建议使用静态 createWriter 方法。由SequenceFile提供,以选择首选格式* * SequenceFile.Reader充当桥接器,可以读取上述SequenceFile格式中的任何一种** SequenceFile 格式化* * 本质上,SequenceFile 有三种不同的格式取决于指定的 CompressionType。它们都共享下面描述的 * 公共标* SequenceFile 头文件*   version - 3个字节的魔术头SEQ,后面跟着1个字节的实际版本号(例如SEQ4或SEQ6)*   keyClassName -key class*   valueClassName - value class*   compression - 一个布尔值,用于指定是否对此文件中的键/值启用压缩。*   blockCompression - 一个布尔值,用于指定是否为此文件中的键/值启用块压缩。*   compression codec - CompressionCodec 类,用于压缩键和/或值(如果启用了压缩)*   metadata - 该二进制文件的元数据(文件的元数据是Text类型的属性名称/值对的列表)*   sync - 一种同步标记,用于表示标头的末尾。* * 未压缩的 SequenceFile * 记录*     Record length*     Key length*     Key*     Value* 每隔100千字节(100M)左右一个同步标记.** 行压缩的 SequenceFile * 记录*     Record length*     Key length*     Key (key不压缩)*     Compressed Value* 每隔100千字节(100M)左右一个同步标记.* * 块压缩的 SequenceFile * 记录 Block*     Uncompressed number of records in the block  块中未压缩的记录数*     Compressed key-lengths block-size  压缩 key 长度块大小*     Compressed key-lengths block  压缩 key 长度块*     Compressed keys block-size  压缩 keys 块大小*     Compressed keys block  压缩 keys 块*     Compressed value-lengths block-size  压缩 value 长度块大小*     Compressed value-lengths block  压缩 value 长度块*     Compressed values block-size  压缩 value 块大小*     Compressed values block  压缩 value 块* 每个块都有一个同步标记* * 密钥长度和值长度的压缩块由以ZeroCompressedInteger格式编码的单个密钥/值的实际长度组成* * @see CompressionCodec*/
@InterfaceAudience.Public
@InterfaceStability.Stable
public class SequenceFile {//......省略......
}

使用Hive提供的标准二进制格式:

CREATE TABLE binary_table(id INT,......
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS sequencefile;

也可以使用自定义的格式处理

ADD JAR /path/my-serde.jar;CREATE TABLE binary_table(id INT,name STRING,data BINARY
)
ROW FORMAT SERDE 'MyBinarySerDe'
STORED ASINPUTFORMAT 'org.apache.hadoop.mapred.SequenceFileInputFormat'OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat';

设置压缩格式为块压缩:

set mapred.output.compression.type=BLOCK;

优点:

        支持基于记录(Record)或块(Block)的数据压缩

        支持Mapper任务的分片

缺点:

        合并文件需要过程,且不方便查看数据

四、行列式文件(RCFile)

源码类:org.apache.hadoop.hive.ql.io.RCFile

/*** RCFiles是Record Columnar File的缩写,是由二进制键/值对组成的平面文件,* 与SequenceFile非常相似** RCFile以记录列的方式存储表的列。它首先将行水平划分为行拆分。* 然后它垂直地划分以柱状方式分割的每一行。* RCFile首先将行拆分的元数据存储为记录的关键部分,将行拆分后的所有数据存储为值部分。* 写入时,RCFile.Writer首先将记录的值字节保存在内存中,* 并在缓冲记录的原始字节大小溢出给定参数(Writer.columnsBufferSize)时确定行拆分* 该参数可以设置为:conf.setInt(COLUMNS_BUFFER_SIZE_CONF_STR,4*1024*1024)* * RCFile分别提供了{@link Writer}、{@link Reader}和用于写入和读取的类** * RCFile以记录列的方式存储表的列。它首先将行水平划分为行拆分。* 然后它垂直地划分以柱状方式分割的每一行。* RCFile首先将行拆分的元数据存储为记录的关键部分,将行拆分后的所有数据存储为值部分** RCFile以比记录级压缩更细粒度的方式压缩值。然而,它目前还不支持压缩 key。* 用于压缩键和/或值的实际压缩算法可以通过使用适当的{@link CompressionCodec}来指定。* * {@link Reader}用于读取和解释RCFile的字节数。* ** RCFile Formats** RC Header*     version - 3字节的魔术头(RCF) + 1个字节的实际版本号 (例如:RCF1)*     compression - 一个布尔值,用于指定是否对此文件中的keys/values启用压缩*     compression codec - 如果开启压缩,使用CompressionCodec 类来对 keys/values 进行压缩*     metadata - 元数据*     sync - 表示标头末尾的同步标记** RCFile Format*     Header*         Record*         Key part*             记录长度(字节)*             Key 长度(字节)*             这条记录中的行号vint)*             Column_1_在磁盘中的长度(vint)*             Column_1_row_1 值的绝对长度*             Column_1_row_2_值的绝对长度*             ...*             Column_2_在磁盘中的长度(vint)*             Column_2_row_1_值的绝对长度*             Column_2_row_2_值的绝对长度*             ...*         Value part*             压缩或原始的列数据 [column_1_row_1_value,column_1_row_2_value,....]*             压缩或原始的列数据 [column_2_row_1_value,column_2_row_2_value,....]* * 以下是RCFile的伪BNF语法. 注释以破折号为前缀** rcfile ::=*   <file-header>*   <rcfile-rowgroup>+** file-header ::=*   <file-version-header>*   <file-key-class-name>              (only exists if version is seq6)*   <file-value-class-name>            (only exists if version is seq6)*   <file-is-compressed>*   <file-is-block-compressed>         (only exists if version is seq6)*   [<file-compression-codec-class>]*   <file-header-metadata>*   <file-sync-field>** -- Hive中包含的标准RCFile实现实际上是基于Hadoop的SequenceFile代码的修改版本。* -- 有些本应修改的内容没有修改,包括写出文件版本头的代码。* -- 因此,RCFile和SequenceFile最初共享相同的版本头。较新版本创建了一个唯一的版本字符串。** file-version-header ::= Byte[4] {'S', 'E', 'Q', 6}*                     |   Byte[4] {'R', 'C', 'F', 1}** -- 负责读取行组的 key 缓冲区组件的Java类的名称。** file-key-class-name ::=*   Text {"org.apache.hadoop.hive.ql.io.RCFile$KeyBuffer"}** -- 负责读取行组的 value 缓冲区组件的Java类的名称。** file-value-class-name ::=*   Text {"org.apache.hadoop.hive.ql.io.RCFile$ValueBuffer"}** -- 布尔变量,指示文件是否对 key  缓冲区和 column  缓冲区部分使用压缩。** file-is-compressed ::= Byte[1]** -- 一个布尔字段,指示文件是否被块压缩。此字段始终为false。* 根据原始RCFile实现中的注释,保留该字段是为了与SequenceFile格式向后兼容。** file-is-block-compressed ::= Byte[1] {false}** -- 压缩编解码器的Java类名* -- 如果是 true. 那么类必须实现 org.apache.hadoop.io.compress.CompressionCodec.* -- 最好是 org.apache.hadoop.io.compress.GzipCodec.** file-compression-codec-class ::= Text** -- 定义文件元数据值的键值对的集合。Map使用标准JDK序列化进行序列化,* -- 即对应于键值对数量的Int,后面是Text键值对。以下元数据属性对于所有RC文件都是强制性的:* --* -- hive.io.rcfile.column.number: RCFile中的列数** file-header-metadata ::= Map<Text, Text>** -- 由写入程序生成的16字节标记。此标记以规则的间隔出现在行组标头的开头,* -- 用于使读取器能够跳过损坏的行组。** file-sync-hash ::= Byte[16]** -- 每个行组分为三个部分:* -- 一个头、一组 key 缓冲区和一组 列 缓冲区。* -- 标头部分包括一个可选的同步哈希、有关行组大小的信息以及行组中的总行数。* -- 每个 key 缓冲区由 RLE (run-length encoding 游程编码) 数据组成,* -- 该数据用于解码相应 列 缓冲区中各个字段的长度和偏移量。** rcfile-rowgroup ::=*   <rowgroup-header>*   <rowgroup-key-data>*   <rowgroup-column-buffers>** rowgroup-header ::=*   [<rowgroup-sync-marker>, <rowgroup-sync-hash>]*   <rowgroup-record-length>*   <rowgroup-key-length>*   <rowgroup-compressed-key-length>** -- rowgroup-key-data 如果列数据被压缩,则被压缩。* rowgroup-key-data ::=*   <rowgroup-num-rows>*   <rowgroup-key-buffers>** -- 一个整数(总是-1),表示同步哈希字段的开始** rowgroup-sync-marker ::= Int** -- 一个16字节的同步字段。这必须与文件头中读取的<file sync hash>值相匹配。** rowgroup-sync-hash ::= Byte[16]** -- 记录长度是用于存储 key 和 column  部分的字节数之和,即当前行组的总长度** rowgroup-record-length ::= Int** -- 行组的 key 的总长度(以字节为单位)** rowgroup-key-length ::= Int** -- 行组的 key 的压缩总长度(以字节为单位)。** rowgroup-compressed-key-length ::= Int** -- 当前行组中的行数。** rowgroup-num-rows ::= VInt** -- 与RCFile中的每一列相对应的一个或多个列的 key 缓冲区。** rowgroup-key-buffers ::= <rowgroup-key-buffer>+** -- 每个 column 缓冲区中的数据使用 RLC 方案来存储,* -- 该方案旨在降低重复列字段值的成本。以下条目将更详细地描述这种机制。** rowgroup-key-buffer ::=*   <column-buffer-length>*   <column-buffer-uncompressed-length>*   <column-key-buffer-length>*   <column-key-buffer>** -- 磁盘上相应列缓冲区的序列化长度。.** column-buffer-length ::= VInt** -- 相应列缓冲区的未压缩长度。如果未压缩RCFile,这相当于列缓冲区长度。** column-buffer-uncompressed-length ::= VInt** -- 当前列 key 缓冲区的长度(以字节为单位)** column-key-buffer-length ::= VInt** -- column-key-buffer 包含与对应行组列缓冲区中的序列化列字段的字节长度* -- 相对应的序列化VInt值序列。* -- 例如,考虑一个包含连续值1、2、3、44的整数列。* -- RCFile格式将这些值作为字符串存储在列缓冲区中,例如“12344”。* -- 每个列字段的长度记录在 column-key-buffer  中,作为VInts:1,1,1,2的序列。* -- 然而,如果相同的长度重复出现,那么我们将重复的游程长度替换为重复次数的补码(即负),* -- 因此1,1,1,2变为1,~2,2。** column-key-buffer ::= Byte[column-key-buffer-length]** rowgroup-column-buffers ::= <rowgroup-value-buffer>+** -- RCFile将所有列数据存储为字符串,而与基础列类型无关。* -- 字符串既不是以长度为前缀的,也不是以null结尾的,* -- 将它们解码为单独的字段需要使用相应  column-key-buffer. 中包含的游程长度信息。** rowgroup-column-buffer ::= Byte[column-buffer-length]** Byte ::= An eight-bit byte** VInt ::= 可变长度整数。每个字节的高阶位指示是否还有更多字节需要读取。* 低阶七位被附加为所得整数值中越来越高的有效位。** Int ::= big-endian格式的四字节整数。** Text ::= VInt, Chars (前缀为UTF-8字符的长度)*/
public class RCFile {//......省略......
}

五、 优化的行列式文件(ORCFile)

1、概览

        诞生时间:2013年1月

        目的:加速Hive和Hadoop数据处理速度,减少文件大小。例如Facebook使用了ORC为其减少了10PB的存储空间

        ORC是Apache顶级项目

        存储格式:二进制,不可直接读、自描述特性(本身存储有文件数据、数据类型、编码信息)不依赖Hive的metastore

        官网:Apache ORC • High-Performance Columnar Storage for Hadoop

        功能:支持ACID、内置索引、支持Hive所有类型

        说明:更准确的标题应该是HDFS的文件格式,因为ORC可以用于MapReduce、Hive、Spark、Flink等等,只是本文章主要讲在Hive中的使用,因此这里这样命名

2、ORC文件结构

ORC文件是一个行列式存储结构

ORC文件结构由三部分组成:条带(stripe)、·文件脚注(file footer)和 postscript

        条带(stripe):ORC文件存储数据的地方

        文件脚注(file footer):包含了文件中stripe的列表,每个stripe的行 数,以及每个列的

                        数据类型。它还包含每个列的最小值、最大值、行计数、 求和等聚合信息

        postscript:含有压缩参数和压缩大小相关的信息

stripe结构同样可以分为三部分:index data、rows data和stripe footer

         index data:保存了所在条带的一些统计信息,以及数据在stripe中的位置索引信息

         rows data:数据存储的地方,由多个行组构成,数据以流(stream)的形式进行存储

                            数据分多个 rows group 存放,每个rows group 存储两部分的数据,即:

                                metadata stream:用于描述每个行组的元数据信息

                                data stream:存储数据的地方

         stripe footer:保存数据所在的文件目录

        

        综上所述,orc在每个文件中提供了3个级别的索引

        文件级:记录文件中所有stripe的位置信息,以及文件中存储的每列数据的统计信息

        条带级:记录每个stripe所存储的数据统计信息

        行组级:在stripe中,每10000行构成一个组,该级索引记录这个行组中存储数据的统计信息

3、源码查看

源码类:org.apache.hadoop.hive.ql.io.orc.OrcFile

父类:org.apache.orc.OrcFile

package org.apache.orc;import java.io.*;
import java.nio.*;
import java.util.*;
import org.apache.hadoop.*;
import org.apache.orc.impl.*;/***包含读取或写入ORC文件的工厂方法。
*/public class OrcFile {//ORC文件的魔数为 "ORC"public static final String MAGIC = "ORC";public enum Version {V_0_11("0.11", 0, 11),V_0_12("0.12", 0, 12),UNSTABLE_PRE_2_0("UNSTABLE-PRE-2.0", 1, 9999),//所有未知版本的通用标识符。FUTURE("future", Integer.MAX_VALUE, Integer.MAX_VALUE);//当前版本public static final Version CURRENT = V_0_12;//.......省略......}//可以看出 ORC 是支持 Java 、C++ 、Presto 、Go 的public enum WriterImplementation {ORC_JAVA(0), // ORC Java writerORC_CPP(1),  // ORC C++ writerPRESTO(2),   // Presto writerSCRITCHLEY_GO(3), // Go writer from https://github.com/scritchley/orcUNKNOWN(Integer.MAX_VALUE);//.......省略......}//记录已修复错误的编写器版本。当您修复了编写器中没有更改文件格式的错误//(或进行了实质性更改)时,请在此处添加一个新版本,而不是version。//每个WriterImplementation从6开始按顺序分配id,//以便ORC-202之前的读取器正确对待其他写入程序。public enum WriterVersion {// Java ORC WriterORIGINAL(WriterImplementation.ORC_JAVA, 0),//固定条带/文件最大统计信息&字符串统计信息使用utf8表示最小值/最大值HIVE_8732(WriterImplementation.ORC_JAVA, 1),//使用 Hive 表中的实际列名HIVE_4243(WriterImplementation.ORC_JAVA, 2),//矢量化写入器HIVE_12055(WriterImplementation.ORC_JAVA, 3), //小数正确写入当前流HIVE_13083(WriterImplementation.ORC_JAVA, 4),//bloom 过滤器使用utf8ORC_101(WriterImplementation.ORC_JAVA, 5),//时间戳统计使用utcORC_135(WriterImplementation.ORC_JAVA, 6),//decimal64 min/max是固定的ORC_517(WriterImplementation.ORC_JAVA, 7), //C++ ORC WriterORC_CPP_ORIGINAL(WriterImplementation.ORC_CPP, 6),// Presto WriterPRESTO_ORIGINAL(WriterImplementation.PRESTO, 6),// Scritchley Go WriterSCRITCHLEY_GO_ORIGINAL(WriterImplementation.SCRITCHLEY_GO, 6),// 除了以下数字外,不要在此处使用任何幻数://除了以下数字外,不要在此处使用任何幻数://来自未来的版本FUTURE(WriterImplementation.UNKNOWN, Integer.MAX_VALUE); //.......省略......}//当前版本的WriterVersion。public static final WriterVersion CURRENT_WRITER = WriterVersion.ORC_517;//编码策略 public enum EncodingStrategy {SPEED, COMPRESSION}//压缩策略public enum CompressionStrategy {SPEED, COMPRESSION}//用于创建ORC文件读取器的选项。public static class ReaderOptions {//.......省略......}public static Reader createReader(Path path,ReaderOptions options) throws IOException {return new ReaderImpl(path, options);}public interface WriterContext {Writer getWriter();}public interface WriterCallback {void preStripeWrite(WriterContext context) throws IOException;void preFooterWrite(WriterContext context) throws IOException;}public enum BloomFilterVersion {}//用于创建ORC文件编写器的选项。public static class WriterOptions implements Cloneable {//.......省略......}//创建一个ORC文件编写器。这是用于创建编写器的公共接口,新选项只会添加到该方法中。public static Writer createWriter(Path path,WriterOptions opts) throws IOException {//.......省略......}//合并所有具有相同架构的多个ORC文件以生成单个ORC文件。//合并将拒绝与合并文件不兼容的文件,因此输出列表可能比输入列表短。//条带被复制为串行字节缓冲区。用户元数据被合并,对与键相关联的值不一致的文件将被拒绝。public static List<Path> mergeFiles(Path outputPath,WriterOptions options,List<Path> inputFiles) throws IOException {//.......省略......}}

六、 Apache Parquet /pɑːrˈkeɪ/

1、概览

        Parquet也是Apache顶级项目

        官网:Parquet (apache.org)

        源码下载地址:Release apache-parquet-format-2.10.0 · apache/parquet-format · GitHub

                (里面又源码和说明文档)

        Parquet也是一种行列式存储结构

        Parquet旨在支持非常高效的压缩和编码方案

        Parquet也同ORC一样记录这些数据的元数据(表结构、行数、列的情况以及偏移量等等)

2、Parquet文件结构

        和ORC一样,数据被分为多个行组,不同的是Parquet把每个列由分为若干个Page

        

        

        

        

        

                

        

七、五种文件格式对比

1、建表

-----textfile格式建表-----
create table test.user_msg_text(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as textfile ;-----sequencefile格式建表-----
create table test.user_msg_sequencefile(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as sequencefile ;-----rcfile格式建表-----
create table test.user_msg_rcfile(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as rcfile ;-----orc格式建表-----
create table test.user_msg_orc(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as orc ;-----parquet格式建表-----
create table test.user_msg_parquet(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as parquet ;

2、制作数据

vi 111.csv 

134xxxx6398,weixin.qq.com,200,6941611,2984

cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
cat 100.csv >> 1000.csv
wc 1000.csv
#1000
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
cat 1000.csv >> 10000.csv
wc 10000.csv
#10000
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
cat 10000.csv >> 100000.csv
wc 100000.csv
#100000
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
cat 100000.csv >> 1000000.csv
wc 1000000.csv
#1000000
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
cat 1000000.csv >> 10000000.csv
wc 10000000.csv
#10000000
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
cat 10000000.csv >> 100000000.csv
wc 100000000.csv
#100000000awk '{printf("%d,%s\n",NR,$0)}' 100000000.csv>> test_data_1y.csv

3、加载数据

load data local inpath '/root/temp/test_data_1y.csv' into table test.user_msg partition(dt='20240627');
Time taken: 38.869 seconds
insert into test.user_msg_sequencefile partition(dt='20240627') select 
id ,telno ,visit_url ,status ,visit_time ,visit_num from test.user_msg_text where dt='20240627' ;
Time taken: 48.752 seconds
insert into test.user_msg_rcfile partition(dt='20240627') select 
id ,telno ,visit_url ,status ,visit_time ,visit_num from test.user_msg_text where dt='20240627' ;
Time taken: 40.362 seconds
insert into test.user_msg_orc partition(dt='20240627') select 
id ,telno ,visit_url ,status ,visit_time ,visit_num from test.user_msg_text where dt='20240627' ;
Time taken: 73.569 seconds
insert into test.user_msg_parquet partition(dt='20240627') select 
id ,telno ,visit_url ,status ,visit_time ,visit_num from test.user_msg_text where dt='20240627' ;
Time taken: 50.563 seconds

4、存储对比

hadoop fs -du -h /user/hive/warehouse/test.db

5、性能对比

select count(1) from test.user_msg_text where dt = '20240627' ;
Time taken: 54.92 seconds, Fetched: 1 row(s)
select count(1) from test.user_msg_sequencefile where dt = '20240627' ;
Time taken: 44.623 seconds, Fetched: 1 row(s)
select count(1) from test.user_msg_rcfile where dt = '20240627' ;
Time taken: 35.356 seconds, Fetched: 1 row(s)
select count(1) from test.user_msg_orc where dt = '20240627' ;
Time taken: 36.07 seconds, Fetched: 1 row(s)
select count(1) from test.user_msg_parquet where dt = '20240627' ;
Time taken: 49.309 seconds, Fetched: 1 row(s)
select sum(visit_num) from test.user_msg_text where dt = '20240627' ;
Time taken: 42.698 seconds, Fetched: 1 row(s)
select sum(visit_num) from test.user_msg_sequencefile where dt = '20240627' ;
Time taken: 45.819 seconds, Fetched: 1 row(s)
select sum(visit_num) from test.user_msg_rcfile where dt = '20240627' ;
Time taken: 39.971 seconds, Fetched: 1 row(s)
select sum(visit_num) from test.user_msg_orc where dt = '20240627' ;
Time taken: 37.584 seconds, Fetched: 1 row(s)
select sum(visit_num) from test.user_msg_parquet where dt = '20240627' ;
Time taken: 45.688 seconds, Fetched: 1 row(s)
select * from test.user_msg_text where dt = '20240627' and id = '999999' ;
Time taken: 31.185 seconds, Fetched: 1 row(s)
select * from test.user_msg_sequencefile where dt = '20240627' and id = '999999' ;
Time taken: 55.459 seconds, Fetched: 1 row(s)
select * from test.user_msg_rcfile where dt = '20240627' and id = '999999' ;
Time taken: 44.476 seconds, Fetched: 1 row(s)
select * from test.user_msg_orc where dt = '20240627' and id = '999999' ;
Time taken: 46.568 seconds, Fetched: 1 row(s)
select * from test.user_msg_parquet where dt = '20240627' and id = '999999' ;
Time taken: 111.57 seconds, Fetched: 1 row(s)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/362122.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2 + dataV 组件问题

在使用 dataV 过程中&#xff0c;遇见 svg 动画不加载问题。 一、理想状态下&#xff1a; 二、开发中遇到的 加载不出来问题。 解决方案 在查找官方资料中&#xff0c;提到使用 key 可以解决方案。 1 绑定 key 2 改变 key 值 注意&#xff1a;一定要在 $nextTick 里面执…

【多线程】线程安全

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 观察线程不安全2. 线程不安全的原因2.1 抢占式执行2.2 修改共享数据2.3 修改操作不是原子的2.4 内存可见性…

【高级篇】分区与分片:MySQL的高级数据管理技术(十三)

引言 在上一章,我们探讨了MySQL的主从复制与高可用性,这是构建健壮数据库架构的基石。现在,让我们深入到更高级的主题——分区与分片,这些技术对于处理大规模数据集和提升数据库性能至关重要。我们将详细介绍表分区的概念、类型及分片技术的应用,为下一章讨论MySQL集群与…

经纬恒润推出面向教育行业的仿真测试实验室

随着汽车行业向电动化和智能化的转型&#xff0c;车辆的智能水平和复杂度不断提升&#xff0c;整车的开发周期却越来越短&#xff0c;测试要求越来越高&#xff0c;自动化测试成为必由之路。作为行业技术创新和引领者&#xff0c;高校面临着新能源和智能驾驶等新技术的众多挑战…

HTML(15)——盒子模型

盒子模型组成 内容区域 -width&height内边距-padding &#xff08;出现在内容与盒子边缘之间&#xff09;边框线-border外边距-margin &#xff08;出现在盒子外面&#xff09; div { width: 200px; height: 200px; background-color: rgb(85, 226, 193); padding: 20px; …

如何降低MCU系统功耗?

大家在做MCU系统开发的时候&#xff0c;是否也碰到过降低MCU系统功耗的需求&#xff1f; MCU系统整板功耗是个综合的数据&#xff0c;包括MCU功耗以及外部器件功耗&#xff0c;在此我们主要介绍如何降低MCU的功耗&#xff1a; 可以在满足应用的前提下&#xff0c;降低MCU的运…

百元蓝牙耳机哪款性价比高?盘点性价比高的百元蓝牙耳机品牌

在如今快节奏的生活中&#xff0c;蓝牙耳机已经成为人们日常生活中不可或缺的配件。然而&#xff0c;市面上百元左右性价比高的蓝牙耳机琳琅满目&#xff0c;消费者往往难以选择到一款质量好、耐用的产品。我们希望可以为广大消费者提供一些参考和建议&#xff0c;接下来&#…

KVM网络模式设置

一、KVM网络模式介绍 1、NAT ( 默认上网 ) 虚拟机利用host机器的ip进行上网,对外显示一个ip;virbr0是KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供NAT访问外网的功能,默认ip为192.168.122.1 2、自带的Bridge 将虚拟机桥接到host机器的网卡上,vm和ho…

vue 实现 word/excel/ppt/pdf 等文件格式预览操作

效果图&#xff1a; 问题描述&#xff1a;一般情况下使用iframe标签就可以实现文件预览&#xff0c;但是这个标签只针对于ppt和pdf是有效的。对于doc文件就需要借助第三方插件&#xff08;vue-office/docx&#xff09;来实现预览了。下面介绍使用方法。 安装插件&#xff1a;n…

云通SIPX,您的码号资源智能调度专家!

在数字化转型的浪潮中&#xff0c;号码资源作为企业与客户沟通的重要桥梁&#xff0c;其管理效率直接关系到企业运营的成败。随着运营商对号码资源管理的规范化和精细化&#xff0c;企业对高效、智能的号码资源管理需求日益增长&#xff0c;以实现对外呼叫的降本增效。 一、什么…

教程:LVM操作讲解

LVM简介 在系统运维过程中&#xff0c;对磁盘扩缩容是常见的操作。如何高效的管理磁盘容量&#xff0c;lvm提供了很好的解决方案。 LVM将磁盘抽象成PV、VG、LV&#xff0c;方便用户进行磁盘管理&#xff0c;简单来讲&#xff0c;是由物理磁盘划分成PV&#xff0c;PV加入到具体…

【AI大模型RAG】深入探索检索增强生成(RAG)技术

目录 1. 引言2. RAG技术概述2.1 RAG技术的定义2.2 RAG技术的工作原理2.3 RAG技术的优势2.4 RAG技术的应用场景 3. RAG的工作流程3.1 输入处理3.2 索引建立3.3 信息检索3.4 文档生成3.5 融合与优化 4. RAG范式的演变4.1 初级 RAG 模型4.2 高级 RAG 模型4.3 模块化 RAG 模型优化技…

HBase:大数据时代的分布式存储利器

HBase&#xff1a;大数据时代的分布式存储利器 HBase&#xff1a;大数据时代的分布式存储利器1. HBase简介2. HBase特点3. HBase应用场景4. 总结 HBase&#xff1a;大数据时代的分布式存储利器 随着互联网和大数据技术的飞速发展&#xff0c;数据存储和计算需求呈现出爆炸式增…

el-select多选超过两个选项省略

前言 相信大家都遇到过这种情况&#xff1a;Element下拉框多选的时候有个毛病&#xff0c;就是选的数量过多就会把下拉框撑高&#xff0c;从而影响布局&#xff1b;但是如果使用了里面collapse-tags属性&#xff0c;element设置的只显示一个&#xff0c;超过一个就隐藏省略了&…

wps的domain转为shp矢量

wps的namelist制作、python出图和转矢量 简介 wps&#xff08;WRF Preprocessing System&#xff09;是中尺度数值天气预报系统WRF(Weather Research and Forecasting)的预处理系统。 wps的安装地址在GitHub上&#xff1a;https://github.com/wrf-model/WPS 下载完成后&…

一步步带你解锁Stable Diffusion:老外都眼馋的 SD 中文提示词插件分享

大家好我是极客菌&#xff01;今天我们继续来分享一个外国人都眼馋的 SD 中文提示词插件。 那我们废话不多说&#xff0c;直接开整。 SD 的插件安装&#xff0c;小伙伴们应该都会了吧&#xff0c;我这里再简单讲下哦&#xff0c;到「扩展」中的「可下载」中点击「加载扩展列表…

分布式锁实现方案-基于Redis实现的分布式锁

目录 一、基于Lua看门狗实现 1.1 缓存实体 1.2 延迟队列存储实体 1.3 分布式锁RedisDistributedLockWithDog 1.4 看门狗线程续期 1.5 测试类 1.6 测试结果 1.7 总结 二、RedLock分布式锁 2.1 Redlock分布式锁简介 2.2 RedLock测试例子 2.3 RedLock 加锁核心源码分析…

560. 和为 K 的子数组

题目描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 解题 简单直接, 但时间复杂度最高 O(n3) class Solution {func subarraySum(_ nums: [Int], _ k: Int) -> Int {var t…

华三中小企业组网

一、组网需求 在中小园区中&#xff0c;S5130系列或S5130S系列以太网交换机通常部署在网络的接入层&#xff0c;S5560X系列或 S6520X系列以太网交换机通常部署在网络的核心&#xff0c;出口路由器一般选用MSR系列路由器。 核心交换机配置VRRP保证网络可靠性。园区网中不同的…

哪些AI生图软件值得推荐,有需要的建议收藏!

人工智能(AI)已经渗透到我们生活的方方面面&#xff0c;AI生图软件就是其中的一种&#xff0c;它们能够帮助我们快速生成高质量的图片&#xff0c;无论是社交媒体的配图&#xff0c;还是设计作品的素材&#xff0c;都能够得到极大的帮助。那么哪些AI生图软件值得推荐呢? 首先&…