Hive 未关闭表的事务功能(ACID)的问题
创始人
2024-04-02 06:28:47
0

Hive 未关闭表的事务功能(ACID)的问题

一、Hive 未关闭表的事务功能(ACID)的所引发的问题

记录一次HDP3.0 的hive 3.1.2由于未关闭ACID功能,导致使用到用户画像的Spark计算引擎报错,无法处理数据,impala无法查询的问题。由于hive 3.0之后默认开启ACID功能,默认建表都是使用ACID的事务表。而spark目前还不支持hive的ACID功能,因此无法读取ACID表的数据。

另外,读取不报错,但是读取不到数据的表INPUTFORMAT=org.apache.hadoop.hive.ql.io.orc.OrcInputFormat;报错insert-only 的表 INPUTFORMAT = org.apache.hadoop.mapred.TextInputFormat 。

hive3默认开启ACID功能引起的spark和impala报错的问题

在hdp3.1.5中hive3中内部表默认开启了ACID,当spark和impala创建和读取内部表的时候会报错,网上建议的方式是舍弃掉acid特性。

hive.strict.managed.tables=false 
hive.create.as.insert.only=false 
metastore.create.as.acid=false

对应hdp的hive默认配置做如下修改,重启hive服务后确实可以生效:

在这里插入图片描述

什么是事务表

  • 概念
    ACID就是常见数据库事务的四大特性:Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性)。

由于HDFS只支持文件的添加和删除,不支持修改,因此Hive原生并不支持原子性的行级别修改。

  • 支持原子性update操作的Hive表称为事务表。
  • 事务表和普通内部表的区别:
    在这里插入图片描述
    可以看到,事务表分为两种,一种是ORC格式,能完整的支持CRUD操作(增删改查),一种是普通的TextFile文件格式,只符合Insert-only特性.

Hive中支持的表类型和ACID特性如下图所示:

表类型ACID文件格式插入更新/删除
托管表:CRUD事务ORC
托管表:仅插入式事务任意格式没有
托管表:临时没有任意格式没有
外部表没有任意格式没有

其中托管表是Hive内部表。

查看表的属性,指令:desc formatted tb_name

非ACID表:

| Table Type:        | MANAGED_TABLE          | NULL  |
| Table Parameters:  | NULL                   | NULL  |
|                    | COLUMN_STATS_ACCURATE  | {\"BASIC_STATS\":\"true\"}  |
|                    | numFiles               | 36554 |
|                    | numPartitions          | 4582  |
|                    | numRows                | 656353471        |
|                    | rawDataSize            | 3687190343914    |
|                    | totalSize              | 191558565757   |
|                    | transient_lastDdlTime  | 1626229162      |

ACID表:

| Table Type:         | MANAGED_TABLE                         | NULL                  |
| Table Parameters:   | NULL                                  | NULL                  |
|                     | bucketing_version                     | 2                     |
|                     | comment                               | 交易日志表             |
|                     | numFiles                              | 2131                  |
|                     | numPartitions                         | 2131                  |
|                     | numRows                               | 1303371497            |
|                     | rawDataSize                           | 0                     |
|                     | totalSize                             | 669842162666          |
|                     | transactional                         | true                  |
|                     | transactional_properties              | insert_only           |
|                     | transient_lastDdlTime                 | 1613705157            |

其中:

  • transactional=true,标识为事务表
  • transactional_properties=insert_only

事务表的适用场景

对于数仓中的行级数据更新删除需求比较频繁的,可以考虑使用事务表。

但平常的hive表并不建议使用事务表。因为事务表的限制很多,加上由于hive表的特性,也很难满足高并发的场景。

另外,如果事务表太多,并且存在大量的更新操作,metastore后台启动的合并线程会定期的提交MapReduce Job,也会一定程度上增重集群的负担。

结论: 除非有非常迫切的行级更新需求,又只能用hive表来做,才需要去考虑事务表。

注意事项

  1. 不支持 BEGIN、COMMIT、ROLLBACK 等语句,所有的语句都是自动提交
  2. 仅支持ORC格式

设计原理与实现

文件管理格式

HDFS本身是不支持直接修改文件的,也不能保证有人追加内容时的读一致性。

因此,为了支持ACID的特性,Hive只能使用其他数据仓库常用的方法,也就是增量的形式记录更新和删除(也称做读时更新)。

存储在事务表中的数据会被分成两种类型的文件:

base文件,用来存放平常的数据
delta文件,用来存储新增、更新、删除的数据。每一个事务处理数据的结果都会单独新建一个delta文件夹用来存储数据。
在有用户要读取这个表的数据时,就会将base文件和delta文件都读取到内存,然后进行合并(就是判断哪些记录有被修改,哪些记录被删除等)。

ACID表的文件结构:${Hive_path}/db/table_name/base_{id}/file。

Found 2 items                                      |
| -rw-rw----+  3 hdfs hadoop 1091048351 2021-07-13 15:00 /warehouse/tablespace/managed/hive/db_name.db/tb_name/date=2021-06-30/base_0002252/000000_0
| -rw-rw----+  3 hdfs hadoop 1091048351 2021-07-13 15:00 /warehouse/tablespace/managed/hive/db_name.db/tb_name/date=2021-06-30/delta_0000023_0000023_0000/000000_0

其中0000023标识事务ID,0000表示序号,从上面的表中我们可以看到有一个事务的数据还未合并成base。

非ACID表,通过别的表格导入数据,文件目录为:

+----------------------------------------------------+
|                     DFS Output                     |
+----------------------------------------------------+
| 2.6 M  7.9 M  /warehouse/tablespace/managed/hive/db_name.db/tb_name/day=2021-07-18/-ext-10000/000000_0 |
+----------------------------------------------------+

普通内部表文件目录:

+----------------------------------------------------+
|                     DFS Output                     |
+----------------------------------------------------+
| 7.4 M  22.1 M  /warehouse/tablespace/managed/hive/db_name.db/tb_name/day=2021-07-18/000000_0 |
+----------------------------------------------------+

参考博客
Hive ACID和事务表支持详解_u013332124的专栏-CSDN博客
Hive ACID 增删改查 原理以及场景描述_Lara1111的博客-CSDN博客
Hive 官方手册翻译 – Hive Transactions (Hive 事务) - 范振勇 - 博客园 (cnblogs.com)
Spark 无法读取hive 3.x的表数据_u013024563的博客-CSDN博客


问题解决办法

那么如果项目一开始就没有关闭hive的ACID设置,怎么解决这个问题呢?

思路:先关闭ACID设置

  • 使用shell脚本或者java程序连接jdbc,导出已有库的所有表的建表语句,

    只保留create table 原表名_bak(col1 type,col2 type,...)partition by (分区字段)store as ORC;
    
  • 执行建表语句,新建表名,然后将数据从老表中查询出来,覆写到新表中。

  • 然后旧表更名为 table名_old,新表面更名为原表名,这样就不影响到下游的使用。

  • 更名操作命令:

  • 当前Hive版本:3.1.3000.7.1.7.0-551
    创建hive外部表: CREATE TABLE IF NOT EXISTS `alter_test` (a string,b string) STORED AS ORC TBLPROPERTIES("transactional"="false");
    转hive内部表:ALTER TABLE alter_test SET TBLPROPERTIES('external'='false');
    重命名:ALTER TABLE alter_test RENAME TO alter_test_bak;
    
  • 设置hive表的Location的hdfs路径:

  • ALTER TABLE  RENAME TO ;
    ALTER TABLE  set location "hdfs://";
    
  • 如果在编写shell脚本时候导出的建表语句有格式化输出可以使用beeline如下命令:

  • 在这里插入图片描述
    如果创建的表impala还是无法查询到数据,记得可能是impala的元数据没有及时更新。可执行如下命令刷新元数据:

  • invalidate metadata 全量刷新,性能消耗较大,主要用于 hive 当中新建数据库或者数据库表的时候来进行刷新。

  • refresh dbname.tablename 增量刷新,刷新某一张表的元数据,主要用于刷新 hive 当中数据表里面的数据改变的情况。

  • quit/exit 命令 从 Impala shell 中弹出

  • explain 命令 用于查看 sql 语句的执行计划

二、root 进入hive 报错:Permission denied: user=root, access=WRITE, inode=“/user/root”:hdfs:hdfs:drwxr-xr-x

使用root用户执行hive -f /home/insert.sql报错
在这里插入图片描述
解决办法:

  1. 进入 Ambari,

  2. 进入HDFS,

  3. 点击Configs
    在这里插入图片描述

  4. 打开 Advanced hdfs-site,设置dfs.permissions.enabled=false.

  5. 重启HDFS,以及相关组建。

上一篇:Mysql注入

下一篇:[数据结构初阶]顺序表

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...