Hive-存储-文件格式

news2024/7/6 20:07:09

一、前言

数据存储是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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大家都在聊IPD(集成产品开发)?国内IPD体系做的比较好的是哪款项目管理软件?看IBM、华为的研发管理之道!

IPD&#xff08;集成产品开发&#xff09;到底是什么&#xff1f;一套体系&#xff1f;一些流程&#xff1f;还是一种模式&#xff1f; 一、回顾一下&#xff0c;什么是IPD&#xff1f; IPD到底是什么&#xff1f;一套体系&#xff1f;一些流程&#xff1f;还是一种模式&#…

Batch学习及应用案例

一、介绍 Batch是一种Windows操作系统中使用的批处理脚本语言&#xff0c;用于自动化执行一系列命令和操作。通过编写批处理脚本&#xff0c;可以实现自动化完成重复性或繁琐的任务&#xff0c;提高工作效率。 Batch脚本可以使用内置的命令和命令行工具&#xff0c;以及调用其…

学校机器该maven环境

在学校机器上 安装maven配置idea中的maven 后&#xff0c;发现无法运行&#xff0c; 推测是学校电脑上idea版本和我们下的maven 可能不太匹配。 学校的电脑上idea有集成的maven&#xff0c;但默认配置是访问国外的服务器 解决办法&#xff1a; 下载分享给各位同学的压缩包m…

顺序表--数据结构第一关

顺序表 数据结构概念 定义&#xff1a;数据结构是计算机存储、组织数据的⽅式 根据学过C语言的基础上&#xff0c;数组是最简单的数据结构 顺序表的底层就是数组 为什么呢&#xff1f; 例子如下&#xff1a; int arr[100]{1,2,3,4,5}; //修改某一个数据&#xff1a;arr[…

vcruntime140_1.dll是什么东东?vcruntime140_1.dll缺失的8个解决方法

当电脑出现找不到vcruntime140_1.dll,或vcruntime140_1.dll丢失无法打开软件怎么办&#xff1f;小编今天在本文详细为大家介绍解决方法与介绍vcruntime140_1.dll究竟是什么等vcruntime140_1.dll的问题。 一、vcruntime140_1.dll文件是什么 文件概述定义与功能 vcruntime140_…

校园圈子小程序系统搭建需求和需要哪些功能?APP小程序H5前后端源码交付

功能&#xff1a;小程序授权登陆&#xff0c;支持app双端&#xff0c;小程序&#xff0c;h5&#xff0c;pc端&#xff0c;手机号登陆&#xff0c;发帖&#xff0c;建圈子、发活动。可置顶推荐帖子&#xff0c;关注、粉 丝、点赞等。可作为圈子贴吧、小红书、校园社区、表白墙、…

【02】从0到1构建AI生成思维导图应用 -- 编写主页

【02】从0到1构建AI生成思维导图应用 – 编写主页 大家好&#xff01;最近自己做了一个完全免费的AI生成思维导图的网站&#xff0c;支持下载&#xff0c;编辑和对接微信公众号&#xff0c;可以在这里体验&#xff1a;https://lt2mind.zeabur.app/ 上一章&#xff1a;https:/…

【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 模型优化技…

生命在于学习——Python人工智能原理(2.5.1)

五、Python的类与继承 5.1 Python面向对象编程 在现实世界中存在各种不同形态的事物&#xff0c;这些事物之间存在各种各样的联系。在程序中使用对象来映射现实中的事物&#xff0c;使用对象之间的关系描述事物之间的联系&#xff0c;这种思想用在编程中就是面向对象编程。 …

nodejs国内源下载

nodejs的官网下载太慢了 可以尝试网盘下载快一点 夸克网盘分享夸克网盘是夸克推出的一款云服务产品&#xff0c;功能包括云存储、高清看剧、文件在线解压、PDF一键转换等。通过夸克网盘可随时随地管理和使用照片、文档、手机资料&#xff0c;目前支持Android、iOS、PC、iPad。…

2024年公司加密软件排行榜(企业加密软件推荐)

在信息时代&#xff0c;企业数据安全至关重要&#xff0c;防止数据泄露和未授权访问是首要任务之一。以下是2024年备受好评的企业加密软件排行榜&#xff1a; 固信加密软件https://www.gooxion.com/ 1.固信加密软件 固信加密软件是新一代企业级加密解决方案&#xff0c;采用先…

【网络架构】lvs集群

目录 一、集群与分布式 1.1 集群介绍 1.2 分布式系统 1.3 集群设计原则 二、LVS 2.1 lvs工作原理 2.2 lvs集群体系架构 ​编辑 2.3 lvs功能及组织架构 2.4 lvs集群类型中术语 三、LVS工作模式和命令 3.1 lvs集群的工作模式 3.1.1 lvs的nat模式 3.1.2 lvs的dr模式 …

胶质瘤的发病原因及诊断方式有哪些?

胶质瘤&#xff0c;这个听起来有些陌生的名词&#xff0c;实际上是一种起源于神经胶质细胞的常见脑肿瘤。它的发病原因复杂&#xff0c;涉及遗传、环境、年龄及感染等多种因素。 首先&#xff0c;遗传因素在胶质瘤的发病中占据一席之地。某些遗传性疾病&#xff0c;如结节性硬化…

3Dmax模型渲染时的常见问题与解决方法

3Dmax是一个广为人知的三维建模工具&#xff0c;它在建筑、电影制作和游戏开发等多个领域都有着广泛的应用。尽管如此&#xff0c;在进行3Dmax模型渲染的过程中&#xff0c;用户可能会遇到一些常见问题。本文将提供这些常见问题的解决方案&#xff0c;以帮助用户提高渲染效率和…

BIO、NIO编程深入理解与直接内存、零拷贝

网路编程基本常识 一. Socket 什么是Socket Socket是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。它提供了应用层进程利用网络协议交换数据的机制&#xff0c;是应用程序与网络协议栈进行交互的接口。 说白了&#xff0c;Socket就是把TCP/IP协议族进行封装…

JOSEF约瑟 ESRW-322打滑开关 智能运算,工作稳定

产品特点 非接触式检测&#xff1a;ESRW-322打滑开关采用非接触式检测方式&#xff0c;不会对输送带造成磨损&#xff0c;提高了设备的使用寿命。 高精度测量&#xff1a;该开关具有高精度测量能力&#xff0c;可检测到的打滑率范围广泛&#xff08;0∽100%&#xff09;&#x…

LangCell:用于细胞注释的语言-细胞预训练模型

细胞身份包括细胞的各种语义&#xff0c;包括细胞类型、pathway信息、疾病信息等。从转录组数据中了解细胞身份&#xff0c;例如注释细胞类型&#xff0c;是一项基础任务。由于语义是由人类赋予的&#xff0c;如果没有cell-label pair提供监督信号&#xff0c;AI模型很难有效地…

文献解读-基因编辑-第十二期|《CRISPR-detector:快速、准确地检测、可视化和注释基因组编辑事件引起的全基因组范围突变》

关键词&#xff1a;基因组变异检测&#xff1b;全基因组测序&#xff1b;基因编辑&#xff1b; 文献简介 标题&#xff08;英文&#xff09;&#xff1a;CRISPR-detector: fast and accurate detection, visualization, and annotation of genome-wide mutations induced by g…

IDEA 安装与激活详细教程最新(附最新激活码)2099年亲测有效!

我们先从 IDEA 官网下载 IDEA 2024.1 版本的安装包&#xff0c;下载链接如下&#xff1a; https://www.jetbrains.com/idea/download/ 点击下载(下载Ultimate版)&#xff0c;静心等待其下载完毕即可。 激活方式&#xff1a; 正版专属激活码领取

自定义APT插件导致IDEA调试时StreamTrace(跟踪当前流链)报internal error(内部错误)

IDEA里面debug的时候&#xff0c;针对stream流提供了流追踪调试功能&#xff0c;方便大家调试stream流代码。 最近改其他人代码&#xff0c;需要用到这个&#xff0c;发现提示内部错误。 然后百度一圈发现没啥解决方案&#xff0c;就自己看IDEA的日志&#xff0c;看看是什么引…