Hive 保姆级入门教程

2023年 7月 25日 127.8k 0

Apache Hive 从入门到放弃

Hive简介

  • Hive是什么

    • 基于Hadoop的数据仓库工具,可以用SQL查询Hive表
    • 实现了类似SQL的HiveQL,使得开发MapReduce应用更简单
    • 示例:SELECT * FROM table LIMIT 10;
  • Hive的优点

    • 易于使用,通过SQL开发大数据应用
    • 良好的扩展性,可处理PB级别的数据
    • 支持表join,group by, order by等复杂操作
    • 支持用户自定义函数,可扩展系统功能
  • Hive架构概览

    • 元数据存储在数据库如MySQL中
    • 解释器、编译器、优化器等组件负责编译查询
    • 使用MapReduce或Spark执行查询
    • 结果输出到HDFS或数据库

Hive安装

下载和安装Hive

  • 在Linux服务器上安装wget工具: yum install -y wget

  • 通过wget下载Hive安装包:

    wget https://dlcdn.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz
    
  • 检查下载的文件完整性:

    md5sum apache-hive-3.1.3-bin.tar.gz
    # 对比显示的md5码与官网给定的md5码是否一致
    
  • 创建安装目录,例如:/opt/hive

    mkdir /opt/hive
    
  • 解压缩Hive压缩包到指定目录:

    tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /opt/hive
    
  • 设置环境变量HIVE_HOME:

    export HIVE_HOME=/opt/hive/apache-hive-3.1.3-bin
    
  • 将HIVE_HOME/bin添加到PATH:

    export PATH=$HIVE_HOME/bin:$PATH
    
  • 配置Hive环境

  • 配置hive-env.sh
  • 进入Hive配置文件目录

    cd $HIVE_HOME/conf
    

    拷贝环境配置模板

    cp hive-env.sh.template hive-env.sh
    

    编辑hive-env.sh文件

    vi hive-env.sh
    

    在hive-env.sh中配置以下环境变量:

    # Hive执行使用的Hadoop路径
    HADOOP_HOME=/usr/local/hadoop 
    
    # Hive运行使用Java的home
    JAVA_HOME=/usr/java/jdk1.8.0_162
    
    # Hive日志目录
    HIVE_LOG_DIR=/tmp/hive/logs
    
    # Hive元数据目录 
    HIVE_METASTORE_WAREHOUSE=/tmp/hive/warehouse
    

    保存退出后,重启Hive使得配置生效

  • 配置hive-site.xml
  • 编辑hive-site.xml:vi hive-site.xml

    
    
    
    
      javax.jdo.option.ConnectionURL
      jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true
    
    
    
    
      javax.jdo.option.ConnectionDriverName
      com.mysql.cj.jdbc.Driver  
    
    
    
    
      javax.jdo.option.ConnectionUserName
      root
    
    
    
    
      javax.jdo.option.ConnectionPassword
      root
    
    
          hive.metastore.warehouse.dir
          /user/hive/warehouse
    
    
    
    

    拷贝MySQL驱动到Hive

    如果本地没有MySQL JDBC驱动,需要先下载该驱动再拷贝到Hive。那么具体的步骤为:

  • 从MySQL官网下载对应版本的驱动连接器

    例如到 https://dev.mysql.com/downloads/connector/j/ 下载mysql-connector-java-8.0.11.tar.gz

  • 解压驱动包获得jar文件

    tar zxvf mysql-connector-java-8.0.11.tar.gz
    
  • 拷贝jar包到Hive的lib目录

    cp mysql-connector-java-8.0.11/mysql-connector-java-8.0.11.jar $HIVE_HOME/lib
    
  • 验证并重启Hive

  • 以上考虑了从MySQL官网下载驱动的情况,提前下载好驱动再拷贝到Hive。

    如果本地已经具备了MySQL驱动,则可以直接拷贝,无需下载。

    初始化MetaStore Schema

  • 确认MySQL数据库已经创建好,并配置在hive-site.xml中

  • 进入Hive的bin目录

    cd $HIVE_HOME/bin
    
  • 执行Schema初始化

    schematool -initSchema -dbType mysql
    
  • 如果成功会显示如下信息

    Metastore connection URL:  jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true
    Metastore Connection Driver :  com.mysql.cj.jdbc.Driver
    Metastore connection User:  root
    Starting metastore schema initialization to 3.1.0
    Initialization script hive-schema-3.1.0.mysql.sql
    
  • 在MySQL数据库中可以查看新建的Hive元数据表,包括:

    • DBS - 记录数据库信息
    • TBLS - 记录表信息
    • COLUMNS_V2 - 记录列信息
    • PARTITIONS - 记录分区信息
    • SDS - 记录表/分区物理存储信息
    • SERDES - 记录序列化/反序列化类信息
    • TBL_PRIVS - 记录表权限信息
    • GLOBAL_PRIVS - 记录全局权限信息
    • ROLES - 记录角色信息
    • ROLE_MAP - 记录角色与用户关联信息
    • SEQUENCE_TABLE - 记录序列信息
    • INDEX_PARAMS - 记录索引信息
    • TYPE_FIELDS - 记录类型字段信息
    • TYPES - 记录类型信息
    • FUNCS - 记录函数信息
    • FUNC_RU - 记录函数与角色关联

    配置完毕后测试启动

  • 启动Hive命令行客户端

    hive
    
  • 在hive命令行执行显示数据库列表查询

    show databases;
    
  • 期望看到初始化的默认数据库

    OK
    default
    Time taken: 0.025 seconds, Fetched: 1 row(s)
    
  • 创建一张测试表

    create table test(id int);
    
  • 查看是否创建成功

    show tables;
    
  • 期望看到test表

    OK
    test
    Time taken: 0.01 seconds, Fetched: 1 row(s)
    
  • 退出hive命令行

    quit;
    
  • Hive服务部署

    Hive的hiveserver2服务的作用是提供jdbc/odbc接口,为用户提供远程访问Hive数据的功能,例如用户期望在个人电脑中访问远程服务中的Hive数据,就需要用到Hiveserver2。

    在远程访问Hive数据时,客户端并未直接访问Hadoop集群,而是由Hivesever2代理访问。由于Hadoop集群中的数据具备访问权限控制,所以此时需考虑一个问题:那就是访问Hadoop集群的用户身份是谁?是Hiveserver2的启动用户?还是客户端的登录用户?答案是都有可能,具体是谁,由Hiveserver2的hive.server2.enable.doAs参数决定,该参数的含义是是否启用Hiveserver2用户模拟的功能。若启用,则Hiveserver2会模拟成客户端的登录用户去访问Hadoop集群的数据,不启用,则Hivesever2会直接使用启动用户访问Hadoop集群数据。模拟用户的功能,默认是开启的。

    生产环境推荐开启用户模拟功能,因为开启后才能保证各用户之间的权限隔离。

    hiveserver2部署

  • Hadoop端配置
  • hivesever2的模拟用户功能,依赖于Hadoop提供的proxy user(代理用户功能),只有Hadoop中的代理用户才能模拟其他用户的身份访问Hadoop集群。因此,需要将hiveserver2的启动用户设置为Hadoop的代理用户,配置方式如下:

    修改配置文件core-site.xml,然后分发到各台服务器
    cd $HADOOP_HOME/etc/hadoop
    vim core-site.xml
    

    增加配置如下:

    
    
        hadoop.proxyuser.hadoop.hosts
        *
    
    
    
    
        hadoop.proxyuser.hadoop.groups
        *
    
    
    
    
        hadoop.proxyuser.hadoop.users
        *
    
    
  • Hive端配置
  • 在hive-site.xml文件中添加如下配置信息:

    # 打开文件
     vim hive-site.xml
     # 添加如下内容
     
    
     hive.server2.thrift.bind.host
     hadoop102
    
    
    
    
     hive.server2.thrift.port
     10000
    
    
  • 测试
  • 启动hiveserver2:bin/hive --service hiveserver2

    使用命令行客户端beeline进行远程访问: bin/beeline -u jdbc:hive2://node01:10000 -n hadoop

    看到如下界面

    Connecting to jdbc:hive2://node01:10000
    Connected to: Apache Hive (version 3.1.3)
    Driver: Hive JDBC (version 3.1.3)
    Transaction isolation: TRANSACTION_REPEATABLE_READ
    Beeline version 3.1.3 by Apache Hive
    0: jdbc:hive2://node01:10000>
    

    metastore服务

    Hive的metastore服务的作用是为Hive CLI或者Hiveserver2提供元数据访问接口。

  • metastore运行模式
  • metastore有两种运行模式,分别为嵌入式模式和独立服务模式。生产环境中,不推荐使用嵌入式模式。因为其存在以下两个问题:

    • 嵌入式模式下,每个Hive CLI都需要直接连接元数据库,当Hive CLI较多时,数据库压力会比较大。
    • 每个客户端都需要用户元数据库的读写权限,元数据库的安全得不到很好的保证。
  • metastore部署
  • 嵌入式模式:嵌入式模式下,只需保证Hiveserver2和每个Hive CLI的配置文件hive-site.xml中包含连接元数据库所需要的以下参数即可:

     
        
            javax.jdo.option.ConnectionURL
            jdbc:mysql://hadonode01op102:3306/metastore?useSSL=false
        
        
        
        
            javax.jdo.option.ConnectionDriverName
            com.mysql.jdbc.Driver
        
        
     
        
            javax.jdo.option.ConnectionUserName
            root
        
    
        
        
            javax.jdo.option.ConnectionPassword
            root
        
    

    独立服务模式:需做以下配置,首先,保证metastore服务的配置文件hive-site.xml中包含连接元数据库所需的以下参数:

    
        
            javax.jdo.option.ConnectionURL
            jdbc:mysql://node01:3306/metastore?useSSL=false
        
        
        
        
            javax.jdo.option.ConnectionDriverName
            com.mysql.jdbc.Driver
        
        
     
        
            javax.jdo.option.ConnectionUserName
            root
        
    
        
        
            javax.jdo.option.ConnectionPassword
            root
        
    

    其次,保证Hiveserver2和每个Hive CLI的配置文件hive-site.xml中包含访问metastore服务所需的以下参数:

    
    
     hive.metastore.uris
     thrift://node01:9083
    
    

    注意:主机名需要改为metastore服务所在节点,端口号无需修改,metastore服务的默认端口就是9083。

  • 测试
  • 此时启动Hive CLI,执行shou databases语句,会出现一下错误提示信息:

    hive (default)> show databases;
    FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
    

    这是因为我们在Hive CLI的配置文件中配置了hive.metastore.uris参数,此时Hive CLI会去请求我们执行的metastore服务地址,所以必须启动metastore服务才能正常使用。

    metastore服务的启动命令如下:hive --service metastore

    注意:启动后该窗口不能再操作,需打开一个新的Xshell窗口来对Hive操作。

    重新启动 Hive CLI(bin/hive),并执行shou databases语句,就能正常访问了。

    Hive服务启动脚本

  • 后台启动方式
  • 前台启动的方式导致需要打开多个Xshell窗口,可以使用如下方式后台方式启动:

    • nohup:放在命令开头,表示不挂起,也就是关闭终端进程也继续保持运行状态
    • /dev/null:是Linux文件系统中的一个文件,被称为黑洞,所有写入该文件的内容都会被自动丢弃
    • 2>&1:表示将错误重定向到标准输出上
    • &:放在命令结尾,表示后台运行

    一般会组合使用:nohup [xxx命令操作]> file 2>&1 &,表示将xxx命令运行的结果输出到file中,并保持命令启动的进程在后台运行。

    nohup hive --service metastore 2>&1 &
    nohup hive --service hiveserver2 2>&1 &
    
  • 为了方便使用,可以直接编写脚本来管理服务的启动和关闭
  • # 打开文件
    vim $HIVE_HOME/bin/hiveservices.sh
    # 添加内容
    #!/bin/bash
    
    HIVE_LOG_DIR=$HIVE_HOME/logs
    if [ ! -d $HIVE_LOG_DIR ]
    then
     mkdir -p $HIVE_LOG_DIR
    fi
    
    #检查进程是否运行正常,参数1为进程名,参数2为进程端口
    function check_process()
    {
        pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}')
        ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1)
        echo $pid
        [[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1
    }
    
    function hive_start()
    {
        metapid=$(check_process HiveMetastore 9083)
        cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 &"
        [ -z "$metapid" ] && eval $cmd || echo "Metastroe服务已启动"
        server2pid=$(check_process HiveServer2 10000)
        cmd="nohup hive --service hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"
        [ -z "$server2pid" ] && eval $cmd || echo "HiveServer2服务已启动"
    }
    
    function hive_stop()
    {
    metapid=$(check_process HiveMetastore 9083)
        [ "$metapid" ] && kill $metapid || echo "Metastore服务未启动"
        server2pid=$(check_process HiveServer2 10000)
        [ "$server2pid" ] && kill $server2pid || echo "HiveServer2服务未启动"
    }
    
    case $1 in
    "start")
        hive_start
        ;;
    "stop")
        hive_stop
        ;;
    "restart")
        hive_stop
        sleep 2
        hive_start
        ;;
    "status")
        check_process HiveMetastore 9083 >/dev/null && echo "Metastore服务运行正常" || echo "Metastore服务运行异常"
        check_process HiveServer2 10000 >/dev/null && echo "HiveServer2服务运行正常" || echo "HiveServer2服务运行异常"
        ;;
    *)
        echo Invalid Args!
        echo 'Usage: '$(basename $0)' start|stop|restart|status'
        ;;
    esac
    
    # 添加执行权限
    chmod +x $HIVE_HOME/bin/hiveservices.sh
    # 启动Hive后台服务
    hiveservices.sh start
    

    Hive数据类型

  • 原始数据类型
    • TINYINT: 1字节整型,取值范围:-128 ~ 127
    • SMALLINT: 2字节整型,取值范围:-32768 ~ 32767
    • INT: 4字节整型,取值范围:-2147483648 ~ 2147483647
    • BIGINT: 8字节整型,取值范围:-9223372036854775808 ~ 9223372036854775807
    • FLOAT: 单精度浮点数,4字节
    • DOUBLE: 双精度浮点数,8字节
    • DECIMAL: 准确的小数值,参数指定精度和范围
    • STRING: 字符系列,可指定长度
    • VARCHAR: 变长字符串,最大长度65535
    • CHAR: 定长字符串,长度1~255
    • BOOLEAN: true/false
    • DATE: 日期格式,yyyy-MM-dd
    • TIMESTAMP: 时间戳格式,yyyy-MM-dd HH:mm:ss
  • 复杂数据类型
    • ARRAY: 索引从0开始的数组,元素类型可以不同

      如 ARRAY, ARRAY

    • MAP: key-value映射表格式

      如 MAP

    • STRUCT: 字段集合,类型可以不同

      如 STRUCT

  • 数据格式
    • ORC: 列式存储数据格式,压缩效率高
    • Parquet: 面向分析查询的列式存储格式
    • Avro: 序列化数据交换格式
    • JSON: 一种文本序列化格式

    Hive操作

    创建/删除/修改数据库

    • 创建数据库

      CREATE DATABASE mydb;
      
    • 查看数据库

      SHOW DATABASES;
      
    • 删除数据库

      DROP DATABASE mydb;
      
    • 修改数据库

      ALTER DATABASE mydb SET DBPROPERTIES('comment' = 'db comment'); 
      

    创建/删除/修改表

    • 创建表

      CREATE TABLE mytab (col1 STRING, col2 INT) 
      ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
      STORED AS TEXTFILE;
      
    • 查看表

      SHOW TABLES;
      DESCRIBE mytab;
      
    • 删除表

      DROP TABLE mytab;
      
    • 修改表

      ALTER TABLE mytab ADD COLUMNS (col3 INT);
      ALTER TABLE mytab CHANGE col1 col1_new INT; 
      

    载入数据

    • 加载本地文件到表

      LOAD DATA LOCAL INPATH '/tmp/data.txt' OVERWRITE INTO TABLE mytab;
      
    • 通过查询插入数据

      INSERT INTO TABLE mytab SELECT * FROM oldtab;
      
    • 创建表时载入数据

      CREATE TABLE newtab AS SELECT * FROM mytab;
      

    查询数据

    • 全表查询

      SELECT * FROM mytab;
      
    • 条件过滤

      SELECT * FROM mytab WHERE col1='value';
      
    • 分组和聚合

      SELECT COUNT(*) FROM mytab GROUP BY col2;
      
    • 排序和限制

      SELECT * FROM mytab ORDER BY col2 DESC LIMIT 10;
      

    修改表结构

    • 添加列

      ALTER TABLE mytab ADD COLUMNS (newcol STRING);
      
    • 更改列

      ALTER TABLE mytab CHANGE COLUMN col1 newcol INT;
      
    • 替换列

      ALTER TABLE mytab REPLACE COLUMNS (col1 STRING, col2 INT);
      

    分区表操作

    • 创建分区表

      CREATE TABLE mytab (col1 STRING, col2 INT) 
      PARTITIONED BY (partcol STRING)
      ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
      
    • 加载数据到分区

      LOAD DATA LOCAL INPATH '/tmp/data1.txt' INTO TABLE mytab PARTITION (partcol='part1'); 
      
      LOAD DATA LOCAL INPATH '/tmp/data2.txt' INTO TABLE mytab PARTITION (partcol='part2');
      
    • 查询分区数据

      SELECT * FROM mytab WHERE partcol='part1';
      
    • 增加分区

      ALTER TABLE mytab ADD PARTITION (partcol='part3') LOCATION '/path/to/part3';
      
    • 删除分区

      ALTER TABLE mytab DROP PARTITION (partcol='part1');
      

    桶表操作

    • 创建桶表

      CREATE TABLE mytab (col1 STRING, col2 INT)
      CLUSTERED BY (col2) INTO 4 BUCKETS
      ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'; 
      
    • 加载数据到桶表

      LOAD DATA LOCAL INPATH '/tmp/data.txt' INTO TABLE mytab;
      
    • 抽样查询

      SELECT * FROM mytab TABLESAMPLE(BUCKET 1 OUT OF 4 ON col2); 
      
    • 插入数据到指定桶

      INSERT INTO TABLE mytab CLUSTER BY (col2) 
      SELECT key, value FROM src LIMIT 100;
      
    • 删除指定桶数据

      ALTER TABLE mytab DROP IF EXISTS PARTITION (col2=5); 
      

    HiveQL

    Data Definition Language (DDL)

    • 创建数据库

      CREATE DATABASE mydb;
      
    • 创建表

      CREATE TABLE mytab (col1 STRING, col2 INT)
      ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
      
    • 创建视图

      CREATE VIEW myview AS SELECT col1, col2 FROM mytab WHERE col2 > 1;
      
    • 删除数据库/表/视图

      DROP DATABASE mydb;
      DROP TABLE mytab;
      DROP VIEW myview;
      

    Data Manipulation Language (DML)

    • 载入数据

      LOAD DATA LOCAL INPATH '/tmp/data.txt' OVERWRITE INTO TABLE mytab;
      
    • 插入数据

      INSERT INTO TABLE mytab VALUES ('val1', 2);
      INSERT INTO TABLE mytab (col1, col2) VALUES ('val2', 3);
      
    • 更新数据

      UPDATE mytab SET col1='newval' WHERE col2=2;
      
    • 删除数据

      DELETE FROM mytab WHERE col2=3;
      

    查询语言

    • 基础查询

      SELECT * FROM mytab;
      SELECT col1, col2 FROM mytab;
      
    • 条件过滤

      SELECT * FROM mytab WHERE col1='val';
      
    • 排序和限制

      SELECT * FROM mytab ORDER BY col2 DESC LIMIT 5;
      
    • 聚合查询

      SELECT COUNT(*) FROM mytab;
      SELECT MAX(col2) FROM mytab;
      
    • 分组

      SELECT col1, COUNT(*) FROM mytab GROUP BY col1; 
      
    • JOIN

      SELECT * FROM tab1 JOIN tab2 ON tab1.id = tab2.id;
      

    Hive架构

  • 元数据存储(Metastore)
    • 默认内置的Apache Derby数据库
    • 也支持MySQL、Postgres等外部数据库
    • 存储数据库、表、分区、列的数据类型信息
    • metastore服务通过Thrift提供元数据访问接口
  • Driver(HiveDriver)
    • 接收来自CLI/JDBC/ODBC的查询请求
    • 进行语法解析生成抽象语法树AST
    • 生成逻辑执行计划
    • 优化逻辑计划,生成最优物理计划
    • 生成MapReduce、Spark或Tez任务
    • 向执行引擎提交作业执行
  • 编译器(Compiler)
    • 对AST进行类型检查、语义分析
    • 生成逻辑执行计划
    • 针对DDL语句生成元数据操作
  • 优化器(Optimizer)
    • 对逻辑计划进行优化,产出多种物理计划
    • 选择代价最低的物理计划
    • 物理优化包括join优化、groupby优化等
  • 执行器(Executor)
    • 接收物理计划,生成MapReduce/Spark/Tez任务
    • 提交给YARN集群执行作业
    • 控制作业的生命周期
    • 通过列式存储格式实现向量化查询
  • 客户端
    • CLI(hive shell)
    • JDBC/ODBC - 通过JDBC连接HiveServer2
    • Web UI - 基于网页的Hive查询接口
    • Thrift/JDBC - 元数据访问接口

    Hive优化

    Join优化

    • 将大表设置为桶表,加快JOIN速度

      SET hive.optimize.bucketmapjoin = true; 
      SET hive.optimize.bucketmapjoin.sortedmerge = true;
      
    • 使用Map Join,避免reduce端数据shuffle

      SET hive.auto.convert.join = true;
      

    数据倾斜

    • 使用抽样和分桶,提前识别和缓解数据倾斜

      CLUSTERED BY(col) INTO NUM BUCKETS; 
      TABLESAMPLE(BUCKET 1 OUT OF NUM)
      
    • 调整map数为表分桶数的整数倍

      SET mapreduce.job.maps=15;
      

    小文件合并

    • 使用CombineHiveInputFormat完成合并

      SET mapreduce.input.fileinputformat.input.dir.recursive = true;
      

    设置任务并行度

    • 设置map数,增加并行度

      SET mapreduce.job.maps=20;
      
    • 设置reduce数,增大并行

      SET mapreduce.job.reduces=10;
      

    压缩

    • 对中间输出进行压缩

      SET hive.exec.compress.intermediate=true; 
      
    • 对最终输出结果进行压缩

      SET hive.exec.compress.output=true;
      

      好的,我用Markdown格式,尽量详细地概述Hive的各种优化策略,并给出参数设置和使用案例:

    本地模式

    利用本地多核心执行任务,跳过YARN资源调度

    设置参数:
    hive.exec.mode.local.auto=true
    

    案例:

    SET hive.exec.mode.local.auto=true;
    
    SELECT * FROM small_table LIMIT 10; 
    

    上述查询会在本地多核心CPU上并行执行

    分桶&抽样

    利用分桶和抽样解决数据倾斜问题

    设置参数:
    CLUSTERED BY(col) INTO BUCKETS
    TABLESAMPLE(BUCKET x OUT OF y)
    

    案例:

    CREATE TABLE page_views 
    CLUSTERED BY(pageID) INTO 128 BUCKETS;
    
    SELECT * FROM page_views TABLESAMPLE(BUCKET 5 OUT OF 128);
    

    Hive on Spark

    Hive on Spark利用Spark作为Hive查询的执行引擎,以实现更高的查询性能

    运行原理

  • Hive的Driver接收并编译SQL查询
  • 产生Spark作业对应的执行计划
  • 在Spark集群上并行执行查询计划
  • 返回结果给Hive Driver
  • 配置方法

    在hive-site.xml中设置参数:

    hive.execution.engine=spark
    

    使用案例

    SET hive.execution.engine=spark;
    
    SELECT * FROM tbl;
    

    上述查询会使用Spark作为执行引擎,实现快速查询

    优点

    • 利用Spark的执行速度优势
    • 低延迟,实时查询
    • 处理流式数据
    • 与机器学习集成

    Hive on Spark让Hive可以享受Spark带来的性能优势,构建低延迟和实时的大数据分析平台。

    Hive 事务

    Hive从0.13版本开始支持基于MVCC的事务功能

    ACID特性

    Hive表开启事务后,可以支持原子性、一致性、隔离性的事务:

    • 支持插入/更新/删除行的事务改变
    • 事务隔离,读取可重复读版本的数据视图
    • 满足ACID特性,保证事务一致性

    事务操作

    -- 开始事务
    START TRANSACTION;
    
    -- 查询
    SELECT * FROM table WHERE id=1 FOR UPDATE; 
    
    -- 数据修改  
    UPDATE table SET col='new_value' WHERE id=1;
    
    -- 提交事务
    COMMIT;
    

    需要先设置表为事务表:ALTER TABLE table SET TBLPROPERTIES('transactional'='true');

    使用案例

    ALTER TABLE table SET TBLPROPERTIES('transactional'='true');
    
    START TRANSACTION;
    
    UPDATE table SET col='v1' WHERE id=1;
    UPDATE table SET col='v2' WHERE id=2;
    
    COMMIT;
    

    窗口函数

    RANK()

    按指定字段排序后进行排名,排名相同会重复

    RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rank
    

    案例:按部门分区,按薪水降序排名,相同薪水会重复排名

    DENSE_RANK()

    按指定字段排序后进行排名,排名相同会跳过编号

    DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dense_rank 
    

    案例:按部门和薪水排名,相同薪水跳过排名编号

    ROW_NUMBER()

    按指定字段排序,为每行生成一个连续递增的编号

    ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS row_num
    

    案例:按部门和薪水给每行生成一个编号,按降序排序

    LEAD()/LAG()

    获取当前行在窗口分区中往后/前指定偏移量行的字段值

    LEAD(salary, 1) OVER (PARTITION BY dept ORDER BY salary DESC) 
    LAG(salary, 1) OVER (PARTITION BY dept ORDER BY salary DESC)
    

    案例:获取当前行后面/前面一行的salary值

    FIRST_VALUE()/LAST_VALUE()

    获取窗口分区中排序后第一行/最后一行指定字段的值

    FIRST_VALUE(salary) OVER (PARTITION BY dept ORDER BY salary DESC)
    LAST_VALUE(salary) OVER (PARTITION BY dept ORDER BY salary DESC) 
    

    案例:获取部门薪水排名第一/最后的salary

    NTILE()

    将窗口分区中的行分发到指定的组中,各组有编号

    NTILE(2) OVER (PARTITION BY dept ORDER BY salary DESC)
    

    案例:按薪水排名后,将部门内员工分为2组

    CUME_DIST()

    计算当前行在窗口分区中的累积分布值(百分位数)

    CUME_DIST() OVER (PARTITION BY dept ORDER BY salary DESC)
    

    案例:计算当前薪水在部门中的百分位数排名

    PERCENT_RANK()

    计算当前行在窗口分区中的百分比排名

    PERCENT_RANK() OVER (PARTITION BY dept ORDER BY salary DESC)  
    

    案例:计算当前薪水在部门的百分比排名

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论