由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考

article/2025/9/28 14:12:18

背景

 

我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求)、调度任务(常规分析需求),两者均通过我们的Web系统进行提交。以前两种类型的任务都被提交至Yarn中一个名称为“hive”的队列,为了避免两种类型的任务之间相互受影响以及并行任务数过多导致“hive”队列资源紧张,我们在调度系统中构建了一个任务缓冲区队列,所有被提交的任务(手动任务、调度任务)并不会直接被提交至集群,而是提交至这个缓冲区队列中,然后固定数目的工作者线程再将缓冲区队列的任务取出提交至集群执行。

 

这种运行模式在运行任务数不是很多的情况下尚且可行,一旦我们的常规分析需求变多,调度任务数也会随之增加,这时临时分析需求建立的手动任务就可能会影响调度任务的执行,这种影响主要表现在以下两个方面:

 

(1)手动任务与调度任务共用一个队列“hive”,而队列“hive”的资源分配主要是根据调度任务的资源消耗情况进行分配的,这样随机提交的手动任务与调度任务共同执行时,就可能会影响原有调度任务的执行速度;而且无法根据两种任务各自的特性选择合适的调度策略(如:FIFO、Fair);

 

(2)手动任务的提交需要经过调度系统内部的缓冲区队列,如果调度任务比较多,则手动任务可能需要在缓冲区队列中等待很长的时间才能够提交至集群运行,而任务运行时所需资源需要与调度任务共享,执行时间无法保证,用户通常需要等待较长时间;

 

针对上述情况,我们对队列“hive”进行拆分:hive.temporary、hive.common,其中hive.temporary用于临时分析需求的手动任务,hive.common用于常规分析需求的调度任务,这样我们就可以根据业务的实际情况,为两者灵活的进行资源分配。

 

队列拆分之后,我们就有了如下思考:手动任务(临时分析需求)是否依然需要经过调度系统的缓冲区队列再提交至集群?

 

队列拆分一定程度上意味着资源的独立,亦即手动任务与调度任务之间做到了物理上的隔离,如果手动任务依然使用调度系统的缓冲区队列,则也必须是专门针对手动任务的队列;而手动任务是临时分析需求,不可能预留太多的资源给它,为了保证手动任务在可接受的时间内执行完成,我们必须限制队列“hive.temporary”可同时运行任务的数目,以此来保证正在运行的任务有足够的资源去执行;如果某个时间点提交给集群的手动任务超过队列“hive.temporary”可同时运行任务数目的限制,则它们会被暂时“堆积”在Yarn调度器的队列当中。

 

由此可见,我们并不需要再为手动任务在调度系统中建立专门的缓冲区队列,直接利用Yarn调度器的队列即可。我们可以直接将手动任务直接提交至集群,由Yarn调度器根据队列“hive.temporary”根据调度策略及目前队列资源使用情况决定是否运行任务。

 

因为现在的手动任务不经过调度系统的缓冲区队列直接提交至集群,则手动任务的提交可以不再受限于Web系统,用户可以通过Hive官方推荐的Beeline客户端直接提交Hive SQL。

 

这就涉及到本文的核心问题:Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句?

 

解决方案

 

MapReduce运行队列的指定是通过配置(Configuration)属性“mapreduce.job.queuename”指定的。

 

大家可能首先想到的是通过“set mapreduce.job.queuename=queueName”的方式来选取运行队列,这在手动任务(临时分析需求)的场景下是不可取的,如前所述,我们为这类似的任务专门分配了相应的队列资源“hive.temporary”,我们必须能够保证用户通过Beeline连接HiveServer2后提交的Hive SQL语句运行在指定的队列“hive.temporary”中,而且用户无法随意更改运行队列,即无法随意更改属性“mapreduce.job.queuename”。

 

目前HiveServer2使用的权限控制策略为SQL Standard Based Hive Authorization和Storage Based Authorization in the Metastore Server。其中SQL Standard Based Hive Authorization会对Hive终端命令“set”做出限制:只能针对白名单(hive.security.authorization.sqlstd.confwhitelist)中列出的属性进行赋值。白名单默认包含一批属性,其中就包括“mapreduce.job.queuename”,我们需要通过配置文件hive-site.xml或者启动HiveServer2时通过参数“--hiveconf”设置白名单“hive.security.authorization.sqlstd.confwhitelist”的值,排除属性“mapreduce.job.queuename”,使得我们的用户通过Beeline连接至HiveServer2之后,无法随意更改“mapreduce.job.queuename”的值。

 

既然用户无法更改属性“mapreduce.job.queuename”,那么HiveServer2启动之后属性“mapreduce.job.queuename”必须具有一个默认值,即“hive.temporary”,这样用户通过Beeline连接HiveServer2之后提交的Hive SQL就会运行在队列“hive.temporary”中。那么,接下来的问题就是如果完成这个默认设定?

 

一般情况下,我们会这样认为,HiveServer2的运行至少涉及到两份配置文件:

 

(1)Hadoop:core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml

 

(2)Hive:hive-site.xml

 

这些配置文件中的属性值都会“打包”到MapReduce任务的配置属性中去。我们自然会想到在mapred-site.xml或者hive-site.xml中指定“mapreduce.job.queuename”即可,然而实际验证之后发现情况并不是这样的。

 

(1)在hive-site.xml(mapred-site.xml)中指定“mapreduce.job.queuename”;

 

 

(2)测试指定值“test”是否生效;

 

 

我们发现通过Beeline使用账号“hdfs”连接至HiveServer2后,属性“mapreduce.job.queuename”的值被替换为“root.hdfs”,实际执行Hive SQL语句时也会发现相应的MapReduce任务被提交至队列“root.hdfs”。

 

网上也有针对此类情况的提问:http://mail-archives.apache.org/mod_mbox/hive-user/201410.mbox/%3CCAGF+3rbzauDSzDU1q=HwSJ5SKrArNWvxKU5Xg98d+qoLVp3Uyg@mail.gmail.com%3E

 

 

其中的一个解决方案如下:

 

 

其实质就是通过建立连接时的URL参数传递属性值。

 

但是这种方法对于我们没有用处,我们不可能强制我们的用户连接HiveServer2时都指定队列,但这个解决方案给了我们一个思路:既然我们可以通过“客户端”建立连接时初始化属性值,那么“服务端”接受连接时会不会也有初始化的操作?

 

通过对源代码以及日志输出的各种“DEBUG”,最终找到了问题所在。大家都知道,HiveServer2有一个“Session”的概念,就是每一个用户有自己的一个会话(“set”的作用就是在用户自己的会话中设置特定的属性值),用户会话之间相互隔离。根据我们的猜测,我们找到了HiveServer2 Session的实现类:org.apache.hive.service.cli.session.HiveSessionImpl.HiveSessionImpl,它的初始化(构造函数)就是“魔法”发生的地方,关键片段如下:

 

 

而且ConfVars.HIVE_SERVER2_MAP_FAIR_SCHEDULER_QUEUE的值默认为true,如下:

 

 

上述代码片段默认情况下肯定会被执行,也就是说HiveSession的构建过程涉及到了Hadoop Scheduler的具体使用。

 

refreshDefaultQueue的作用就是在可用的情况下为特定用户根据公平调度策略选取队列,其中可用的情况:

 

(1)MapReduce2;

(2)用户名不为空值;

(3)使用公平调度策略;

 

 

继续跟进代码,可以看到如下代码片段:

…...

 

 

QueuePlacementPolicy assignAppToQueue的作用就是为用户分配队列的,其中YarnConfiguration.DEFAULT_QUEUE_NAME的值为default,MR2_JOB_QUEUE_PROPERTY的值为mapreduce.job.queuename,conf实际是HiveConf实例,我们在hive-site.xml或者mapred-site.xml中指定的mapreduce.job.queuename的值也就是在此处被覆盖的(注意:每一个用户会话中都保存着自己的conf)。

 

 

从上面的代码可以看出,最终是由某个QueuePlacementRule决定用户队列的,那么什么决定rules的呢?

 

 

其中FairSchedulerConfiguration.USER_AS_DEFAULT_QUEUE的值为yarn.scheduler.fair.user-as-default-queue,FairSchedulerConfiguration.DEFAULT_USER_AS_DEFAULT_QUEUE的值为true,也就是说默认情况下rules包含两个QueuePlacementRule实例:

 

(1)org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.QueuePlacementRule.Specified

 

 

如前所述,requestedQueue值为“default”,因此该rule返回值为“”(空字符串),继续下一个rule的队列选取。

 

(2)org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.QueuePlacementRule.User

 

 

该rule队列的选取规则特别简单:root. + 用户名。

 

这也就是上述验证过程中出现队列“root.hdfs”的原因所在。

 

结论

 

综上所述,用户通过Beeline连接HiveServer2后的队列选取,默认情况下受公平调度策略的影响,如果想通过hive-site.xml或者mapred-site.xml中指定mapreduce.job.queuename,有一个非常简单的办法就是将属性值hive.server2.map.fair.scheduler.queue(ConfVars.HIVE_SERVER2_MAP_FAIR_SCHEDULER_QUEUE)置为false,可以在hive-site.xml中指定或或者启动HiveServer2时通过参数指定,这样HiveServer2队列的选取就不再受公平调度策略的影响。


http://chatgpt.dhexx.cn/article/PaovpmhX.shtml

相关文章

beeline

beeline -u jdbc:hive2://192.168.1.102:10000 本文转自 yntmdr 51CTO博客,原文链接:http://blog.51cto.com/yntmdr/1730234,如需转载请自行联系原作者

Sentry Beeline

环境 Ubuntu STL 16.0.4 Hadoop 2.7.4 Hive 2.1.1 sentry 1.7.0 maven 3.5.0//注:伪分布式环境 安装maven 1.apache maven官网下载maven,用于编译sentry源码。 2.修改~/.bashrc文件,添加maven路径。 export MAVEN_…

beeline 使用

最近对hive设置权限,具体设置权限的方法请参考http://blog.csdn.net/qq_31382921/article/details/71133323,使用beeline的时候总会出现各种小问题,毕竟还是跟hive有点区别。 beeline 常用语法: 1. beeline -u “jdbc:hive2://n…

hive之beeline连接与操作

hive之beeline连接与操作 一、连接配置1.连接测试1.1前提1.2启动hive服务1.3测试连接 2.问题解决1.解决方式2.连接 二、操作1.beeline操作 一、连接配置 1.连接测试 1.1前提 hadoop集群、hive已正常安装,hadoop集群已启动 1.2启动hive服务 先启动 metastore 服…

Hive _ Hive2 新版连接工具 beeline 详解

Hive客户端工具后续将使用Beeline 替代HiveCLI ,并且后续版本也会废弃掉HiveCLI 客户端工具。 Beeline是Hive新的命令行客户端工具。 Beeline是从 Hive 0.11版本引入的。 HiveServer2 支持一个新的命令行Shell,称为Beeline,它是基于SQLLine …

Hive3详细教程(四)beeline的使用

beeline提供了命令行中以简单字符串拼凑的图形形式的表结构&#xff0c;如下图所示&#xff0c;比hive客户端有更好的用户体验度。 配置beeline连接&#xff0c;需要在hadoop的etc/core.site.xml文件中添加以下配置权限代码&#xff1a; <property><name>hadoop.…

Hive CLI和Beeline命令行的基本使用

一、Hive CLI 1.1 Help 使用 hive -H 或者 hive --help 命令可以查看所有命令的帮助&#xff0c;显示如下&#xff1a; usage: hive-d,--define <keyvalue> Variable subsitution to apply to hive commands. e.g. -d AB or --define AB --定义用户自定义变…

【Qt学习】OpenCV帧差法 车辆识别

目录 一&#xff1a;效果展示 二&#xff1a;Qt UI界面设计 三&#xff1a;源码分享 一&#xff1a;效果展示 使用Qt界面实现 点击 线程启动按钮播放视频 同时 左边界面显示原视频 右边界面显示车辆识别视频 初始界面 点击线程启动后&#xff0c;即可车辆识别 框选车辆 二&a…

【车辆识别】基于卷积神经网络yolov3识别车辆和车辆速度附matlab代码

1 简介 近年来,自动驾驶研究,智慧交通建设突飞猛进,车辆检测技术成为业界的研究热点.由于深度卷积神经网络具有一定的旋转与平移不变性等特点,在车辆检测任务中得到广泛应用,其中,YOLOv3(You Only Look Once version 3)算法是目前主要的检测算法之一. 2 部分代码 clearclc​%…

基于深度学习的车牌+车辆识别(YOLOv5和CNN)

yolov5车牌识别+车辆识别 行人识别yolov5和v7对比 订阅专栏获得源码(提供完整代码,无需看下文) 基于深度学习的车牌识别(YOLOv5和CNN) 目录 一、综述 二、车牌检测 一、综述 本篇文章是面向的是小白,想要学习深度学习上的应用,本文中目前应用了YOLO v5和CNN来对车牌进行…

Qt +opencv 通过级联分类器训练的模型进行识别(车辆识别+人脸识别)

有不对的或更好的方法欢迎交流 一些内容可参照这篇文章&#xff1a;https://blog.csdn.net/m0_64596200/article/details/126748697?spm1001.2014.3001.5502 训练好的的模型&#xff1a; 车辆识别模型&#xff1a;https://download.csdn.net/download/m0_64596200/86507302?…

机器学习1:OpenCV4.5.5加载xml进行车辆识别

深度学习准确率高识别效果好&#xff0c;但是对软硬件环境要求高&#xff0c;使用及部署有一定难度&#xff0c;应用受限。相比之下&#xff0c;机器学习效果差一个量级&#xff0c;但是计算量小&#xff0c;计算迅速&#xff0c;部署相对容易&#xff0c;尤其是在一些计算能力…

基于YOLOv5的车辆识别系统

基于YOLOv5的车辆识别系统&#xff08;展示&#xff09; 文章目录 基于YOLOv5的车辆识别系统&#xff08;展示&#xff09;前言车牌识别车型识别 前言 YOLO能实现图像或视频中物体的快速识别&#xff0c;在相同的识别类别范围和识别准确率条件下&#xff0c;YOLO识别速度最快。…

Review of Vehicle Recognition Technology - 车辆识别技术综述

Review of Vehicle Recognition Technology - 车辆识别技术综述 ZHANG Qiang, LI Jiafeng, ZHUO Li Faculty of Information Technology, Beijing University of Technology, Beijing 100124, China 北京工业大学信息学部&#xff0c;北京 100124 Beijing University of Tech…

deeplearning.36车辆识别YOLO算法实践

车辆识别 下载相关资料导入相关包数据集定义YOLO模型细节分类阈值过滤非最大值抑制非最大值抑制函数对所有框进行过滤 测试训练好的yolo模型定义分类、锚框、图像维度加载已经训练好的模型模型的输出转换为边界框过滤锚框实际图像中运行计算图实际预测一下 下载相关资料 下载本…

基于python的transform行人车辆识别

Transformer是一种神经网络体系结构&#xff0c;由于它能够有效地处理顺序数据中的长期依赖性&#xff0c;因此在自然语言处理(NLP)任务中受到欢迎。它还被应用于各种其他任务&#xff0c;包括图像分类、对象检测和语音识别。 在车辆和行人识别方面&#xff0c;transformer可用…

使用Python和docTR提取车辆识别号

VIN&#xff08;车辆识别号&#xff09;是一个17个字符的字符串&#xff0c;由数字和大写字母组成&#xff0c;用作汽车的指纹。 它可以帮助识别任何一辆汽车的寿命&#xff0c;并获得有关它的具体信息。该唯一标识符在制造过程中打印在车辆的某个位置&#xff0c;以便人们在租…

Opencv python之车辆识别项目(附代码)

文章目录 图片车辆识别视频车辆识别 图片车辆识别 根据文章搭建好环境后开始进行做项目link import sys import cv2 from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtGui import QIcon, QPalette, QPixmap, QBrush, QRegExpValidatorclass mainWin(QW…

java opencv 之车辆识别

上篇写了人脸识别&#xff0c;因为人脸识别的训练模型 haarcascade_frontalface_alt.xml 之类的官方已经训练好了可以直接用&#xff0c;但是我们要识别车辆或者其它物体就得训练模型&#xff0c;好在废了一点力 找到了一位大神训练好的模型 核心代码 几乎和人脸识别的差不多 s…

如何开发一个车牌识别,车牌识别系统,车辆识别系统毕业设计毕设作品

开发准备 第1步&#xff1a;准备好百度智能云的账号 第2步&#xff1a;在百度智能云领取对应AI开发的免费资源包 第3步&#xff1a;创建对应的应用&#xff0c;然后获取对应的开发信息&#xff0c;主要是下面几个 AppID&#xff1a;应用列表中 API Key&#xff1a;应用列表…