Windows10系统下Hadoop和Hive开发环境搭建填坑指南

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 笔者目前需要搭建数据平台,发现了Windows系统下,Hadoop和Hive等组件的安装和运行存在大量的坑,而本着有坑必填的目标,笔者还是花了几个晚上的下班时候在多个互联网参考资料的帮助下完成了Windows10系统下Hadoop和Hive开发环境的搭建。这篇文章记录了整个搭建过程中的具体步骤、遇到的问题和对应的解决方案。

前提



笔者目前需要搭建数据平台,发现了Windows系统下,HadoopHive等组件的安装和运行存在大量的坑,而本着有坑必填的目标,笔者还是花了几个晚上的下班时候在多个互联网参考资料的帮助下完成了Windows10系统下HadoopHive开发环境的搭建。这篇文章记录了整个搭建过程中的具体步骤、遇到的问题和对应的解决方案。


环境准备



基于笔者的软件版本洁癖,所有选用的组件都会使用当前(2020-10-30)最高的版本。


软件 版本 备注
Windows 10 操作系统
JDK 8 暂时不要选用大于等于JDK9的版本,因为启动虚拟机会发生未知异常
MySQL 8.x 用于管理Hive的元数据
Apache Hadoop 3.3.0 -
Apache Hive 3.1.2 -
Apache Hive src 1.2.2 因为只有1.x版本的Hive源码提供了.bat启动脚本,有能力可以自己写脚本就不用下此源码包
winutils hadoop-3.3.0 HadoopWindows系统下的启动依赖


下面列举部分组件对应的下载地址:



下载完这一些列软件之后,MySQL正常安装为系统服务随系统自启。解压hadoop-3.3.0.tar.gzapache-hive-3.1.2-bin.tar.gzapache-hive-1.2.2-src.tar.gzwinutils到指定目录:


网络异常,图片无法展示
|


接着把源码包apache-hive-1.2.2-src.tar.gz解压后的bin目录下的文件拷贝到apache-hive-3.1.2-binbin目录中:


网络异常,图片无法展示
|


然后把winutils中的hadoop-3.3.0\bin目录下的hadoop.dllwinutils.exe文件拷贝到Hadoop的解压目录的bin文件夹下:


网络异常,图片无法展示
|


最后再配置一下JAVA_HOMEHADOOP_HOME两个环境变量,并且在Path中添加%JAVA_HOME%\bin;%HADOOP_HOME%\bin


网络异常,图片无法展示
|


笔者本地安装的JDK版本为1.8.0.212,理论上任意一个小版本的JDK8都可以。


接着用命令行测试一下,如果上述步骤没问题,控制台输出如下:


网络异常,图片无法展示
|


配置和启动Hadoop



HADOOP_HOMEetc\hadoop子目录下,找到并且修改下面的几个配置文件:

core-site.xml(这里的tmp目录一定要配置一个非虚拟目录,别用默认的tmp目录,否则后面会遇到权限分配失败的问题)


<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>  
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/e:/LittleData/hadoop-3.3.0/data/tmp</value>
    </property>  
</configuration>
复制代码


hdfs-site.xml(这里要预先创建nameNodedataNode的数据存放目录,注意一下每个目录要以/开头,笔者这里预先在HADOOP_HOME/data创建了nameNodedataNode子目录)


<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.http.address</name>
        <value>0.0.0.0:50070</value>
    </property>
    <property>    
        <name>dfs.namenode.name.dir</name>    
        <value>/e:/LittleData/hadoop-3.3.0/data/nameNode</value>    
    </property>    
    <property>    
        <name>dfs.datanode.data.dir</name>    
        <value>/e:/LittleData/hadoop-3.3.0/data/dataNode</value>  
    </property>
    <property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
    </property>
</configuration>
复制代码


mapred-site.xml


<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>
复制代码


yarn-site.xml


<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
</configuration>
复制代码


至此,最小化配置基本完成。接着需要格式化namenode并且启动Hadoop服务。切换至$HADOOP_HOME/bin目录下,使用CMD输入命令hdfs namenode -format(格式化namenode切记不要重复执行):


网络异常,图片无法展示
|


格式化namenode完毕后,切换至$HADOOP_HOME/sbin目录下,执行start-all.cmd脚本:


网络异常,图片无法展示
|


这里命令行会提示start-all.cmd脚本已经过期,建议使用start-dfs.cmdstart-yarn.cmd替代。同理,如果执行stop-all.cmd也会有类似的提示,可以使用stop-dfs.cmdstop-yarn.cmd替代。start-all.cmd成功执行后,会拉起四个JVM实例(见上图中的Shell窗口自动新建了四个Tab),此时可以通过jps查看当前的JVM实例:


λ jps
19408 ResourceManager
16324 NodeManager
14792 Jps
15004 NameNode
2252 DataNode
复制代码


可见已经启动了ResourceManagerNodeManagerNameNodeDataNode四个应用,至此Hadoop的单机版已经启动成功。通过stop-all.cmd命令退出这四个进程。可以通过http://localhost:8088/查看调度任务的状态:


网络异常,图片无法展示
|


通过http://localhost:50070/去查看HDFS的状态和文件:


网络异常,图片无法展示
|


重启Hadoop的办法:先执行stop-all.cmd脚本,再执行start-all.cmd脚本。


配置和启动Hive



Hive是构筑于HDFS上的,所以务必确保Hadoop已经启动。HiveHDFS中默认的文件路径前缀是/user/hive/warehouse,因此可以先通过命令行在HDFS中创建此文件夹:


hdfs dfs -mkdir /user/hive/warehouse
hdfs dfs -chmod -R 777 /user/hive/warehouse
复制代码


同时需要通过下面的命令创建并为tmp目录赋予权限:


hdfs dfs -mkdir /tmp
hdfs dfs -chmod -R 777 /tmp
复制代码


在系统变量中添加HIVE_HOME,具体的值配置为E:\LittleData\apache-hive-3.1.2-bin,同时在Path变量添加%HIVE_HOME%\bin;,跟之前配置HADOOP_HOME差不多。下载和拷贝一个mysql-connector-java-8.0.x.jar$HIVE_HOME/lib目录下:


网络异常,图片无法展示
|


创建Hive的配置文件,在$HIVE_HOME/conf目录下已经有对应的配置文件模板,需要拷贝和重命名,具体如下:

  • $HIVE_HOME/conf/hive-default.xml.template => $HIVE_HOME/conf/hive-site.xml
  • $HIVE_HOME/conf/hive-env.sh.template => $HIVE_HOME/conf/hive-env.sh
  • $HIVE_HOME/conf/hive-exec-log4j.properties.template => $HIVE_HOME/conf/hive-exec-log4j.properties
  • $HIVE_HOME/conf/hive-log4j.properties.template => $HIVE_HOME/conf/hive-log4j.properties


网络异常,图片无法展示
|


修改hive-env.sh脚本,在尾部添加下面内容:


export HADOOP_HOME=E:\LittleData\hadoop-3.3.0
export HIVE_CONF_DIR=E:\LittleData\apache-hive-3.1.2-bin\conf
export HIVE_AUX_JARS_PATH=E:\LittleData\apache-hive-3.1.2-bin\lib
复制代码


修改hive-site.xml文件,主要修改下面的属性项:


属性名 属性值 备注
hive.metastore.warehouse.dir /user/hive/warehouse Hive的数据存储目录,这个是默认值
hive.exec.scratchdir /tmp/hive Hive的临时数据目录,这个是默认值
javax.jdo.option.ConnectionURL jdbc:mysql://localhost:3306/hive?characterEncoding=UTF-8&amp;serverTimezone=UTC Hive元数据存放的数据库连接
javax.jdo.option.ConnectionDriverName com.mysql.cj.jdbc.Driver Hive元数据存放的数据库驱动
javax.jdo.option.ConnectionUserName root Hive元数据存放的数据库用户
javax.jdo.option.ConnectionPassword root Hive元数据存放的数据库密码
hive.exec.local.scratchdir E:/LittleData/apache-hive-3.1.2-bin/data/scratchDir 创建本地目录$HIVE_HOME/data/scratchDir
hive.downloaded.resources.dir E:/LittleData/apache-hive-3.1.2-bin/data/resourcesDir 创建本地目录$HIVE_HOME/data/resourcesDir
hive.querylog.location E:/LittleData/apache-hive-3.1.2-bin/data/querylogDir 创建本地目录$HIVE_HOME/data/querylogDir
hive.server2.logging.operation.log.location E:/LittleData/apache-hive-3.1.2-bin/data/operationDir 创建本地目录$HIVE_HOME/data/operationDir
datanucleus.autoCreateSchema true 可选
datanucleus.autoCreateTables true 可选
datanucleus.autoCreateColumns true 可选
hive.metastore.schema.verification false 可选


修改完毕之后,在本地的MySQL服务新建一个数据库hive,编码和字符集可以选用范围比较大的utf8mb4(虽然官方建议是latin1,但是字符集往大范围选没有影响):


网络异常,图片无法展示
|


上面的准备工作做完之后,可以进行Hive的元数据库初始化,在$HIVE_HOME/bin目录下执行下面的脚本:


hive.cmd --service schematool -dbType mysql -initSchema
复制代码


这里有个小坑,hive-site.xml文件的第3215行有个神奇的无法识别的符号:


网络异常,图片无法展示
|


此无法识别符号会导致Hive的命令执行异常,需要去掉。当控制台输出Initialization script completed schemaTool completed的时候,说明元数据库已经初始化完毕:


网络异常,图片无法展示
|


$HIVE_HOME/bin目录下,通过hive.cmd可以连接Hive(关闭控制台即可退出):


> hive.cmd
复制代码


尝试创建一个表t_test


hive>  create table t_test(id INT,name string);
hive>  show tables;
复制代码


查看http://localhost:50070/确认t_test表已经创建成功。


网络异常,图片无法展示
|


尝试执行一个写入语句和查询语句:


hive>  insert into t_test(id,name) values(1,'throwx');
hive>  select * from t_test;
复制代码


网络异常,图片无法展示
|


写用了30多秒,读用了0.165秒。


使用JDBC连接Hive



HiveServer2Hive服务端接口模块,必须启动此模块,远程客户端才能对Hive进行数据写入和查询。目前,此模块还是基于Thrift RPC实现,它是HiveServer的改进版,支持多客户端接入和身份验证等功能。配置文件hive-site.xml中可以修改下面几个关于HiveServer2的常用属性:


属性名 属性值 备注
hive.server2.thrift.min.worker.threads 5 最小工作线程数,默认值为5
hive.server2.thrift.max.worker.threads 500 最大工作线程数,默认值为500
hive.server2.thrift.port 10000 侦听的TCP端口号,默认值为10000
hive.server2.thrift.bind.host 127.0.0.1 绑定的主机,默认值为127.0.0.1
hive.execution.engine mr 执行引擎,默认值为mr


$HIVE_HOME/bin目录下执行下面的命令可以启动HiveServer2


hive.cmd --service hiveserver2
复制代码


客户端需要引入hadoop-commonhive-jdbc依赖,依赖的版本尽量和对接的HadoopHive版本对应。


<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>3.1.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.3.5.RELEASE</version>
</dependency>
复制代码


hadoop-common依赖链比较长,会连带下载大量其他相关依赖,所以可以找个空闲时间在某个Maven项目先挂起该依赖下载的任务(笔者挂起此依赖下载任务洗完澡仍然没下完,还会出现org.glassfish:javax.el的快照包无法下载的问题,不过不影响正常使用)。最后添加一个单元测试类HiveJdbcTest


@Slf4j
public class HiveJdbcTest {
    private static JdbcTemplate TEMPLATE;
    private static HikariDataSource DS;
    @BeforeClass
    public static void beforeClass() throws Exception {
        HikariConfig config = new HikariConfig();
        config.setDriverClassName("org.apache.hive.jdbc.HiveDriver");
        // 这里笔者修改过hive-site.xml的对应配置,因为端口不是默认的10000
//        config.setJdbcUrl("jdbc:hive2://127.0.0.1:10091");
        config.setJdbcUrl("jdbc:hive2://127.0.0.1:10091/db_test");
        DS = new HikariDataSource(config);
        TEMPLATE = new JdbcTemplate(DS);
    }
    @AfterClass
    public static void afterClass() throws Exception {
        DS.close();
    }
    @Test
    public void testCreateDb() throws Exception {
        TEMPLATE.execute("CREATE DATABASE db_test");
    }
    @Test
    public void testCreateTable() throws Exception {
        TEMPLATE.execute("CREATE TABLE IF NOT EXISTS t_student(id INT,name string,major string)");
        log.info("创建t_student表成功");
    }
    @Test
    public void testInsert() throws Exception {
        int update = TEMPLATE.update("INSERT INTO TABLE t_student(id,name,major) VALUES(?,?,?)", p -> {
            p.setInt(1, 10087);
            p.setString(2, "throwable");
            p.setString(3, "math");
        });
        log.info("写入t_student成功,更新记录数:{}", update);  // 这里比较神奇,数据写入了,返回的update数量为0
    }
    @Test
    public void testSelect() throws Exception {
        List<Student> result = TEMPLATE.query("SELECT * FROM t_student", rs -> {
            List<Student> list = new ArrayList<>();
            while (rs.next()) {
                Student student = new Student();
                student.setId(rs.getLong("id"));
                student.setName(rs.getString("name"));
                student.setMajor(rs.getString("major"));
                list.add(student);
            }
            return list;
        });
        // 打印日志:查询t_student成功,结果:[HiveJdbcTest.Student(id=10087, name=throwable, major=math)]
        log.info("查询t_student成功,结果:{}", result);
    }
    @Data
    private static class Student {
        private Long id;
        private String name;
        private String major;
    }
}
复制代码


可能遇到的问题



下面小结一下可能遇到的问题。


Java虚拟机启动失败


目前定位到是Hadoop无法使用JDK[9+的任意版本JDK,建议切换为任意JDK8的小版本。


出现找不到Hadoop执行文件异常


确保已经把winutils中的hadoop-3.3.0\bin目录下的hadoop.dllwinutils.exe文件拷贝到Hadoop的解压目录的bin文件夹中。


start-all.cmd脚本执行时有可能出现找不到批处理脚本的异常。此问题在公司的开发机出现过,在家用的开发机没有重现,具体解决方案是在start-all.cmd脚本的首行加入cd $HADOOP_HOME,如cd E:\LittleData\hadoop-3.3.0


无法访问localhost:50070


一般是因为hdfs-site.xml配置遗漏了dfs.http.address配置项,添加:


<property>
    <name>dfs.http.address</name>
    <value>0.0.0.0:50070</value>
</property>
复制代码


然后调用stop-all.cmd,再调用start-all.cmd重启Hadoop即可。


Hive连接MySQL异常


注意MySQL的驱动包是否已经正确拷贝到$HIVE_HOME/lib下,并且检查javax.jdo.option.ConnectionURL等四个属性是否配置正确。如果都正确,注意是否MySQL的版本存在问题,或者服务的版本与驱动版本不匹配。


Hive找不到批处理文件


一般描述是'xxx.cmd' is not recognized as an internal or external command...,一般是Hive的命令执行时的异常,需要把Hive 1.x的源码包的bin目录下的所有.cmd脚本拷贝到$HIVE_HOME/bin对应的目录下。


文件夹权限问题


常见如CreateSymbolicLink异常,会导致Hive无法使用INSERT或者LOAD命令写入数据。出现这类问题可以通过下面方式解决:


  • Win + R然后运行gpedit.msc - 计算机设置 - Windows设置 — 安全设置 - 本地策略 - 用户权限分配 - 创建符号链接 - 添加当前用户。


网络异常,图片无法展示
|


或者直接使用管理员账号或者管理员权限启动CMD,然后执行对应的脚本启动Hadoop或者Hive


SessionNotRunning异常


启动HiveServer2中或者外部客户端连接HiveServer2时候有可能出现此异常,具体是java.lang.ClassNotFoundException: org.apache.tez.dag.api.TezConfiguration的异常。解决方案是:配置文件hive-site.xml中的hive.execution.engine属性值由tez修改为mr,然后重启HiveServer2即可。因为没有集成tez,重启后依然会报错,但是60000ms后会自动重试启动(一般重试后会启动成功):


网络异常,图片无法展示
|


这算是一个遗留问题,但是不影响客户端正常连接,只是启动时间会多了60秒。


HiveServer2端口冲突


修改配置文件hive-site.xml中的hive.server2.thrift.port属性值为未被占用的端口,重启HiveServer2即可。


数据节点安全模式异常


一般是出现SafeModeException异常,提示Safe mode is ON。通过命令hdfs dfsadmin -safemode leave解除安全模式即可。


AuthorizationException


常见的是Hive通过JDBC客户端连接HiveServer2服务时候会出现这个异常,具体是信息是:User: xxx is not allowed to impersonate anonymous。这种情况只需要修改Hadoop的配置文件core-site.xml,添加:


<property>
    <name>hadoop.proxyuser.xxx.hosts</name>
    <value>*</value>
</property>
<property>
    <name>hadoop.proxyuser.xxx.groups</name>
    <value>*</value>
</property>
复制代码


这里的xxx是指报错时候具体的系统用户名,例如笔者开发机的系统用户名为doge

然后重启Hadoop服务即可。


MapRedTask的权限问题


常见的是Hive通过JDBC客户端连接HiveServer2服务执行INSERT或者LOAD操作时候抛出的异常,一般描述是Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. Permission denied: user=anonymous, access=EXECUTE, inode="/tmp/hadoop-yarn":xxxx:supergroup:drwx------。通过命令hdfs dfs -chmod -R 777 /tmp赋予匿名用户/tmp目录的读写权限即可。


小结



没什么事最好还是直接在Linux或者Unix系统中搭建HadoopHive的开发环境比较合理,Windows系统的文件路径和权限问题会导致很多意想不到的问题。本文参考了大量互联网资料和HadoopHive的入门书籍,这里就不一一贴出,站在巨人的肩膀上。


(本文完 c-4-d e-a-20201102)


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
安全 Windows
永久关闭 Windows 11 系统更新
永久关闭 Windows 11 系统更新
138 0
|
1月前
|
存储 负载均衡 Java
如何配置Windows主机MPIO多路径访问存储系统
Windows主机多路径(MPIO)是一种技术,用于在客户端计算机上配置多个路径到存储设备,以提高数据访问的可靠性和性能。本文以Windows2012 R2版本为例介绍如何在客户端主机和存储系统配置多路径访问。
82 13
如何配置Windows主机MPIO多路径访问存储系统
|
2月前
|
SQL 分布式计算 Hadoop
手把手的教你搭建hadoop、hive
手把手的教你搭建hadoop、hive
129 1
|
2月前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。
|
2月前
|
Apache 数据中心 Windows
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
|
2月前
|
域名解析 缓存 网络协议
Windows系统云服务器自定义域名解析导致网站无法访问怎么解决?
Windows系统云服务器自定义域名解析导致网站无法访问怎么解决?
|
2月前
|
Windows
安装Windows XP系统
安装Windows XP系统
|
2月前
|
安全 Windows
windows系统中,通过LOAD到入csv格式的文件到neo4j中,如何写文件路径
windows系统中,通过LOAD到入csv格式的文件到neo4j中,如何写文件路径
46 0
|
2月前
|
关系型数据库 MySQL Linux
Navicat 连接 Windows、Linux系统下的MySQL 各种错误,修改密码。
使用Navicat连接Windows和Linux系统下的MySQL时可能遇到的四种错误及其解决方法,包括错误代码2003、1045和2013,以及如何修改MySQL密码。
245 0
|
2月前
|
安全 Windows
Windows系统实现exe服务注册的方法都有哪些?
【10月更文挑战第5天】Windows系统实现exe服务注册的方法都有哪些?
356 0