1. 从零开始的Hive部署为什么选择Ubuntu 16.04如果你正在大数据领域摸索或者你的项目需要一个本地的、可控的Hive环境来做数据仓库的开发和测试那么自己动手在Ubuntu上部署一套Hive几乎是每个数据工程师都会经历的“成人礼”。我选择Ubuntu 16.04 LTS作为起点并不是因为它最新恰恰相反是因为它足够经典和稳定。很多企业遗留的生产环境、教程文档甚至是某些特定版本的Hadoop生态组件对Ubuntu 16.04的支持和兼容性经过了时间的考验踩坑的路径相对清晰解决方案也更容易找到。这能让你把精力集中在理解Hive本身而不是和最新的系统版本、依赖库版本作斗争。Hive是什么简单说它是一套构建在Hadoop之上的数据仓库工具。它允许你使用一种类似SQL的语言HiveQL去查询和分析存储在HDFSHadoop分布式文件系统上的海量数据。对于熟悉传统数据库如MySQL的开发者来说Hive极大地降低了进入大数据处理领域的门槛。但请注意Hive本身不存储数据也不直接执行计算它更像一个翻译官和调度员将你的SQL“翻译”成一系列的MapReduce或Tez任务提交给Hadoop集群去执行。因此安装Hive的前提是你已经有一个可以正常工作的Hadoop环境伪分布式或完全分布式。本系列文章我们就从最基础的伪分布式Hadoop环境开始一步步在Ubuntu 16.04上搭建起一个功能完整的Hive。2. 环境准备与前置条件检查在开始安装Hive之前我们必须确保地基是牢固的。一个混乱的初始环境是后续所有诡异问题的根源。这里我假设你已经有一台安装了纯净Ubuntu 16.04 LTS的机器物理机或虚拟机均可。我们将从系统层面开始一步步搭建起Hive所需的所有依赖。2.1 系统基础配置与Java环境搭建Hadoop和Hive都是基于Java开发的所以JDK是我们的第一块基石。我强烈建议使用Oracle JDK 8这是Hadoop生态圈历史最悠久、兼容性最广的版本。在Ubuntu 16.04上我们可以通过PPA源来安装。首先更新系统包列表并安装一些基础工具sudo apt-get update sudo apt-get install -y vim wget curl ssh pdshpdsh是一个并行分布式shell工具在管理多节点集群时很有用单机环境先装上也无妨。接下来添加Oracle JDK的PPA并安装sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install -y oracle-java8-installer安装过程中会弹出图形界面许可协议按Tab键切换到“OK”再回车然后选择“Yes”同意即可。安装完成后配置JAVA_HOME环境变量。这是至关重要的一步很多后续问题都源于此变量配置错误。# 查找JDK的安装路径通常类似 /usr/lib/jvm/java-8-oracle sudo update-alternatives --config java # 记下路径例如 /usr/lib/jvm/java-8-oracle/jre/bin/java # 那么JAVA_HOME就是 /usr/lib/jvm/java-8-oracle # 编辑环境变量配置文件 sudo vim /etc/profile在文件末尾添加以下内容请将路径替换为你实际查到的export JAVA_HOME/usr/lib/jvm/java-8-oracle export PATH$PATH:$JAVA_HOME/bin保存退出后执行source /etc/profile使配置立即生效。然后验证java -version echo $JAVA_HOME你应该能看到Java版本为1.8.x并且JAVA_HOME变量被正确设置。注意有些教程会建议修改~/.bashrc这只对当前用户生效。为了确保所有用户特别是以后以hadoop用户运行的服务都能正确读取到环境变量我习惯将其配置在/etc/profile中。这是一个个人偏好但也避免了后续切换用户时可能遇到的“命令找不到”的坑。2.2 创建专用用户与SSH免密登录配置为了安全和管理方便我们不应该使用root用户来运行Hadoop和Hive。创建一个专用的hadoop用户是个好习惯。sudo adduser hadoop按照提示设置密码并填写一些无关紧要的信息即可。之后我们将在这个用户下进行所有操作。Hadoop的脚本如启动集群需要管理节点间无密码的SSH通信。即使在单机伪分布式模式下它也需要能通过SSH连接到localhost。因此我们需要为hadoop用户配置SSH免密登录到本机。首先切换到hadoop用户并生成SSH密钥对su - hadoop ssh-keygen -t rsa -P -f ~/.ssh/id_rsa-P 表示空密码-f指定密钥文件。这将在/home/hadoop/.ssh/目录下生成id_rsa私钥和id_rsa.pub公钥。然后将公钥追加到授权密钥文件中并设置正确的权限cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys现在尝试用hadoop用户SSH登录本机ssh localhost如果配置正确你应该不需要输入密码就能直接登录。首次连接会询问是否将主机加入已知列表输入yes即可。成功后输入exit退出SSH会话回到原来的shell。实操心得如果这一步失败提示需要密码最常见的原因是.ssh目录或authorized_keys文件的权限不对。确保/home/hadoop/.ssh目录权限为700 (drwx------)authorized_keys文件权限为600 (-rw-------)。可以使用ls -la ~/.ssh命令检查。3. Hadoop伪分布式集群搭建详解正如前文所述Hive的运行依赖于Hadoop。我们将搭建一个伪分布式模式的Hadoop集群这意味着所有的Hadoop守护进程NameNode, DataNode, ResourceManager, NodeManager都运行在同一台机器上但它们在逻辑上仍然以分布式架构运行。这是学习和测试的最佳方式。3.1 Hadoop安装与核心配置文件解析首先以hadoop用户身份下载Hadoop。我们选择2.7.x系列的一个稳定版本比如2.7.7。你可以在清华大学开源镜像站找到更快的下载源。cd /home/hadoop wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz下载完成后解压并移动到合适的目录我习惯放在/usr/local下并创建软链接方便管理sudo tar -xzf hadoop-2.7.7.tar.gz -C /usr/local cd /usr/local sudo mv hadoop-2.7.7 hadoop sudo chown -R hadoop:hadoop hadoop接下来是配置的核心部分。Hadoop的配置文件位于/usr/local/hadoop/etc/hadoop/目录下我们需要修改其中几个关键文件。1. 配置Hadoop环境变量 (hadoop-env.sh)编辑/usr/local/hadoop/etc/hadoop/hadoop-env.sh找到设置JAVA_HOME的行取消注释并修改为你的JDK路径export JAVA_HOME/usr/lib/jvm/java-8-oracle如果文件中没有明确的JAVA_HOME行直接在文件开头附近添加即可。2. 核心配置 (core-site.xml)这个文件配置Hadoop的核心参数最重要的是定义HDFS的默认文件系统地址fs.defaultFS和临时文件目录。 编辑/usr/local/hadoop/etc/hadoop/core-site.xml在configuration标签内添加configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/home/hadoop/tmp/value /property /configurationfs.defaultFS告诉Hadoop客户端默认的文件系统是HDFS地址在localhost的9000端口。hadoop.tmp.dir是Hadoop许多进程如DataNode存储临时数据的目录务必确保hadoop用户对这个目录有读写权限。3. HDFS配置 (hdfs-site.xml)这个文件配置HDFS相关的参数。在伪分布式模式下我们设置数据块的副本数为1因为只有一台机器。 编辑/usr/local/hadoop/etc/hadoop/hdfs-site.xmlconfiguration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name valuefile:/home/hadoop/hdfs/name/value /property property namedfs.datanode.data.dir/name valuefile:/home/hadoop/hdfs/data/value /property /configurationdfs.namenode.name.dir和dfs.datanode.data.dir分别指定了NameNode和DataNode存储元数据和实际数据块的本地目录。请预先创建这些目录并赋予权限mkdir -p /home/hadoop/hdfs/{name,data}4. YARN配置 (yarn-site.xml)YARN是Hadoop的资源调度框架。Hive在默认情况下会将查询转换为MapReduce任务这些任务由YARN来调度执行。 编辑/usr/local/hadoop/etc/hadoop/yarn-site.xmlconfiguration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.nodemanager.aux-services.mapreduce.shuffle.class/name valueorg.apache.hadoop.mapred.ShuffleHandler/value /property property nameyarn.resourcemanager.hostname/name valuelocalhost/value /property /configuration5. MapReduce配置 (mapred-site.xml)首先需要从模板文件复制一份cp /usr/local/hadoop/etc/hadoop/mapred-site.xml.template /usr/local/hadoop/etc/hadoop/mapred-site.xml然后编辑mapred-site.xml指定MapReduce框架使用YARNconfiguration property namemapreduce.framework.name/name valueyarn/value /property /configuration最后将Hadoop的bin和sbin目录添加到hadoop用户的PATH环境变量中。编辑/home/hadoop/.bashrc在末尾添加export HADOOP_HOME/usr/local/hadoop export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin执行source ~/.bashrc使其生效。3.2 HDFS格式化与集群启动验证在首次启动Hadoop之前必须格式化HDFS的NameNode。这是一个危险操作它会清空NameNode上所有的元数据。只有在第一次安装或者确定要完全重置HDFS数据时才执行。hdfs namenode -format你会看到大量日志输出最后几行如果出现“Storage directory ... has been successfully formatted”则表示成功。现在可以启动HDFS和YARN了。Hadoop提供了脚本来启动所有相关进程。# 启动HDFS start-dfs.sh # 启动YARN start-yarn.sh你可以使用jps命令来检查Java进程是否都正常启动了jps你应该能看到类似以下的进程NameNode DataNode SecondaryNameNode ResourceManager NodeManager Jps如果缺少某个进程比如DataNode没起来可以去/usr/local/hadoop/logs目录下查看对应的日志文件如hadoop-hadoop-datanode-*.log里面通常有详细的错误信息。常见问题包括目录权限不足、端口被占用、配置文件有拼写错误等。验证HDFS是否正常工作可以访问NameNode的Web UIhttp://localhost:50070。你应该能看到一个管理界面显示集群的概览信息。同样YARN的ResourceManager UI在http://localhost:8088。为了后续Hive测试方便我们可以在HDFS上创建一个临时目录并赋予hadoop用户写入权限hdfs dfs -mkdir -p /user/hadoop hdfs dfs -chown hadoop:hadoop /user/hadoop至此一个可用的伪分布式Hadoop集群就搭建完成了。这是Hive能够运行的基石。4. Hive 4.2.0 安装与元数据存储配置有了Hadoop我们终于可以开始安装Hive了。Hive 4.2.0是一个相对较新的稳定版本修复了许多旧版本的bug并引入了一些新特性。Hive需要一个数据库来存储它的“元数据”Metadata也就是表的结构、字段类型、分区信息等。默认情况下Hive使用内嵌的Derby数据库但这只适用于单会话、单用户的测试场景。一旦你开启第二个Hive CLI会话就会报错。因此在生产或严肃的开发和测试中我们通常使用MySQL或PostgreSQL作为元数据库。这里我们选择MySQL。4.1 MySQL元数据库安装与初始化首先安装MySQL服务器和客户端sudo apt-get update sudo apt-get install -y mysql-server mysql-client安装过程中会提示你设置root用户的密码请务必记住。安装完成后登录MySQL为Hive创建一个专用的数据库和用户mysql -u root -p输入你设置的root密码后进入MySQL命令行执行以下SQL-- 创建一个名为hive_metastore的数据库字符集使用utf8 CREATE DATABASE hive_metastore DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- 创建一个名为hiveuser的用户并设置密码这里示例密码为‘hivepassword’请务必修改 CREATE USER hiveuser% IDENTIFIED BY hivepassword; -- 授予hiveuser用户对hive_metastore数据库的所有权限 GRANT ALL PRIVILEGES ON hive_metastore.* TO hiveuser%; -- 授予hiveuser用户授予权限的权限某些版本的Hive初始化脚本需要 GRANT ALL PRIVILEGES ON hive_metastore.* TO hiveuserlocalhost IDENTIFIED BY hivepassword; -- 刷新权限使更改生效 FLUSH PRIVILEGES; -- 退出MySQL EXIT;重要安全提示上述配置中‘hiveuser’‘%’允许从任何主机连接密码也是示例。在生产环境中你应该限制访问IP例如‘hiveuser’‘localhost’并使用强密码。接下来我们需要下载MySQL的Java连接驱动JDBC Driver。去MySQL官网或使用wget下载对应版本的驱动jar包例如mysql-connector-java-5.1.47.jar并将其放置到Hive的lib目录下。cd /home/hadoop wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.47.tar.gz tar -xzf mysql-connector-java-5.1.47.tar.gz sudo cp mysql-connector-java-5.1.47/mysql-connector-java-5.1.47-bin.jar /usr/local/hive/lib/请根据你下载的实际版本调整命令中的版本号。4.2 Hive软件包部署与关键配置现在下载并安装Hive。我们到Apache镜像站下载Hive 4.2.0。cd /home/hadoop wget https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-4.2.0/apache-hive-4.2.0-bin.tar.gz sudo tar -xzf apache-hive-4.2.0-bin.tar.gz -C /usr/local cd /usr/local sudo mv apache-hive-4.2.0-bin hive sudo chown -R hadoop:hadoop hive同样创建软链接或直接将Hive的bin目录加入PATH。编辑/home/hadoop/.bashrc添加export HIVE_HOME/usr/local/hive export PATH$PATH:$HIVE_HOME/bin执行source ~/.bashrc。Hive的核心配置文件是$HIVE_HOME/conf/hive-site.xml。默认情况下这个文件不存在我们需要从模板创建并编辑它。cd /usr/local/hive/conf cp hive-default.xml.template hive-site.xmlhive-default.xml.template包含了所有配置项及其默认值但非常冗长。我们最好创建一个新的、简洁的hive-site.xml来覆盖我们关心的配置。你可以先备份原始的模板然后直接编辑hive-site.xml或者更推荐的做法是直接新建一个hive-site.xml因为Hive会加载这个文件并且它的配置优先级很高。用编辑器新建/编辑/usr/local/hive/conf/hive-site.xml填入以下内容。请务必将javax.jdo.option.ConnectionPassword的值替换为你为hiveuser设置的密码。?xml version1.0 encodingUTF-8 standaloneno? ?xml-stylesheet typetext/xsl hrefconfiguration.xsl? configuration !-- 连接元数据库的URL -- property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://localhost:3306/hive_metastore?createDatabaseIfNotExisttrueamp;useSSLfalseamp;characterEncodingUTF-8/value descriptionJDBC connect string for a JDBC metastore/description /property !-- 连接元数据库的驱动类 -- property namejavax.jdo.option.ConnectionDriverName/name valuecom.mysql.jdbc.Driver/value descriptionDriver class name for a JDBC metastore/description /property !-- 连接元数据库的用户名 -- property namejavax.jdo.option.ConnectionUserName/name valuehiveuser/value descriptionusername to use against metastore database/description /property !-- 连接元数据库的密码 -- property namejavax.jdo.option.ConnectionPassword/name valuehivepassword/value !-- 请修改为你的密码 -- descriptionpassword to use against metastore database/description /property !-- Hive数据在HDFS上的存储路径 -- property namehive.metastore.warehouse.dir/name value/user/hive/warehouse/value descriptionlocation of default database for the warehouse/description /property !-- 在命令行中显示当前数据库名 -- property namehive.cli.print.current.db/name valuetrue/value descriptionWhether to include the current database in the Hive prompt./description /property !-- 在命令行中显示表头信息 -- property namehive.cli.print.header/name valuetrue/value descriptionWhether to print the names of the columns in query output./description /property !-- 指定Hive执行引擎为MapReduce (Tez或Spark是其他选项) -- property namehive.execution.engine/name valuemr/value descriptionChooses execution engine. Options are: mr (MapReduce), tez, spark./description /property /configuration配置文件中有几个关键点useSSLfalse在测试环境可以禁用SSL连接避免证书问题。生产环境应启用。createDatabaseIfNotExisttrue如果hive_metastore数据库不存在JDBC连接时会自动创建。hive.metastore.warehouse.dir这是Hive中创建的表的默认存储位置位于HDFS上。我们稍后需要创建这个目录并赋权。4.3 元数据库初始化与目录权限设置在启动Hive之前必须初始化它的元数据库。Hive提供了schematool来完成这个工作。这个工具会连接到我们配置的MySQL数据库创建一系列存储元数据的表。cd /usr/local/hive bin/schematool -dbType mysql -initSchema如果一切顺利你会看到“Initialization script completed”和“schemaTool completed”的成功信息。此时登录MySQL查看hive_metastore数据库应该能看到很多以TBLS、COLUMNS_V2等命名的表。接下来在HDFS上创建Hive的仓库目录并赋予hadoop用户也就是运行Hive进程的用户写权限hdfs dfs -mkdir -p /user/hive/warehouse hdfs dfs -chown -R hadoop:hadoop /user/hive hdfs dfs -chmod -R 775 /user/hive/warehouse-chmod 775使得同组用户也有写权限这在多用户环境下有时是必要的。5. Hive CLI启动、基础测试与排错指南经过漫长的配置终于到了激动人心的启动时刻。Hive最传统的交互方式是通过命令行界面CLI。5.1 启动Hive CLI并执行首个查询确保Hadoop集群start-dfs.sh和start-yarn.sh正在运行。然后切换到hadoop用户直接输入hive命令su - hadoop hive如果一切配置正确你会看到Hive的命令行提示符并且前面会显示当前数据库默认为default这是因为我们设置了hive.cli.print.current.dbtrue。hive (default)现在让我们执行一些最基本的操作来验证Hive是否工作正常。1. 显示所有数据库show databases;你应该能看到一个名为default的数据库。2. 创建一个测试表CREATE TABLE IF NOT EXISTS test_hive (id INT, name STRING) COMMENT This is a test table ROW FORMAT DELIMITED FIELDS TERMINATED BY \t STORED AS TEXTFILE;这条命令创建了一个名为test_hive的内部表有两个字段id和name字段间用制表符分隔以文本文件格式存储。3. 查看创建的表show tables;你应该能看到test_hive表。4. 向表中插入一条测试数据在Hive中直接使用INSERT INTO ... VALUES语句效率很低因为它会启动一个MapReduce作业。对于测试我们可以用INSERT ... SELECT或者更简单地直接加载本地文件。我们先插入一条数据看看INSERT INTO TABLE test_hive VALUES (1, Alice);这会触发一个MapReduce作业。你可以在YARN的Web UI (http://localhost:8088)上看到这个作业的运行情况。执行完成后查询数据SELECT * FROM test_hive;如果配置了hive.cli.print.headertrue你会看到带表头的输出test_hive.id test_hive.name 1 Alice5. 查看表在HDFS上的存储位置DESCRIBE FORMATTED test_hive;在输出信息中找到Location一项它的值应该类似hdfs://localhost:9000/user/hive/warehouse/test_hive。你可以用HDFS命令验证文件是否存在hdfs dfs -ls /user/hive/warehouse/test_hive应该能看到一个类似于000000_0的文件这就是我们插入的数据文件。5.2 常见启动失败问题与排查思路理想很丰满现实往往会在第一步hive命令就给你一个下马威。下面是一些我踩过的坑和排查方法问题1启动Hive时报错java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf原因通常是因为HADOOP_HOME环境变量没有正确设置或者Hive找不到Hadoop的jar包。解决确认echo $HADOOP_HOME输出正确路径。检查/usr/local/hive/bin/hive这个shell脚本。旧版本Hive可能需要手动在脚本里设置HADOOP_HOME。但更通用的方法是确保hadoop命令在PATH中且能正常执行。Hive脚本会通过which hadoop来定位Hadoop。将Hadoop的共享库比如$HADOOP_HOME/share/hadoop/common/*.jar添加到Hive的CLASSPATH中。一种粗暴但有效的方法是在hive-env.sh中设置如果该文件不存在从模板复制hive-env.sh.templateexport HADOOP_HOME/usr/local/hadoop export HIVE_CONF_DIR/usr/local/hive/conf export HIVE_AUX_JARS_PATH/usr/local/hive/lib问题2执行Hive命令时连接元数据库失败报错Failed to get schema version.或Communications link failure原因Hive无法连接到MySQL元数据库。解决检查MySQL服务sudo systemctl status mysql确保MySQL正在运行。检查连接参数仔细核对hive-site.xml中的ConnectionURL、ConnectionUserName、ConnectionPassword。特别是密码是否正确。检查MySQL用户权限确认hiveuser用户是否可以从localhost访问hive_metastore数据库。可以尝试用mysql -u hiveuser -p登录MySQL。检查MySQL绑定地址MySQL默认可能只绑定到127.0.0.1。编辑MySQL配置文件/etc/mysql/mysql.conf.d/mysqld.cnf找到bind-address确保其值为127.0.0.1或0.0.0.0后者允许所有IP连接测试环境可用。检查防火墙Ubuntu 16.04默认的ufw防火墙可能关闭但如果有其他防火墙规则确保3306端口是开放的。问题3执行查询时报错FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask原因MapReduce任务执行失败。这是最宽泛的错误之一需要查看Hadoop任务的具体日志。解决去YARN的Web UI (http://localhost:8088)找到失败的任务点击ApplicationMaster链接再查看Logs特别是stderr和stdout里面通常有更详细的错误信息。常见原因包括HDFS目录权限不足确保/user/hive/warehouse目录对执行MapReduce任务的用户可写、内存不足可以尝试在mapred-site.xml中调小mapreduce.map.memory.mb和mapreduce.reduce.memory.mb、类冲突等。问题4Hive CLI中无法使用CtrlC中断长时间运行的查询原因这是Hive CLI的一个已知行为。解决打开另一个终端用yarn application -list找到对应的Hive查询的Application ID然后用yarn application -kill Application_ID来强制杀死任务。然后再回到Hive CLI它应该会提示任务被中断。安装和初步配置Hive只是万里长征的第一步。一个稳定运行的Hive环境是后续进行HiveQL学习、性能调优、集成其他组件如Hue, Spark的基础。在下一篇文章中我们将深入Hive的内部探讨其数据库、表的类型如内部表、外部表、分区表、分桶表以及基础的数据操作并开始接触一些实用的HiveQL技巧。当你看到第一个查询结果成功返回时之前所有的繁琐配置都是值得的。