编程导航Hive话题讨论

Hive

4 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

Hive3的安装配置

### 1.<font style="color:rgba(58, 64, 73, 0.97);">上传安装包 解压</font> ```shell tar zxvf apache-hive-3.1.2-bin.tar.gz # 解决Hive与Hadoop之间guava版本差异 cd /export/server/apache-hive-3.1.2-bin/ rm -rf lib/guava-19.0.jar cp /export/server/hadoop-3.3.0/share/hadoop/common/lib/guava-27.0-jre.jar ./lib/ ``` ### 2.修改配置文件 1. **hive-env.sh** ```shell cd /export/server/apache-hive-3.1.2-bin/conf mv hive-env.sh.template hive-env.sh vim hive-env.sh export HADOOP_HOME=/export/server/hadoop-3.3.0 export HIVE_CONF_DIR=/export/server/apache-hive-3.1.2-bin/conf export HIVE_AUX_JARS_PATH=/export/server/apache-hive-3.1.2-bin/lib ``` 2. **<font style="color:rgba(58, 64, 73, 0.97);">hive-site.xml</font>** ```shell vim hive-site.xml ``` ```xml <configuration> <!-- 存储元数据mysql相关配置 --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node1:3306/hive3?createDatabaseIfNotExist=true&amp;useSSL=false</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>你的数据库密码</value> </property> <!-- H2S运行绑定host --> <property> <name>hive.server2.thrift.bind.host</name> <value>node1</value> </property> <!-- 远程模式部署metastore metastore地址 --> <property> <name>hive.metastore.uris</name> <value>thrift://node1:9083</value> </property> <!-- 关闭元数据存储授权 --> <property> <name>hive.metastore.event.db.notification.api.auth</name> <value>false</value> </property> </configuration> ``` ### 3.初始化元数据 ```shell # 上传mysql jdbc驱动到hive安装包lib下 cd /export/server/apache-hive-3.1.2-bin/ bin/schematool -initSchema -dbType mysql -verbos #初始化成功会在mysql中创建74张表 # 在hdfs创建hive存储目录 hadoop fs -mkdir /tmp hadoop fs -mkdir -p /user/hive/warehouse hadoop fs -chmod g+w /tmp hadoop fs -chmod g+w /user/hive/warehouse ``` ### 4.<font style="color:rgba(58, 64, 73, 0.97);">启动hive</font> 1. **启动metastore服务 ** ```shell #前台启动 关闭ctrl+c /export/server/apache-hive-3.1.2-bin/bin/hive --service metastore #前台启动开启debug日志 /export/server/apache-hive-3.1.2-bin/bin/hive --service metastore --hiveconf hive.root.logger=DEBUG,console #后台启动 进程挂起 关闭使用jps+ kill -9 nohup /export/server/apache-hive-3.1.2-bin/bin/hive --service metastore & ``` 2. **启动hiveserver2服务** ```shell nohup /export/server/apache-hive-3.1.2-bin/bin/hive --service hiveserver2 & #注意 启动hiveserver2需要一定的时间 不要启动之后立即beeline连接 可能连接不上 ``` 3. **<font style="color:rgba(58, 64, 73, 0.97);">beeline客户端连接</font>** ```shell # 拷贝node1安装包到beeline客户端机器上(node3) scp -r /export/server/apache-hive-3.1.2-bin/ node3:/export/server/ # 连接访问 /export/server/apache-hive-3.1.2-bin/bin/beeline beeline> ! connect jdbc:hive2://node1:10000 beeline> root beeline> 直接回车 ``` ### 所需要的文件 [apache-hive-3.1.2-bin.tar.gz](https://www.yuque.com/attachments/yuque/0/2024/gz/34310486/1708588493356-d6226ea1-e5b0-4864-a3e3-27202cc04de8.gz) [mysql-connector-java-5.1.32.jar](https://www.yuque.com/attachments/yuque/0/2024/jar/34310486/1708588481658-f9a3f3d5-61ef-4eca-883f-6a92cd68e78c.jar)

Hive中有分组聚合导致的数据倾斜问题解决方案

## Hive 解决 GROUP BY 数据倾斜的核心方法 ### Skew-GroupBy(两阶段聚合) **原理** 识别热点 Key,将其数据打散(添加随机后缀)进行第一次部分聚合,第二次聚合合并最终结果。 **启用方式** ```sql SET hive.groupby.skewindata = true; -- 最常用,让 Hive 自动探测和处理 SET hive.optimize.skewjoin = true; -- 通常建议同时开启,处理关联倾斜 SET hive.skewjoin.key = <skewed_column_name>; -- 明确指定倾斜列 SET hive.skewjoin.mapjoin.map.tasks = 10000; -- 控制拆分的份数 (可选) SET hive.skewjoin.mapjoin.min.split = 33554432; -- 控制最小拆分大小,单位字节 (32MB, 可选) ``` **适用场景** - 存在少量、明确或可探测的极高频热点 Key (如某个用户ID、某个分类ID的数据量占绝大部分)。 - 倾斜程度非常严重,单个 Reducer 处理热点 Key 会导致任务显著变慢或失败。 - 可以接受增加一个额外的 MR Job (Stage) 带来的开销。 **优缺点** - 优点: 能有效解决严重倾斜,避免单个 Reducer 瓶颈。 - 缺点: 增加作业复杂度和执行时间(多一个Stage),对小规模倾斜可能不划算。自动探测可能不总是准确。 ### 增加 Reducer 数量 **原理** : 直接增加处理分组任务的 Reducer 数量。如果数据本身分布相对均匀(只是总量大),或者热点 Key 数量较多(但每个不是极端大),增加 Reducer 可以让负载更分散。 **启用方式** ```sql SET mapred.reduce.tasks = <larger_number>; -- 设置为比默认值(或当前值)大得多的数 -- 估算参考:通常可设置为 (总输入数据量 / 期望每个Reducer处理的数据量)。期望值可参考 hive.exec.reducers.bytes.per.reducer (默认256MB)。 ``` **适用场景** - 数据量整体很大,但没有极端突出的单一热点 Key,或者有多个中等规模的热点 Key。 - 倾斜程度中等,增加 Reducer 能有效分担负载。 - 集群有充足的 Reducer 槽位资源。 **优缺点** - 优点: 简单直接,配置方便。 - 缺点: 对单一超级热点 Key 无效(该 Key 的数据最终还是会落在一个 Reducer 上)。设置过大可能导致过多小文件、Reducer 启动开销增大、资源浪费。 ### Map 端部分聚合 **原理** : 在 Map 阶段(Mapper 输出时)先对数据进行一次局部的聚合(类似 Combiner)。这能显著减少需要传输到 Reducer 的数据量,特别是当 Map 输出有很多相同 Key 时。**虽然主要目标是减少数据传输,但在某些中等倾斜场景下也能缓解 Reducer 压力。** **启用方式**(通常默认开启) ```sql SET hive.map.aggr = true; -- 确保开启(默认通常是 true) SET hive.groupby.mapaggr.checkinterval = 100000; -- 聚合操作的条目数目 (可选调优) SET hive.map.aggr.hash.percentmemory = 0.5; -- Mapper 用于聚合的内存占比 (可选调优,避免OOM) ``` **适用场景** - 几乎所有分组聚合查询都应该开启此优化。 - 对中等程度倾斜或数据压缩传输有辅助缓解作用。 - 是其他方法(如 skew-groupby 或 增加 Reducer)的重要基础配合手段。 **优缺点** - 优点: 开销小,效果显著(减少网络传输和 Reducer 输入数据量),默认开启。 - 缺点: 对极端严重倾斜单独作用有限,需要结合其他方法。聚合操作消耗 Mapper 内存,可能需要调优内存参数。 ### 手动随机分桶 + 两阶段聚合 **原理** 当 **hive.groupby.skewindata** 效果不佳或需要对特定热点 Key 进行更精细控制时,可以在 SQL 中手动实现两阶段聚合。 1. 第一阶段: 对原始数据,在分组字段上拼接一个随机数后缀 (**如 CONCAT(group_key, '_', CAST(CEIL(RAND() * N) AS STRING),N 通常取 10-100 或 Reducer 数量级)**,然后按这个新字段进行分组聚合。 2. 第二阶段: 对上一步的结果,**去除随机后缀**,按原始分组字段进行最终聚合。 **示例 SQL** ```sql -- 第一阶段:添加随机后缀并聚合 SELECT split(t.group_key_bucket, '_')[0] AS original_key, -- 先不在这里拆,第二阶段再拆更清晰 t.group_key_bucket, SUM(t.value) AS partial_sum FROM ( SELECT CONCAT(group_key, '_', CAST(CEIL(RAND() * 10) AS STRING) AS group_key_bucket, -- 假设分成10个桶 value FROM your_table ) t GROUP BY t.group_key_bucket; -- 第二阶段:去除后缀,最终聚合 SELECT split(original_key, '_')[0] AS final_group_key, -- 或者用 SUBSTR/REGEXP_EXTRACT SUM(partial_sum) AS total_sum FROM stage1_result GROUP BY split(original_key, '_')[0]; ``` **适用场景** - 已知特定热点 Key 且 hive.groupby.skewindata 效果不理想或需要更精确控制分桶逻辑。 - 倾斜发生在组合 Key 上,自动探测可能失效。 - 开发者希望更透明地控制倾斜处理过程。 **优缺点** - 优点: 灵活性强,可控度高,适用于复杂倾斜场景。 - 缺点: SQL 编写更复杂,需要写两个子查询/CTE,维护成本稍高。 ### 预处理 / ETL 优化 #### 预处理 / ETL 优化 (治本之策) **原理:** 在数据进入 Hive 表之前或在独立的 ETL 流程中,对可能导致倾斜的字段进行处理: - **打散热点 Key:** 对极高频的 Key (如 null, 0, -1, 特定用户ID),在写入时主动添加随机后缀(类似手动分桶),使其在物理存储层面就分布均匀。后续查询直接用这个处理过的字段分组或关联。 - **分离热点数据:** 将热点 Key 的数据单独抽取出来存储和处理。主表处理非热点数据,最后合并结果。 - **业务逻辑规避:** 与业务方沟通,能否改变统计口径,避免按极端倾斜的维度分组(如按城市分组时,把“未知”或“其他”拆分成更细的类别)。 - **使用其他存储/计算引擎:** 对于特定场景,考虑使用 Spark (其 salting 机制更灵活) 或 Flink 处理倾斜问题,或者使用 Kylin/Druid 等预聚合 OLAP 引擎。 **适用场景:** - 数据倾斜是长期存在、可预测且根源性的问题。 - 有权限和能力修改上游数据生成或 ETL 流程。 - 追求根本性解决和查询性能的长期稳定。 **优缺点:** - 优点: 从源头解决问题,后续查询无需特殊优化,性能最佳最稳定。 - 缺点: 改动范围大,涉及数据生产链,可能需要跨团队协作,实施周期长。 ### 📌 如何选择?决策流程图 ![在这里插入图片描述](https://pic.code-nav.cn/post_picture/1611273898647617537/fNDTvdpabEOK6V7i.webp) 综上所述: 1. 基础必备: 始终确保 hive.map.aggr = true (Map端聚合)。这是性价比最高的优化,对几乎所有聚合查询有益。 2. 中等倾斜/整体量大: 优先尝试 增大 mapred.reduce.tasks。结合集群资源,设置一个合理的较大值。 3. 严重倾斜 (明确热点Key): 启用 SET hive.groupby.skewindata = true;。这是 Hive 内置的最直接应对严重分组倾斜的手段。 4. 复杂倾斜/自动优化失效: 采用 手动随机分桶 + 两阶段聚合 SQL 写法。灵活可控。 5. 根源性解决/长期优化: 推动 数据预处理/ETL 优化,在源头打散热点 Key 或分离处理。这是最彻底的方案。 6. 组合使用: 通常需要组合使用。例如:开启 Map 端聚合 + 开启 skew-groupby + 适当增加 Reducer 数量。 7. 监控与分析: 使用 EXPLAIN 查看执行计划,关注各个 Stage 的输入输出记录数。利用 YARN 资源管理器或 Hive/Tez/Spark UI 监控各个 Reducer 的处理时间和数据量,精准定位倾斜点。 最终选择取决于对数据特征的理解、倾斜的严重程度、对查询延迟的要求以及可投入的优化成本。 对于即席查询,优先使用参数优化 (skew-groupby + 增加 Reducers)。对于关键且频繁运行的作业,投资于 ETL 预处理通常是长远之计。

hive踩坑

# 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 命令有几个特点: 1. 它会快速创建新表,并填充数据,无需先创建表结构再插入数据。 2. 新表会继承 `SELECT` 语句中指定的列的数据类型。 3. 如果 `SELECT` 语句中包含聚合函数或 `GROUP BY` 子句,新表将包含聚合后的结果。 4. 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 ``` ![e6a5684f517ae05231eaa495dffc6a5](https://pic.code-nav.cn/post_picture/1623004460282298369/FQkM8AOmnXrSlVtB.webp) 然后我去网上查找了一下该报错,结果发现却没有,我心想:坏了,又要踩坑了 于是我去虚拟机内部执行了同样的指令却执行成功了,如下图: ![b8f195bab85fec629ae6fae0d9fd7ef](https://pic.code-nav.cn/post_picture/1623004460282298369/6WOEheJqV5JJ5bYU.webp) 查看一下进程都没有错误 ![6f2aad964965c2da2ac6fe9063bfe3e](https://pic.code-nav.cn/post_picture/1623004460282298369/cPgY9qF6OHzoss8V.webp) 然后我就开始纳闷了,为什么服务器内部可以执行成功,使用软件工具就不可以,带着这个问题我来问了一下AI,他给我的答复是这样的:这个错误信息表明,在使用Hive执行查询时,用户`xiaowang`尝试模拟(impersonate)自己,但是Hive的配置不允许这样做。这通常与Hadoop的安全配置有关。以下是一些可能的解决方案: 1. **检查Hadoop的安全配置**: - 确认`hadoop.proxyuser.xiaowang.groups`和`hadoop.proxyuser.xiaowang.hosts`配置项是否正确设置在`core-site.xml`文件中。这些配置项控制着用户`xiaowang`可以模拟哪些用户以及从哪些主机发起模拟。 2. **修改`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> ``` - `*`表示允许所有组和主机,出于安全考虑,您应该替换为具体的组和主机名。 3. **重启Hadoop服务**: - 修改配置文件后,需要重启Hadoop服务,以便配置生效。 4. **检查Hive的配置**: - 确认Hive是否启用了安全模式。如果是,确保Hive的配置与Hadoop的安全配置相匹配。 5. **检查用户权限**: - 确认用户`xiaowang`有足够的权限在Hadoop集群上执行作业。 6. **查看日志文件**: - 查看Hive和Hadoop的日志文件以获取更详细的错误信息,这有助于进一步定位问题。 7. **确保没有其他安全策略冲突**: - 如果集群有额外的安全策略(如Kerberos),确保它们没有与用户的模拟权限发生冲突。 于是我按照要求查了一下我的相关配置文件: core-site.xml配置 ```bash <?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配置 ```bash <?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这个文件,从中我发现了有个参数: ```bash <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` 也就是: ```bash <property> <name>hive.server2.enable.doAs</name> <value>false</value> </property> ``` 然后重启服务就好了。。。 ![image-20240802154550211](https://pic.code-nav.cn/post_picture/1623004460282298369/gHFmc8zPLA39KVyk.webp) 踩坑踩了3小时。。。。 真是醉了

hive的code2错误

hive开启本地模式后,在datagrip执行insert操作,当执行一定数量的insert后,就报错 Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask。如何解决?

下载 APP