ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Hive 3.1.2安装全攻略:从环境准备到避坑实战

Hive 3.1.2安装全攻略:从环境准备到避坑实战 Hive这个东西我见过太多人卡在安装这一步了。明明Hadoop集群跑得好好的一装Hive就各种报错guava版本冲突、MetaStore连不上MySQL、schematool初始化失败、启动后一查日志全是Exception查个资料还东拼西凑。其实Hive安装本身不复杂难的是你永远在错误的信息里打转。这篇博文就是一篇能直接对着操作的Hive安装教程我会从环境准备、版本选型、核心配置到常见坑位全程用我自己实测的配置和排错思路讲一遍争取让你一次装通。这篇内容适合谁呢刚搭好Hadoop分布式集群、正准备在上面构建数仓的同学或者在已有集群里想新加一套Hive做离线分析的老手。不管哪种情况这篇教程的核心目标都是一样的让你拿到一个能稳定跑SQL、元数据不丢、重启不慌的Hive环境而不是那种装完只能拍张截图然后就废掉的demo。1. 先搞清楚Hive是干什么的再动手装1.1 Hive不是数据库而是一层“翻译器”很多新手最容易误会的一件事觉得Hive是个数据库。其实Hive本身不存数据它只是把SQL翻译成MapReduce、Tez或者Spark任务丢给底层的Hadoop集群去执行。数据真正存放的地方是HDFS计算资源来自YARN而Hive自己只负责管理两样东西元数据库名、表名、列名、分区信息、字段类型、表在HDFS上的存储路径执行计划把SQL语句解析成一套执行逻辑然后调度到集群上跑。我习惯把Hive比作一个“翻译官”。你对着它说SQL它转头跟YARN说“兄弟帮我跑个MapReduce任务”YARN再派给DataNode干活。它自己不干活但是离开它你想用SQL的方式操作HDFS上的批量数据就得自己写一堆Java程序。这也是为什么这么久了Hive仍然是离线数仓里最常用的查询入口之一。1.2 为什么安装Hive会牵扯到MySQL这里就有一个绕不开的问题元数据存哪里Hive自带一个内嵌的Derby数据库只能在本地单进程访问一旦你有两个会话想同时操作就直接锁住报错。生产环境必须用一个独立的元数据库来存这些信息业内普遍选的就是MySQL。Hive通过JDBC接口去连接MySQL把表结构、分区信息、统计信息这些全部写进MySQL的表中。所以你在安装Hive时不仅仅是解压一个压缩包还要去做三件事装好MySQL并创建Hive专用账号和独立的元数据库把MySQL的JDBC驱动jar包放进Hive的lib目录用Hive自带的schematool工具在MySQL里初始化一套Hive元数据表结构。这三步缺一个安装都会出问题。后面我会一步一步拆开讲尤其是schematool那一步特别容易因为字符集、权限或者驱动版本问题卡住。2. 版本选型与环境准备别在这一步省时间2.1 我实测的版本组合直接抄作业版本兼容性是Hive安装里最玄学的一件事。我踩过的最大的坑就是Hadoop 3.3.x配Hive 2.x跑起来各种奇奇怪怪的ClassNotFound最后全部推翻重来。现在我用的这套组合稳定跑了一年多你可以直接参考组件版本说明JDK1.8.0_202Hive 3.x对JDK 8支持最好别图新鲜用JDK 11Hadoop3.2.4也可以3.1.x但别低于2.9Hive3.1.2目前生产环境最主流版本坑少资料多MySQL5.7.35 或 8.0.x建议5.7初始化schema时兼容性更好mysql-connector-java5.1.49 或 8.0.26注意驱动类名和URL参数差别Hive 3.1.2对应的是Hadoop 3.x系列所以如果你的Hadoop还是2.x建议要么升级Hadoop要么换Hive 2.3.x不要混着用。JDK强烈建议用8虽然现在新出的很多组件都要求JDK 11了但Hive 3.1.2在JDK 8下的稳定性最好网上能搜到的资料也都是基于JDK 8的。2.2 安装包下载与目录规划下载Hive不复杂去Apache官网找一个稳定版本的binary包名字大概是apache-hive-3.1.2-bin.tar.gz大概几百MB解压出来就能用。不要下载源码包需要自己编译的那种除非你是真的要对源码做二次开发。解压目录我个人习惯放在/opt/module/下和大数据其他组件放一起方便统一管理mkdir -p /opt/module tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/module mv /opt/module/apache-hive-3.1.2-bin /opt/module/hive这里有一个细节容易被忽略Hive运行时会往/tmp目录写一堆临时文件如果你是用root用户跑的建议先把整个/opt/module/hive目录授权给一个专用的系统用户比如hadoop用户。不然你后面以root起动完再用hadoop用户去跑Hive会因为权限问题直接报Permission denied。2.3 前置检查你的HDFS和YARN真的能用吗装Hive之前我强烈建议你先做一轮Hadoop自检别急着解压Hive。Hive的所有计算任务最终都要落到Hadoop上如果底层的HDFS或者YARN本身就有问题后面排查起来你根本分不清是Hive的锅还是Hadoop的锅。自检就做三件事用hdfs dfs -ls /能正常查看根目录用yarn node -list能看到节点列表如果你开了NameNode、ResourceManager等服务jps进程都在。这三条如果都通过再继续往下走。否则先解决Hadoop集群的问题。我自己见过太多同学一上来就报Hive的错查了半天才发现是HDFS没走安全模式、NameNode都在反复重启。3. 核心配置文件详解这一章是整个教程的灵魂3.1 环境变量配置把Hive的bin目录加进PATH这一步没什么技术含量但漏了就很尴尬。你打开终端敲hive结果提示command not found还以为自己装错了其实就是环境变量没配好。编辑/etc/profileexport HIVE_HOME/opt/module/hive export PATH$PATH:$HIVE_HOME/bin然后执行source /etc/profile再用hive --version验证一下。能正常打印出Hive版本号说明基础环境OK接下来才是重头戏。3.2 hive-site.xml从零手写一份靠谱的配置Hive解压之后默认是没有hive-site.xml的只有一份hive-default.xml.template模板文件。很多人直接把模板文件改名copy过来用结果启动时日志刷出几百行WARN而且模板里有一堆默认指向本地Derby的配置甚至在本地直接创建一个叫metastore_db的目录看起来很干净实际就是个坑。我建议手写一份精简的hive-site.xml只保留和生产环境真正相关的配置项全部放在$HIVE_HOME/conf下。下面这套是我实际生产环境里常用的最小配置configuration !-- 元数据存储在MySQL上 -- property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://localhost:3306/hive?createDatabaseIfNotExisttrueuseSSLfalseamp;serverTimezoneAsia/Shanghai/value /property property namejavax.jdo.option.ConnectionDriverName/name valuecom.mysql.cj.jdbc.Driver/value /property property namejavax.jdo.option.ConnectionUserName/name valuehive/value /property property namejavax.jdo.option.ConnectionPassword/name valueHive123456/value /property !-- MetaStore服务地址客户端通过这个地址访问元数据 -- property namehive.metastore.uris/name valuethrift://node1:9083/value /property !-- 关闭schema自动验证避免版本不一致时报错 -- property namehive.metastore.schema.verification/name valuefalse/value /property !-- 显示当前库名和列头主要是方便命令行使用 -- property namehive.cli.print.current.db/name valuetrue/value /property property namehive.cli.print.header/name valuetrue/value /property /configuration这里我要重点解释两个关键点。第一个是javax.jdo.option.ConnectionURL。如果你是MySQL 8.0必须在URL里加上serverTimezone参数否则驱动程序初始化时会报时区异常。同时你还需要在DriverName里写com.mysql.cj.jdbc.Driver这是MySQL 8.0的驱动入口。如果你用的是MySQL 5.7DriverName则写com.mysql.jdbc.DriverURL里的serverTimezone可以去掉。第二个是hive.metastore.uris。这一项决定你是以什么模式连接元数据。如果你是单机测试可以不填这一项Hive会在当前机器内嵌一个MetaStore。但只要你开了HiveServer2让其他客户端远程连接就必须把MetaStore作为一个独立服务跑在集群指定节点上并在这里填上thrift://node1:9083这样的地址。我生产环境里就是node1专门跑MetaStore其他节点通过这个地址去读取元数据。3.3 解决guava版本冲突安装中最容易翻车的一环Hive能解压安装但真正跑起来的时候第一个绕不开的坑就是guava版本冲突。Hadoop的lib目录里有一个guava包Hive的lib目录里也有一个guava包两个版本不一致启动的时候就会出现NoSuchMethodError、NoClassDefFoundError一看日志以为是代码错了其实只是guava不兼容。最简单的解决方式就是“统一”。你先看Hadoop的guava版本ls $HADOOP_HOME/share/hadoop/common/lib/ | grep guava然后把Hive lib目录里的guava删掉把Hadoop目录里的guava拷贝过来或者反过来总之保证两边的jar包版本完全一致。我在3.1.2版本里遇到的情况是Hive自带guava-10.0.jar和guava-19.0.jar而Hadoop 3.2.4用的是guava-27.0-jre.jar直接统一成Hadoop的27版本问题解决。这里还有一个隐藏细节mysql-connector-java驱动也必须放进Hive的lib目录。如果你下载的是mysql-connector-java-8.0.26.jar放到$HIVE_HOME/lib下之后千万别忘了之前配置里的DriverName写的是com.mysql.cj.jdbc.Driver。很多同学把jar包丢进去就以为大功告成了结果启动时还在报找不到驱动类就是因为驱动类和jar包版本对不上。3.4 日志目录和内存参数提前配好不然后悔Hive启动时如果你什么配置都不改默认会在当前终端直接打印日志而且日志文件可能落到/tmp下等你想查历史问题的时候早就被系统自动清理了。我一般会在$HIVE_HOME/conf下新建一个hive-env.sh内容参照模板改export HADOOP_HOME/opt/module/hadoop export HIVE_CONF_DIR/opt/module/hive/conf export HIVE_LOG_DIR/opt/module/hive/logs再顺手设置一下Hive进程的堆内存。HiveServer2在默认情况下可能因为堆内存不足直接挂掉尤其是并发一多的时候。在hive-env.sh里加上export HADOOP_HEAPSIZE2048注意这个是针对Hive自身进程的堆大小不是YARN上的MapReduce任务的堆大小。不要把它等同于Hadoop集群的资源配置否则你会误判内存瓶颈。4. 元数据库初始化与启动冒烟测试4.1 在MySQL里创建Hive专用账号和元数据库在开始初始化元数据之前先准备MySQL这边的环境。登录MySQLCREATE DATABASE hive CHARACTER SET utf8; CREATE USER hive% IDENTIFIED BY Hive123456; GRANT ALL PRIVILEGES ON hive.* TO hive%; FLUSH PRIVILEGES;这边有一个非常重要的小细节建库字符集最好用utf8而不要用utf8mb4。我在早期安装的时候用了utf8mb4结果schematool初始化到一半直接报错提示Specified key was too long; max key length is 1000 bytes。这是因为Hive元数据表里有些索引字段长度比较长utf8mb4每个字符占4字节索引键长度就会超限。很多教程不会提及这一点但你在第一次初始化schema时大概率会碰到。4.2 schematool初始化这一步卡住的人最多配置好MySQL和hive-site.xml之后就可以初始化元数据库了。这一步会往MySQL的hive库里创建几十张表包括DBS、TBLS、PARTITIONS、SDS这些核心元数据表。执行命令如下/opt/module/hive/bin/schematool -dbType mysql -initSchema -verbose解释一下这个命令的作用-dbType mysql表示告诉schematool你要针对MySQL来建表-initSchema表示初始化schema-verbose表示打印详细日志方便你出问题时有足够的信息去排查。正常情况下看到一行类似Initialization script completed的提示就说明成功了。如果中途报错最稳妥的办法是直接删掉之前建好的hive数据库重新建一遍再跑一次不要试图在脏数据基础上做修复。我见过不少人在初始化失败后反复去手工改MySQL表结构最后越弄越乱不如重置来得干净。4.3 第一次启动先跑CLI验证基本功能初始化完成之后先别急着启动HiveServer2直接用命令行模式跑一下验证基础环境是否完整hive进入Hive命令行后依次执行CREATE DATABASE test; USE test; CREATE TABLE student(id INT, name STRING); INSERT INTO student VALUES(1, zhangsan); SELECT * FROM student;如果你能成功执行说明Hive已经能正常将SQL翻译成MapReduce任务并且元数据也已经正确写入MySQL了。你还可以顺手在MySQL里看一下SELECT * FROM hive.TBLS;能看到刚才建的student表说明MetaStore写入没问题。5. 集群模式下启动MetaStore和HiveServer25.1 为什么生产环境要单独起MetaStore服务CLI模式只能说明Hive单机能跑但真实的数仓环境里肯定不止一个客户端连到Hive上执行SQL。你需要把HiveServer2跑起来让Beeline、DataGrip、DBeaver或者代码里的JDBC都能连上来。而HiveServer2要正常工作它就得通过MetaStore服务去读取元数据。所以生产环境的标准模式是MetaStore负责和MySQL的元数据库打交道HiveServer2负责接收客户端SQL请求并调用底层计算引擎多个客户端连HiveServer2时MetaStore统一提供元数据读写不会互相干扰。启动方式我用的是nohup丢后台同时把日志单独切出来nohup /opt/module/hive/bin/hive --service metastore /opt/module/hive/logs/metastore.log 21 nohup /opt/module/hive/bin/hive --service hiveserver2 /opt/module/hive/logs/hiveserver2.log 21 启动以后别急着连先检查两个端口netstat -an | grep 9083 netstat -an | grep 10000MetaStore监听9083HiveServer2监听10000。如果你端口没起来直接去看对应的日志文件后边我会列常见问题。5.2 用Beeline验证远程连接服务起来以后用Hive自带的Beeline客户端验证一下/opt/module/hive/bin/beeline -u jdbc:hive2://node1:10000/default -n hive能进入jdbc:hive2://的提示符就说明HiveServer2已经把服务暴露出来了。在这里执行一条show databases如果返回了default和test两个库说明你从客户端到MetaStore再到MySQL的整个链路全部打通。5.3 本地工具连接HiveServer2的配置很多同学装了Hive后却不会从开发工具连接。以DataGrip为例驱动选HiveJDBC URL填jdbc:hive2://node1:10000/default用户名密码填你启动HiveServer2时指定的认证方式。如果Hive没有启用认证用户名随便填一个非空字符串就行密码留空也能进。这里稍微提醒一句HiveServer2默认不开启认证在局域网内做开发测试没问题但如果你的集群是对外打开的建议至少在DriverManager层面做一些最小化的授权否则风险很大。生产环境我一般会在前面加一层认证或者防火墙白名单限制访问端。6. 安装过程中最容易踩的坑全部整理给你6.1 初始化schema报错Access denied或者Unknown database这两个报错几乎是Hive安装阶段出现频率最高的。Access denied的意思是你在hive-site.xml里配置的用户名或密码不正确或者MySQL那边没有给这个账号足够的权限。先到MySQL里手工执行一下SELECT User, Host FROM mysql.user;看看hive用户是否存在再手动用hive账号去连接一次MySQL确认密码无误。Unknown database比较低级一般是MySQL里没手动建hive库或者你用了URL里的createDatabaseIfNotExisttrue但当前的这个hive账号不具备创建数据库的权限。解决方式就是回到4.1节创建数据库并授权一条龙做完整。6.2 启动时NoClassDefFoundError八成是guava的问题这个问题我在3.3节已经重点说了这里再给一个快速判断方法报错堆栈里有一行是com.google.common.base.Preconditions或者com.google.common.collect.*基本就是guava冲突。删掉Hive lib下的旧guava换成和Hadoop完全一致的版本问题就没了。另外还有一个容易误判的是jline包冲突。报错信息里如果出现jline/console/completer说明Hive里的jline jar包跟Hadoop里另一个路径下的jline版本有冲突。处理方式跟guava一样保证Hive lib里的叫jline-2.14.jar就能匹配Hive 3.1.2的预期不用额外动。6.3 Hive能启动但一执行SQL就报OutOfMemoryError如果你在建表或者执行INSERT时看到java.lang.OutOfMemoryError: Java heap space通常不是Hive本身挂了而是YARN上负责跑MapReduce任务的NodeManager可用内存不够或者YARN给单个container分配的内存上限太小。这时候你要去调整的是yarn-site.xml里的几个参数yarn.nodemanager.resource.memory-mb、yarn.scheduler.maximum-allocation-mb以及Hive提交的MapReduce任务内存参数mapreduce.map.memory.mb、mapreduce.reduce.memory.mb。简单来说先确认NodeManager还有没有空闲内存再看有没有其他任务占满了资源池。不是Hive安装的问题但经常被误当成Hive的问题去排查。6.4 中文注释和分区乱码这一坑藏得比较深我之前提到过建库字符集用utf8不要用utf8mb4但还有一个更隐蔽的问题如果你在Hive里建表时给字段或表添加了中文注释然后用SHOW CREATE TABLE或者从MySQL里查看描述信息时发现中文乱码那大概率是Hive元数据表里某一列使用的字符集不是utf8。你可以登录MySQL查看SHOW CREATE TABLE hive.COLUMNS_V2;如果表结构里的COMMENT字段字符集是latin1那中文写进去就全是乱码。解决办法是把Hive元数据中跟COMMENT相关的表字段统一改成utf8比如ALTER TABLE hive.COLUMNS_V2 MODIFY COLUMN COMMENT VARCHAR(256) CHARACTER SET utf8;除此之外分区值如果包含中文也可能出现乱码分区甚至有人遇到HDFS目录名都变成乱码的情况。这时候你先确认Hive生成的HDFS路径是否正确再看MySQL里的PARTITIONS表是否与HDFS目录对应。如果只是元数据里的中文乱码你把对应字段的字符集改掉就行如果是HDFS上真的多出了一些目录就要手工删除无用的乱码分区目录并修复元数据表记录。这个操作比较敏感动手前最好先备份元数据库。7. 安装完成后你可能会马上撞上的几个衍生问题7.1 还没跑几个任务怎么就有了几百个小文件Hive安装完第一件事往往是导入测试数据或者跑几条SQL。跑不了几轮你再看HDFS上的目录一堆小文件每个才几KB或者几百KB。这就是大数据领域的老大难问题小文件。小文件本身不是Hive安装能解决的但你在安装阶段提前做好心理准备和参数配置后面能轻松很多。我一般会在hive-site.xml里加上几个reduce输出合并参数property namehive.merge.mapfiles/name valuetrue/value /property property namehive.merge.mapredfiles/name valuetrue/value /property property namehive.merge.size.per.task/name value134217728/value /propertyhive.merge.mapfiles控制Map-only任务结束后是否合并小文件hive.merge.mapredfiles控制MapReduce任务结束后是否合并输出小文件hive.merge.size.per.task是合并后每个文件期望的大小单位是字节我一般设128MB。这个配置在安装阶段就顺手做好比后面数据越堆越多再想办法省力得多。7.2 Flink sink到Hive表数据怎么就是不进去还有一个搜得很热的问题用Flink往Hive表里sink数据任务明明跑成功了但表里查不到数据。这个问题跟Hive安装的关联在于你hive-site.xml里的元数据连接有没有配对Flink是不是走了一套独立的HiveCatalog。最常见的两个原因第一Flink运行的机器上缺少Hive的hive-site.xml或者配置里的hive.metastore.uris没有指向正确的MetaStore地址。第二Flink写的是分区表但没开启流式分区提交或者写到HDFS之后没有刷新分区导致HiveMetaStore里的分区信息跟HDFS目录对不上。排查时先检查MetaStore日志里有没有报错再确认HDFS目录下是否真的有数据文件生成。如果文件已经生成了那问题大概率在分区感知层面。7.3 顺便聊一句Hive和Doris该怎么选很多人在离线分析场景里会纠结用Hive还是Doris。我的判断很直接Hive依然是离线数仓ETL的第一层最稳的选择它生态成熟、门槛低、能挂各种执行引擎而且安装部署资料多。Doris强在实时多维分析和点查更适合做OLAP加速层你需要做报表查询时再把数据同步到Doris而不是拿Doris替代Hive做全量离线计算。如果你刚装好Hive接下来最值得投入时间的是把底层HDFS的目录规划、分区策略、小文件合并策略想清楚。不然数据量一上来再回过头来调这些东西代价要大得多。8. 我个人安装Hive的一点经验收尾文章写到这里核心的安装流程和避坑点都讲得差不多了。最后分享一个我自己常用的安装后排错顺序帮助你在慌乱的时候理清思路先看端口有没有起来再看日志有没有关键字再看MySQL里有没有对应元数据记录最后才去考虑SQL和业务层面。按照这个顺序排查绝大多数问题都能在5分钟内定位到根源。再补充一个小技巧装完之后把hive-site.xml里你自己修改的配置项单独整理成一份清单用注释标明每一行的作用方便后续维护。尤其是Hive这种在团队里长期用下去的组件配置项动过一次三个月后谁都记不清当初是怎么配的了。如果你在安装过程中还有卡在某个报错里出不来的建议先把完整的堆栈日志打开从第一行开始看而不是只看最后一行。Hive的报错信息很啰嗦但最关键的原因往往就在最靠前的几行里。大概就是这样。祝你一次装通。
返回列表