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 AS
  INPUTFORMAT '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 writer
        ORC_CPP(1),  // ORC C++ writer
        PRESTO(2),   // Presto writer
        SCRITCHLEY_GO(3), // Go writer from https://github.com/scritchley/orc
        UNKNOWN(Integer.MAX_VALUE);

        //.......省略......
    }

    //记录已修复错误的编写器版本。当您修复了编写器中没有更改文件格式的错误
    //(或进行了实质性更改)时,请在此处添加一个新版本,而不是version。
    //每个WriterImplementation从6开始按顺序分配id,
    //以便ORC-202之前的读取器正确对待其他写入程序。
    public enum WriterVersion {
        // Java ORC Writer
        ORIGINAL(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 过滤器使用utf8
        ORC_101(WriterImplementation.ORC_JAVA, 5),
        //时间戳统计使用utc
        ORC_135(WriterImplementation.ORC_JAVA, 6),
        //decimal64 min/max是固定的
        ORC_517(WriterImplementation.ORC_JAVA, 7), 
        //C++ ORC Writer
        ORC_CPP_ORIGINAL(WriterImplementation.ORC_CPP, 6),
        // Presto Writer
        PRESTO_ORIGINAL(WriterImplementation.PRESTO, 6),
        // Scritchley Go Writer
        SCRITCHLEY_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
#100000000

awk '{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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

期末复习---程序填空

注意&#xff1a; 1.数组后移 *p *(p-1) //把前一个数赋值到后一个数的位置上来覆盖后一个数 2.指针找最大字符 max *p while( *p){ if( max< *p) { max*p; qp;/ 用新的指针指向这个已经找到的最大位置&#xff1b;!!!!!!!!! } p; //因为开始没有next &#xff…

Fragment+Viewpage2+FragmentStateAdapter实现滑动式标签布局

大家好&#xff0c;我是网创有方&#xff0c;今天记录下标签布局的实现方法&#xff0c;先看下效果图。 第一步&#xff1a;编写一个activity或者fragment。内含有一个viewpager2的适配器&#xff0c;适配器类型为FragmentStateAdapter。 ​ public class MediaCreateFragment…

计算机图形学入门22:双向反射分布函数(BRDF)

1.定义 所谓BRDF&#xff08;Bidirectional Reflectance Distribution Function&#xff0c;双向反射分布函数&#xff09;&#xff0c;指的是从辐射度量学的角度去理解光线的反射&#xff0c;如下图所示。 所谓反射就是一个点从ωi方向发出的Radiance转化为dA接收到的功率E&am…

在jeesite框架中增加一个收藏夹功能-- V1.0版本

Jeesite简介&#xff1a;JeeSite 快速开发平台&#xff0c;不仅仅是一个后台开发框架&#xff0c;它是一个企业级快速开发解决方案&#xff0c;提供在线数据源管理、数据表建模、代码生成等功能。 正文&#xff1a;Jeesite是一个方便实用&#xff0c;适合敏捷开发&#xff0c;提…

openmetadata1.3.1 自定义连接器 开发教程

openmetadata自定义连接器开发教程 一、开发通用自定义连接器教程 官网教程链接&#xff1a; 1.https://docs.open-metadata.org/v1.3.x/connectors/custom-connectors 2.https://github.com/open-metadata/openmetadata-demo/tree/main/custom-connector &#xff08;一&…

Webpack: 其他性能优化

概述 前面章节我们已经详细探讨 Webpack 中如何使用分包、代码压缩提升应用执行性能。除此之外&#xff0c;还有不少普适、细碎的方法&#xff0c;能够有效降低应用体积&#xff0c;提升网络分发性能&#xff0c;包括&#xff1a; 使用动态加载&#xff0c;减少首屏资源加载量&…

Adobe Photoshop 2024 v25.5.1 中文激活版下载以及安装方法教程

软件介绍 Adobe Photoshop 2024 v25.5.1 是Adobe公司的最新版图像处理软件&#xff0c;它提供了强大的图像编辑工具和智能自动化功能&#xff0c;包括图像修复、色彩校正和滤镜效果&#xff0c;以满足专业人士和业余爱好者的需求。这款软件还支持矢量图形设计和实时协作&#…

一维信号短时傅里叶变换域邻域降噪方法(MATLAB)

噪声在人类日常生活中无处不在,其会降低语音信号的质量和可懂度。在低信噪比的恶劣环境中,这种负面影响愈发严重。为了解决这个问题,众多研究人员在过去的几十年里提出了许多降噪算法。 根据原理的不同,降噪算法可大致分为五类:谱减法、最优滤波法、基于统计模型的方法、子空间…

Java案例打印乘法口诀表,三角形

目录 一问题&#xff1a; ​编辑二代码&#xff1a; 三运行结果&#xff1a; 四问题 二代码&#xff1a; 三运行结果&#xff1a; 一问题&#xff1a; 二代码&#xff1a; package 重修;import java.util.Random; import java.util.Scanner;public class first {public …

IDEA中Java源文件编译后class文件中文乱码

文章目录 一、设置 一、设置 路径&#xff1a;File -> Settings -> Bulid, Execution,Deployment -> Compiler -> Java Compiler

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的生日聚会(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

WordPress网站如何做超级菜单(Mega Menu)?

大多数的网站菜单都是像以下这种条状的形式&#xff1a; 这种形式的是比较中规中矩的&#xff0c;大多数网站都在用的。当然还有另外一种菜单的表现形式&#xff0c;我们通常叫做“超级菜单”简称Mega Menu。网站的超级菜单&#xff08;Mega Menu&#xff09;是一种扩展的菜单&…

前端基础:CSS(篇一)

目录 css概述 CSS与HTML的关系 基本语法 行内样式表 代码 运行 内嵌样式表 代码 运行 外部样式表 代码 运行 选择器 标签选择器 代码 运行 id选择器 代码 运行 类选择器 代码 运行 选择器优先问题 通配选择器 选中所有的标签 代码 运行 选择器组…

2-22 基于matlab的NSGA-2求解多目标柔性车间调度算法

基于matlab的NSGA-2求解多目标柔性车间调度算法,计算最大完工时间、计算总延期时长、计算调度方案的总能耗、计算设备总负荷。输出四项结果&#xff0c;多次运行可寻找最佳的调度计划。程序已调通&#xff0c;可直接运行。 2-22 NSGA-2求解多目标柔性车间调度算法 - 小红书 (xi…

Java - 程序员面试笔记记录 实现 - Part2

2.1 输入输出流 流可以被看作一组有序的字节集合&#xff0c;即数据在两个设备间的传输。 字节流&#xff1a;以字节作为单位&#xff0c;读到一个字节就返回一个字节&#xff1b;InputStream & OutputStream。 字符流&#xff1a;使用字节流读到一个到多个字节先查询码…

传输距离3000M|低延迟|48K采样音频传输模块-SA356大功率发射模块

无线音频应用中&#xff0c;远距离音频传输在许多领域具有广泛的应用需求&#xff0c;例如大型会议系统、公共广播、户外活动和音乐演出等。为了满足这些需求&#xff0c;音频传输模块需要具备一些关键特性&#xff0c;包括长距离传输能力、高音质、低延迟、稳定性以及抗干扰能…

【第11章】MyBatis-Plus条件构造器(上)

文章目录 前言一、功能详解1. allEq2. eq3. ne4. gt5. ge6. lt7. le8. between9. notBetween10. like11. notLike12. likeLeft13. likeRight14. notLikeLeft15. notLikeRight16. isNull17. in18. notIn19. inSql20. notInSql21. eqSqlSince 3.5.622. gtSql Since 3.4.3.223. ge…

【CentOS7.6】yum 报错:Could not retrieve mirrorlist http://mirrorlist.centos.org

一、报错 1.报错内容如下 在使用 yum makecache 命令时报错&#xff0c;在 yum install -y xxx 的时候报错等等 [roothcss-ecs-a901 yum.repos.d]# yum makecache Loaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorl…

【鸿蒙学习笔记】Column迭代完备

属性含义介绍 Column({ space: 10 }) {Row() {Text(文本描述).size({ width: 80%, height: 60 }).backgroundColor(Color.Red)}.width(90%).height(90).backgroundColor(Color.Yellow) } .width(100%) // 宽度 .height(200) // 高度 .backgroundColor(Color.Pink) // 背景色 .…

【深圳大学算法设计与分析】 实验六 最大流应用问题 FF -> EK -> Dinic

目录 一、实验目的&#xff1a; 二、内容&#xff1a;棒球赛问题 三、实验要求 四、提交要求 ———————— 问题分析解释&#xff1a; ———————— 算法简解&#xff1a; Ford–Fulkerson 增广 Edmonds–Karp 算法 Dinic算法 Dinic和EK的区别&#xff1a; …