一、X86 和 ARM
众所周知,当前 CPU 的主流系统架构分为 X86 架构和 ARM 架构。其中 X86 架构的所有权归属于 Intel 公司,而 ARM 架构则是开源的。
X86 架构的系统推出已经近 30 年,在这 30 年来互联网领域发展飞快,X86 架构也伴随着互联网的腾飞经过了高速发展的黄金时期,用户的应用、软件配套、软件开发等工具的配套和兼容都非常成熟,但由于 X86 架构的所有权问题,所有使用该架构的用户都需向 Intel 公司付费方可使用。
而开源的 ARM 架构在近年来尤为受到关注,面对当前日益复杂的国际环境以及基于 ARM 架构本身在功耗上的优异表现,国内外大量企业自研基于 ARM 架构的服务器芯片,越来越多的应用和软件配套也适配 ARM 架构。
CDH(Cloudra's Distribution Apache Of Hadoop)是 Apache Hadoop 和相关项目的最完整,经过测试和最流行的发行版。
CDH 是一个 WEB 操作平台,它集成了丰富的 Hadoop 生态,基于 CDH 版本的各种 Hadoop 框架和组件都能较为轻松并且高效的集成至 Hadoop 集群中。基于 CDH 的易用性和高效性,在 X86 架构下,绝大多数的公司和个人都会基于 CDH 进行大数据 Hadoop 集群的搭建与部署,但 CDH 本身并未提供基于 ARM 架构的版本,所以在当前火热的 ARM 架构和大数据发展下,如何在基于 ARM 架构的集群上搭建 Hadoop 集群是一个需要解决的问题。
当前基于 ARM 架构的 Hadoop 集群搭建有多种解决方案:
上述解决方案中,基于 Hadoop 开源版本的部署,会更加的贴近于 Hadoop 生态的蓬勃发展,并且能够更好地基于需求进行整个 Hadoop 集群的升级或优化。本文将介绍如何基于 Hadoop 开源版本完成一个大数据 Hadoop 集群的搭建。
得益于当前 ARM 架构的蓬勃发展,当前国内基于 ARM 架构投入研发的公司也越来越多,伴随着大家的研发与开源贡献,当前主流并且较为核心的 Hadoop 框架都已有支持 ARM 架构的版本。
本文将介绍如何安装 Zookeeper、Hadoop、Hive 和 Spark 用于实现基于开源 Hadoop 框架的大数据集群搭建。
Hadoop 集群内部通信,需设置各个机器互相免密登录,并且各机器之间应确保时钟同步。
设置免密可通过修改 .ssh/authorized_keys 文件,设置 ssh 访问,在此不详细赘述。
设置 NTP 时间同步是用于确保分布式集群的时间一致性,在此不详细赘述。
模拟集群模式至少需要 3 台机器,默认以 node1,node2 和 node3 来指代,其中 node1 作为 master 节点。
Java 是搭建 Hadoop 集群最基础的配置,当前业界使用较为主流的是 JAVA8 和 JAVA11,由于当前 Hadoop 开源框架主流版本依旧使用 JAVA8,故本文使用 JAVA8。
上传 JAVA 包至 /usr/local 目录下,本文使用的是 zulu-java8-aarch64 的包。
tar -zxvf /usr/local/java8.tar.gz
mv /usr/local/java8 /opt/java
vim ~/.bashrc
export JAVA_HOME=/opt/java
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:${JRE_HOME}/lib
export PATH=$JAVA_HOME/bin:$PATH
source ~/.bashrc
java -version
Zookeeper 是一个分布式、开源的分布式应用程序协调服务,Hadoop 集群的各个组件的通信都依赖于 Zookeeper,所以首先安装 Zookeeper。
上传 Zookeeper 包至 /usr/local 目录下,本文使用的是 zk-3.4.14 版本。
tar -zxvf /usr/local/zookeeper.tar.gz
mv /usr/local/zookeeper /opt/zookeeper
cd /opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
dataDir=/opt/zookeeper/data
server.1=node1:2888:3888
server.1=node1:2888:3888
server.1=node1:2888:3888
cd /opt/zookeeper
mkdir data
echo 1 > /opt/zookeeper/data/myid(node1 为 1,node2 为 2,node3 为 3)
scp -r /opt/zookeeper node2:/opt/zookeeper
其他机器相同操作
ssh node2
echo 2 > /opt/zookeeper/data/myid
export ZOOKEEPER_HOME=/opt/zookeeper/zookeeper-3.4.14
export PATH=$ZOOKEEPER_HOME/bin:$PATH
# 更新
source ~/.bashrc
cd /opt/zookeeper/bin
./zkServer.sh start
jps
有一个进程名为 QuorumPeerMain
cd /opt/zookeeper/bin
./zkServer.sh status
Hadoop 生态其实最初起源于 Hadoop 这个框架,Hadoop 中包括分布式文件存储系统 HDFS(Hadoop Distributed File System)、集群管理系统 YARN(Yet Another Resource Negotiator)和计算框架 MR(MapReduce)。
上传 Hadoop 包至 /usr/local 目录下,本文使用的是 hadoop-3.3.5-arrch64 版本。
tar -zxvf /usr/local/hadoop.tar.gz
mv /usr/local/hadoop /opt/hadoop
vim ~/.bashrc
export HADOOP_HOME=/opt/hadoop/hadoop-3.3.5
export HADOOP_USER_NAME=user
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# 更新
source ~/.bashrc
cd /opt/hadoop/bin
./hadoop version
export JAVA_HOME=/opt/java
# 修改启动用户为 root
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
export YARN_PROXYSERVER_USER=root
cd /opt/hadoop/etc/hadoop
core-site.xml
core-site.xml 文件中的主要是集群全局参数,用于定义系统级别的参数,如 HDFS 的 namenode 地址、Hadoop 临时目录等。
<configuration>
<property>
<!-- namenode 地址 -->
<name>fs.defaultFS</name>
<value>hdfs://node1:8020</value>
</property>
<property>
<name>fs.trash.interval</name>
<value>1</value>
</property>
<property>
<name>io.compression.codecs</name>
<value>org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.DeflateCodec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec</value>
</property>
<property>
<name>hadoop.security.authentication</name>
<value>simple</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>false</value>
</property>
<property>
<name>hadoop.rpc.protection</name>
<value>authentication</value>
</property>
<property>
<name>hadoop.security.auth_to_local</name>
<value>DEFAULT</value>
</property>
<property>
<name>hadoop.proxyuser.oozie.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.oozie.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.flume.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.flume.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.HTTP.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.HTTP.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hive.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hive.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hue.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hue.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.httpfs.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.httpfs.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfs.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfs.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.yarn.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.yarn.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.security.group.mapping</name>
<value>org.apache.hadoop.security.ShellBasedUnixGroupsMapping</value>
</property>
<property>
<name>hadoop.security.instrumentation.requires.admin</name>
<value>false</value>
</property>
<property>
<name>net.topology.script.file.name</name>
<value>/etc/hadoop/conf.cloudera.yarn/topology.py</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>65536</value>
</property>
<property>
<name>hadoop.ssl.enabled</name>
<value>false</value>
</property>
<property>
<name>hadoop.ssl.require.client.cert</name>
<value>false</value>
<final>true</final>
</property>
<property>
<name>hadoop.ssl.keystores.factory.class</name>
<value>org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory</value>
<final>true</final>
</property>
<property>
<name>hadoop.ssl.server.conf</name>
<value>ssl-server.xml</value>
<final>true</final>
</property>
<property>
<name>hadoop.ssl.client.conf</name>
<value>ssl-client.xml</value>
<final>true</final>
</property>
</configuration>
hdfs-site.xml
hdfs-site.xml 文件是关于 HDFS 的配置信息,其中重点包括 namenode 节点地址、second namenode 节点地址、hdfs 的副本数和 block 块大小等。
<configuration>
<!-- namenode 存放位置 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/hadoop/hadoop-3.3.5/data/namenode</value>
</property>
<!-- namenode 的 http 地址 -->
<property>
<name>dfs.namenode.servicerpc-address</name>
<value>node1:8022</value>
</property>
<!-- second namenode 地址 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node2:8022</value>
</property>
<property>
<name>dfs.https.address</name>
<value>node1:9871</value>
</property>
<!-- datanode 存放位置 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/hadoop/hadoop-3.3.5/data/datanode</value>
</property>
<property>
<name>dfs.https.port</name>
<value>9871</value>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>node1:9870</value>
</property>
<!-- hdfs 副本数 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- hdfs 的 block 块大小 -->
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
<property>
<name>dfs.client.use.datanode.hostname</name>
<value>false</value>
</property>
<property>
<name>fs.permissions.umask-mode</name>
<value>022</value>
</property>
<property>
<name>dfs.client.block.write.locateFollowingBlock.retries</name>
<value>7</value>
</property>
<property>
<name>dfs.namenode.acls.enabled</name>
<value>false</value>
</property>
<property>
<name>dfs.client.read.shortcircuit</name>
<value>false</value>
</property>
<property>
<name>dfs.domain.socket.path</name>
<value>/var/run/hdfs-sockets/dn</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.skip.checksum</name>
<value>false</value>
</property>
<property>
<name>dfs.client.domain.socket.data.traffic</name>
<value>false</value>
</property>
<property>
<name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
<value>true</value>
</property>
</configuration>
yarn.site.xml
yarn-site.xml 文件是 YARN 的配置文件信息,主要包括 resource manager 地址和 yarn 日志存放地址等。
<configuration>
<!-- resourceManager 地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node1</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- nodeManager 本地路径 -->
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>file:///home/shaocx/.bigdata/hadoop/data/nm</value>
</property>
<!-- yarn 日志存放路径 -->
<property>
<name>yarn.log.server.url</name>
<value>http://node1:19888/jobhistory/logs/</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.web-proxy.address</name>
<value>node1:54321</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>-1</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/logs</value>
</property>
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
</configuration>
mapred-site.xml
mapred-site.xml 文件是 MapReduce 的参数配置文件,其中中的包括使用 yarn 进行 job 的调度管理、job 的历史文件存放位置等。
<configuration>
<!-- 使用 yarn 调度 MR 任务 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>node1:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>node1:19888</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop/hadoop-3.3.5</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop/hadoop-3.3.5</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop/hadoop-3.3.5</value>
</property>
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
</configuration>
vim /opt/hadoop/etc/hadoop/workers
node1
node2
node3
scp -r /opt/hadoop node2:/opt/hadoop
其他节点相同操作
各节点设置环境变量
vim ~/.bashrc
cd /opt/hadoop/bin
./hadoop namenode -format
cd /opt/hadoop/sbin
./start-all.sh
Master
jps
Jps
ResourceManager
QuorumPeerMain
NameNode
NodeManager
WebAppProxyServer
DataNode
Second Namenode
jps
SecondaryNameNode
NodeManager
Jps
DataNode
QuorumPeerMain
Worker
jps
DataNode
NodeManager
Jps
QuorumPeerMain
Mysql 的安装是为了使用 Mysql 作为 Hive 的基础库。
上传 Mysql 压缩包至 /usr/local 目录下,使用的是 mysql-5.7.27-aarch64 版本的包。
tar -zxvf /usr/local/mysql-5.7.27-aarch64.tar.gz
mkdir -p /usr/local/mysql/logs
chmod -R mysql:mysql /usr/local/mysql
cd /usr/local/mysql
vim my.cnf
[mysqld]下增加 skip-grant-tables
cd /usr/local/mysql/bin
./mysqld --initialize --console
./mysqld -start
Hive 是基于 Hadoop 之上的一个分布式数据仓库工具,可能经常能够听到说数仓的数据存储于 Hive 中,这其实是不准确的。Hive 本质是让开发人员能够使用类 SQL 的 HiveQL 对存储于 HDFS 上的文件能够进行快速操作,Hive 会将 HiveQL 转化为在 YARN 上 运行的 MapReduce 任务从而实现读取或操作。
上传 Hive 包至 /usr/local 目录下,使用的是 hive-3.1.2 版本的包。
tar -zxvf /usr/local/hive.tar.gz
mv /usr/local/hive /opt/hive
cd /opt/hive/conf
cp hive-default.xml.template hive-site.xml
vim hive-site.xml
删除 hive-site.xml 第 3215 行的 "&8"。
将 hive-site.xml 中 "system:" 替换为 "",如 {system:java.io.tmpdir} 替换为 {java.io.tmpdir}
hive-site.xml 最后追加数据库连接信息
<!-- hive 元数据账号 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- hive 元数据库连接密码 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>password</value>
</property>
<!-- hive 元数据库连接字符串 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node1:3306/hive</value>
</property>
<!-- hive 元数据库连接驱动类 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
在 Mysql 下创建 hive 库
上传 mysql-connector-java-8.0.15.jar 至 /opt/hive/lib 目录下
cd /opt/hive/bin
./schematool -dbType mysql -initSchema
vim ~/.bashrc
export HIVE_HOME=/opt/hive/apache-hive-3.1.2-bin
export PATH=$PATH:$HIVE_HOME/bin:$PATH
source ~/.bashrc
查看 Mysql 下的 hive 库下是否新增 74 张表。
启动 Hive
cd /opt/hive/bin
./hive
Spark 是一个类似于 MapReduce 的分布式快速计算框架,用于解决 MapReduce 的查询效率问题,Spark 将中间的查询结果读取到内存中用于后续继续计算,大大提高了查询效率。
上传 Spark 包至 /usr/local 下,使用的是 spark-3.3.2-hadoop3-scala2.13 版本,从包名可以看出这是基于 Hadoop3 和 Scala2.13 版本的 Spark-3.3.2。
tar -zxvf /usr/local/spark
mv /usr/local/hive /opt/spark
cd /opt/spark/conf
cp spark-env.sh.template spark-env.sh
vim spark-env.sh
export JAVA_HOME=/opt/java
export HADOOP_HOME=/opt/hadoop
export HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop
export HADOOP_LOG_DIR=/opt/hadoop/logs
cp spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
spark.master yarn
spark.eventLog.enabled true
spark.driver.memory 5g
cd /opt/spark/bin
./spark-shell
一段启动日志后,Spark 启动成功并进入操作控制台,可以执行增删改查命令。
一个基于开源 Hadoop 框架的基础的大数据集群也就搭建完成了。