Hive CTAS知识点回顾
CREATE TABLE AS SELECT
(简称 CTAS)是 SQL 中的一个命令,用于从一个或多个表中选取数据,并根据选择的结果创建一个新表。这个命令通常具有以下形式:
CREATE TABLE 新表名 AS
SELECT 列名1, 列名2, ...
FROM 原表名
WHERE 条件;
这里:
新表名
是你想要创建的新表的名称。SELECT
语句后跟的是你希望从原表中选取的列名,或者使用*
来选取所有列。原表名
是你想要从中选取数据的表的名称。WHERE
子句是可选的,用于指定数据的选择条件。
以下是一个简单的例子:
CREATE TABLE teacher1 AS
SELECT * FROM teacher;
这个例子会创建一个名为 teacher1
的新表,其结构与 teacher
表相同,并包含了 teacher
表中的所有数据。
CTAS 命令有几个特点:
- 它会快速创建新表,并填充数据,无需先创建表结构再插入数据。
- 新表会继承
SELECT
语句中指定的列的数据类型。 - 如果
SELECT
语句中包含聚合函数或GROUP BY
子句,新表将包含聚合后的结果。 - CTAS 不会复制原表的索引、触发器、约束等属性,只会复制数据和结构。
情景再现
今天我在DataGrip 这个软件里执行create table teacher1 as select * from teacher;
语句遇到以下报错:
[08S01][1] Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. User: xiaowang is not allowed to impersonate xiaowang
然后我去网上查找了一下该报错,结果发现却没有,我心想:坏了,又要踩坑了
于是我去虚拟机内部执行了同样的指令却执行成功了,如下图:
查看一下进程都没有错误
然后我就开始纳闷了,为什么服务器内部可以执行成功,使用软件工具就不可以,带着这个问题我来问了一下AI,他给我的答复是这样的:这个错误信息表明,在使用Hive执行查询时,用户xiaowang
尝试模拟(impersonate)自己,但是Hive的配置不允许这样做。这通常与Hadoop的安全配置有关。以下是一些可能的解决方案:
-
检查Hadoop的安全配置:
- 确认
hadoop.proxyuser.xiaowang.groups
和hadoop.proxyuser.xiaowang.hosts
配置项是否正确设置在core-site.xml
文件中。这些配置项控制着用户xiaowang
可以模拟哪些用户以及从哪些主机发起模拟。
- 确认
-
修改
core-site.xml
:-
打开Hadoop的
core-site.xml
文件。 -
确保有如下配置项,如果没有,则添加它们:
<property> <name>hadoop.proxyuser.xiaowang.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.xiaowang.hosts</name> <value>*</value> </property>
-
*
表示允许所有组和主机,出于安全考虑,您应该替换为具体的组和主机名。
-
-
重启Hadoop服务:
- 修改配置文件后,需要重启Hadoop服务,以便配置生效。
-
检查Hive的配置:
- 确认Hive是否启用了安全模式。如果是,确保Hive的配置与Hadoop的安全配置相匹配。
-
检查用户权限:
- 确认用户
xiaowang
有足够的权限在Hadoop集群上执行作业。
- 确认用户
-
查看日志文件:
- 查看Hive和Hadoop的日志文件以获取更详细的错误信息,这有助于进一步定位问题。
-
确保没有其他安全策略冲突:
- 如果集群有额外的安全策略(如Kerberos),确保它们没有与用户的模拟权限发生冲突。
于是我按照要求查了一下我的相关配置文件:
core-site.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->
<!-- Put site-specific property overrides in this file. -->
<configuration>
<!-- 指定NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:8020</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-3.1.3/data</value>
</property>
<!-- 配置HDFS网页登录使用的静态用户为xiaowang -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>xiaowang</value>
</property>
<!-- 配置所有节点的xiaowang用户都可作为代理用户 -->
<property>
<name>hadoop.proxyuser.xiaowang.hosts</name>
<value>*</value>
</property>
<!-- 配置xiaowang用户能够代理的用户组为任意组 -->
<property>
<name>hadoop.proxyuser.xiaowang.groups</name>
<value>*</value>
</property>
<!-- 配置xiaowang用户能够代理的用户为任意用户 -->
<property>
<name>hadoop.proxyuser.xiaowang.users</name>
<value>*</value>
</property>
</configuration>
我有加这个配置项,那就不是这个配置的问题,然后我当时又查看了一下这个hive-site.xml
这个配置
hive-site.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- jdbc连接的URL -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop102:3306/metastore?useSSL=false</value>
</property>
<!-- jdbc连接的Driver-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<!-- jdbc连接的username-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- jdbc连接的password -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>000000</value>
</property>
<!-- Hive默认在HDFS的工作目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- 指定hiveserver2连接的host -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>hadoop102</value>
</property>
<!-- 指定hiveserver2连接的端口号 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hive.cli.print.header</name>
<value>true</value>
<description>Whether to print the names of the columns in query output.</description>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
<description>Whether to include the current database in the Hive prompt.</description>
</property>
</configuration>
我心想,没毛病啊。。。接着继续查找资料,然后发现
**配置文件方式*
默认配置文件:hive-default.xml
用户自定义配置文件:hive-site.xml
注意:用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。配置文件的设定对本机启动的所有Hive进程都有效。
我找到了这个hive-default.xml这个文件,从中我发现了有个参数:
<property>
<name>hive.server2.enable.doAs</name>
<value>true</value>
<description>
Setting this property to true will have HiveServer2 execute
Hive operations as the user making the calls to it.
</description>
</property>
具体的配置解释如下:
- 配置名称:
hive.server2.enable.doAs
- 配置值:
true
- 描述:当这个属性设置为
true
时,HiveServer2 将会以调用它的用户身份来执行 Hive 操作。这意味着,如果用户 A 连接到 HiveServer2 并执行查询,那么查询将在用户 A 的权限下运行,而不是以运行 HiveServer2 进程的用户身份运行。
这个配置的主要作用是安全性和权限管理。它允许每个用户在HiveServer2上执行操作时,使用他们自己的权限,这有助于实现更细粒度的访问控制。例如,用户 A 可能只能访问特定的数据库或表,而用户 B 可能可以访问其他资源。通过设置 hive.server2.enable.doAs
为 true
,HiveServer2 可以确保每个用户都遵守这些权限限制。
所以,在Hive中允许用户模拟自己,就得把其中的true
改为 false
也就是:
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
然后重启服务就好了。。。
le.doAs为
true`,HiveServer2 可以确保每个用户都遵守这些权限限制。
所以,在Hive中允许用户模拟自己,就得把其中的true
改为 false
也就是:
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
然后重启服务就好了。。。
[外链图片转存中…(img-r1MHn0oS-1722584972947)]
踩坑踩了3小时。。。。 真是醉了