大資料環境搭建
本文整理了 zookeeper 叢集、Hadoop 叢集、Spark 叢集的詳細搭建步驟。
0. 環境準備
本實驗基於以下 8 臺測試機器進行:
IP | hostname |
---|---|
10.4.79.90 | hadoop-1 |
10.4.79.8 | hadoop-2 |
10.4.79.6 | hadoop-3 |
10.4.79.58 | hadoop-4 |
10.4.79.38 | hadoop-5 |
10.4.79.96 | hadoop-6 |
10.4.79.62 | hadoop-7 |
10.4.79.92 | hadoop-8 |
首先確認每個機器都安裝瞭如下軟體:
- JAVA >= 1.8.x
-
SSH,並確保所有叢集節點之間可互相 SSH免密登入
為叢集每個節點配置 hostname:vi /etc/hosts
10.4.79.90 hadoop-1
10.4.79.8 hadoop-2
10.4.79.6 hadoop-3
10.4.79.58 hadoop-4
10.4.79.38 hadoop-5
10.4.79.96 hadoop-6
10.4.79.62 hadoop-7
10.4.79.92 hadoop-8
1. zookeeper 叢集搭建
為什麼要搭建 zookeeper 叢集呢?這是為了保障後續 hadoop 叢集的高可用性,zookeeper 可以為 hadoop 叢集的主備切換控制器提供主備選舉支援。
我們選擇 hadoop-1
本文所使用的 zookeeper 版本為:3.5.8
-
解壓縮:
tar -zxvf apache-zookeeper-x.x.x-bin.tar.gz
-
建立 data 資料夾用於存放 zookeeper 的資料:
cd apache-zookeeper mkdir data
-
建立配置檔案 zoo.cfg(從 zoo_sample.cfg 複製得到),zookeeper 預設以 zoo.cfg 作為配置檔案啟動:
cd apache-zookeeper/conf
cp zoo_sample.cfg zoo.cfg
-
修改配置檔案 zoo.cfg:
一共需要修改兩處:
第一處:修改 dataDir 為我們建立的 zookeeper/data 路徑:
dataDir=/data/apache-zookeeper/data
第二處:檔案末尾新增其他 zookeeper 節點的資訊:
server.1=hadoop-1:2888:3888 server.2=hadoop-2:2888:3888 server.3=hadoop-3:2888:3888
其中 server.1 中的字尾 1 實際上為相應 zookeeper 節點的 id,例如本例中我們指定 hadoop-1 節點作為 zookeeper 叢集的 1 號節點。
如何讓 hadoop-1 知道自己是 1 號節點呢?在 zookeeper/data 下建立一個檔案 myid,裡面寫入 1 即可。
相應地,在 hadoop-2 的 zookeeper/data 下建立檔案 myid,修改內容為 2,在 hadoop-3 的 zookeeper/data 下建立檔案 myid,修改內容為 3。
一般我們在一個節點配置好後,再 scp 到其他節點,那麼在複製之後不要忘記修改 myid 為相應節點的編號。
-
啟動 zookeeper:
依次在每個節點啟動 zookeeper:
./bin/zkServer.sh start
檢視每個節點在叢集中的角色:
./bin/zkServer.sh status
可以看到叢集中有一個 leader 節點,其餘為 follower 節點。
2. hadoop 叢集搭建
本文所使用的 hadoop 版本為:2.10.0
搭建高可用 Hadoop 叢集之前,我們需要對叢集做一個規劃,分配好每個節點在叢集中扮演的角色;
hostname | NameNode | JournalNode | ZKFC | DataNode | ResourceManager | NodeManager |
---|---|---|---|---|---|---|
hadoop-1 | Y | Y | Y | Y | Y | |
hadoop-2 | Y | Y | Y | Y | Y | |
hadoop-3 | Y | Y | Y | Y | ||
hadoop-4 | Y | Y | Y | |||
hadoop-5 | Y | Y | ||||
hadoop-6 | Y | Y | ||||
hadoop-7 | Y | Y | ||||
hadoop-8 | Y | Y |
-
解壓 hadoop 安裝包:
tar -zxvf hadoop-2.10.0.tar.gz
-
編輯 /etc/profile 新增 hadoop 環境變數:
export JAVA_HOME=/opt/jdk1.8.0_281 export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib export HADOOP_HOME=/opt/hadoop-2.10.0 export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
-
編輯 hadoop/etc/hadoop/hadoop-env.sh,配置 JAVA_HOME
# The java implementation to use. export JAVA_HOME=/opt/jdk1.8.0_281
-
驗證一下 hadoop 是否安裝成功:
-
hadoop 叢集的核心配置
接著配置 hadoop 的 4 個核心配置檔案:core-site.xml,hdfs-site.xml,mapred-site.xml,yarn-site.xml,分別對應 hadoop 的 4 個主要組成部分:核心包,HDFS檔案系統,MapReduce模型,yarn 資源排程框架。
如果沒有相應檔案,從當前目錄下的模板檔案複製:
cp hadoop/etc/hadoop/xxx.site.xml.template hadoop/etc/hadoop/xxx.site.xml
core-site.xml 的配置:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <!--臨時檔案存放位置--> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop</value> </property> <!--zookeeper--> <property> <name>ha.zookeeper.quorum</name> <value>hadoop-1:2181,hadoop-2:2181,hadoop-3:2181</value> </property> </configuration>
hdfs-site.xml的配置
按照我們的規劃,選擇 hadoop-1,hadoop-2 作為 namenode,hadoop-1,hadoop-2,hadoop-3 作為 journalnode;
<configuration> <!--指定 hdfs 的 nameservice 為 mycluster,需要和 core-site.xml 中保持一致--> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <!-- mycluster 下面有兩個 NameNode,分別是 nn1,nn2 --> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <!-- nn1 的 RPC 通訊地址 --> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>hadoop-1:9000</value> </property> <!-- nn1 的 http 通訊地址 --> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>hadoop-1:50070</value> </property> <!-- nn2 的 RPC 通訊地址 --> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>hadoop-2:9000</value> </property> <!-- nn2 的 http 通訊地址 --> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>hadoop-2:50070</value> </property> <!-- 指定 NameNode 的 edits 元資料在 JournalNode 上的存放位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop-1:8485;hadoop-2:8485;hadoop-3:8485/mycluster</value> </property> <!-- 指定 JournalNode 在本地磁碟存放資料的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/data/hadoop/journaldata</value> </property> <!-- 開啟 NameNode 失敗自動切換 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 配置失敗自動切換實現方式 --> <!-- 此處配置較長,在安裝的時候切記檢查不要換行--> <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!-- 配置隔離機制方法,多個機制用換行分割,即每個機制佔用一行--> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property> <!-- 使用 sshfence 隔離機制時需要 ssh 免登陸 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <!-- 配置 sshfence 隔離機制超時時間(30s) --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <property> <name>dfs.permissions.enabled</name> <value>false</value> </property> </configuration>
mapred-site.xml 的配置
<configuration> <!-- 指定 mr 框架為 yarn 方式 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <!-- 設定 mapreduce 的歷史伺服器地址和埠號 --> <property> <name>mapreduce.jobhistory.address</name> <value>hadoop-1:10020</value> </property> <!-- mapreduce 歷史伺服器的 web 訪問地址 --> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>hadoop-1:19888</value> </property> </configuration>
yarn-site.xml 的配置
按照我們的規劃,選擇 hadoop-3,hadoop-4 作為 ResourceManager
<configuration> <!-- 開啟 RM 高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <!-- 指定 RM 的 cluster id,可以自定義--> <property> <name>yarn.resourcemanager.cluster-id</name> <value>jyarn</value> </property> <!-- 指定 RM 的名字,可以自定義 --> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <!-- 分別指定 RM 的地址 --> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoop-3</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoop-4</value> </property> <!-- 指定 zk 叢集地址 --> <property> <name>yarn.resourcemanager.zk-address</name> <value>hadoop-1:2181,hadoop-2:2181,hadoop-3:2181</value> </property> <!-- 要執行 MapReduce 程式必須配置的附屬服務 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 開啟 YARN 叢集的日誌聚合功能 --> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <!-- YARN 叢集的聚合日誌最長保留時長 --> <property> <name>yarn.log-aggregation.retain-seconds</name> <!--1天--> <value>86400</value> </property> <!-- 啟用自動恢復 --> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <!-- 設定 resourcemanager 的狀態資訊儲存在 zookeeper 叢集上--> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>8192</value> <discription>每個任務最多可用記憶體,單位MB</discription> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>4096</value> <discription>每個任務最少可用記憶體</discription> </property> <property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>4</value> </property> </configuration>
-
配置叢集 master 節點:
編輯 hadoop/etc/hadoop/master 檔案,選擇 hadoop-1 節點為 master:
hadoop-1
-
配置叢集 slave 節點,指定 DataNode 節點:
編輯 hadoop/etc/hadoop/slaves 檔案,配置 slave 節點,每行一個:
hadoop-1 hadoop-2 hadoop-3 hadoop-4 hadoop-5 hadoop-6 hadoop-7 hadoop-8
到此,hadoop 的 master 節點配置就基本完成了,將配置好的 hadoop 從 master 節點複製到其它節點,但要保證 hadoop 在每個節點的存放路徑相同,同時不要忘記在各個節點配置 HADOOP 環境變數。
-
啟動 journalnode
分別在每個 journalnode 節點(hadoop-1,hadoop-2,hadoop-3)啟動 journalnode 程序:
cd hadoop/sbin hadoop-daemon.sh start journalnode
-
格式化 HDFS 檔案系統
在第一個 namenode 節點(hadoop-1)輸入以下命令格式化 HDFS 檔案系統
hadoop namenode -format
出現以下結果就算成功
-
格式化 ZKFC
任選一個 namenode 節點格式化 ZKFC
hdfs zkfc -formatZK
出現以下資訊說明格式化成功:
-
啟動 namenode:
啟動主 namenode(hadoop-1):
./sbin/hadoop-daemon.sh start namenode
在備用 namenode(hadoop-2)上同步元資料:
hadoop namenode -bootstrapStandby
出現以下資訊說明元資料同步成功:
-
啟動 hdfs
在第一個 namenode 節點(hadoop-1)啟動 hdfs:
./sbin/start-dfs.sh
執行個 hdfs 命令測試一下是否啟動成功:
hdfs dfs -ls /
如果沒有異常輸出就代表啟動成功。
-
啟動 yarn
在第一個 resourcemanager 節點(hadoop-3)啟動 yarn:
./sbin/start-yarn.sh
在另一個 resourcemanager 節點(hadoop-4)手動啟動 resourcemanager:
./sbin/yarn-daemon.sh start resourcemanager
3. hive
本文所使用的 zookeeper 版本為:2.3.5
安裝 hive 的三個前提條件為:
-
JDK
-
hadoop
-
MySql
-
配置 hive-env.sh
檔案末尾新增:
export JAVA_HOME=/opt/jdk1.8.0_281 export HADOOP_HOME=/opt/hadoop-2.10.0 export HIVE_HOME=/opt/apache-hive-2.3.5-bin
-
配置 hive-site.xml
<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://10.4.53.180:3306/hive?createDatabaseIfNotExist=true&serverTimezone=GMT%2B8&useSSL=false</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>aaa123+-*/</value> </property> <property> <name>hive.querylog.location</name> <value>/data/hive/tmp</value> </property> <property> <name>hive.exec.local.scratchdir</name> <value>/data/hive/tmp</value> </property> <property> <name>hive.downloaded.resources.dir</name> <value>/data/hive/tmp</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>hdfs://mycluster/user/spark/spark-sql-warehouse</value> </property> <property> <name>spark.sql.warehouse.dir</name> <value>hdfs://mycluster/user/spark/spark-sql-warehouse</value> </property> </configuration>
-
將 mysql 驅動拷貝到 hive/lib 目錄下
-
初始化Hive元資料庫
./bin/schematool -initSchema -dbType mysql -userName root -passWord abc123+-*/
出現以下資訊則代表資料庫初始化成功:
成功後可以在 mysql 中看到建立的 hive 資料庫和相關表:
mysql> use hive; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +---------------------------+ | Tables_in_hive | +---------------------------+ | AUX_TABLE | | BUCKETING_COLS | | CDS | | COLUMNS_V2 | | COMPACTION_QUEUE | | DATABASE_PARAMS | | VERSION | | ... | +---------------------------+ 57 rows in set (0.00 sec)
4. Spark 叢集搭建
本文所使用的 Spark 版本為:spark-2.4.5-bin-hadoop2.7
-
配置環境變數:
export JAVA_HOME=/opt/jdk1.8.0_281 export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib export HADOOP_HOME=/opt/hadoop-2.10.0 export SPARK_HOME=/opt/spark-2.4.5-bin-hadoop2.7 export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$SPARK_HOME/bin:$SPARK_HOME/sbin
-
修改配置檔案:
編輯 spark/conf/spark-env.sh:
export JAVA_HOME=/opt/jdk1.8.0_281 export SPARK_MASTER_IP=hadoop-1 export SPARK_WORKER_MEMORY=1024m export SPARK_WORKER_CORES=1 export HADOOP_CONF_DIR=/opt/hadoop-2.10.0/etc/hadoop
編輯 spark-defaults.conf
spark.master spark://hadoop-1:7077
編輯 slaves 檔案配置 worker 節點:
hadoop-2 hadoop-3 hadoop-4 hadoop-5 hadoop-6 hadoop-7 hadoop-8
-
將配置好的 spark scp 到其他各個節點
-
啟動 spark 叢集:
./sbin/start-all.sh
5. Spark、Hadoop 和 Hive 的整合
現在一般 Spark 應用程式會部署到 Hadoop 的 Yarn 上進行排程,雖然 Spark 本身也提供了 standalone 的部署模式。
而在使用Spark SQL時,因為大部分資料一般都是儲存在 HDFS 上,而 Hive 本身就是操作 HDFS 上的資料,因此一般會將 Spark SQL 和 Hive 整合使用,元資料資訊是使用Hive表的,而真正處理資料時使用的計算引擎是 Spark 的。
當希望通過 Java JDBC 的方式使用 Spark SQL 的能力時,就可以使用 Spark Thrift JDBCServer,並且其本身也是可以和 Hive 整合使用。
官方文件關於這部分的說明:
Configuration of Hive is done by placing your hive-site.xml, core-site.xml and hdfs-site.xml files in conf/.
其實也就是將 Hive 的配置檔案 hive-site.xml,Hadoop 的配置檔案 core-site.xml 和 hdfs-site.xml 放到 Spark 的配置目錄下。
我們不是向 hive/lib 目錄上傳了一個 mysql 驅動嘛,還需要再把這個驅動程式拷貝到 spark/jars 目錄下,否則會丟擲找不到驅動程式的異常。
-
啟動Thirftserver:
./sbin/start-thriftserver.sh
如果啟動成功,預設會監聽10000埠:
-
使用 beeline 連線試試看:
-
部署 thrift-server 到 yarn
編輯 spark/conf/spark-env.sh(從 spark-env.sh.template 複製而來)
檔案末尾新增:
export JAVA_HOME=/opt/jdk1.8.0_281 export SPARK_MASTER_IP=hadoop-1 export SPARK_WORKER_MEMORY=1024m export SPARK_WORKER_CORES=1 export HADOOP_CONF_DIR=/opt/hadoop-2.10.0/etc/hadoop
編輯 spark/conf/slaves(從 slaves.template 複製而來),配置 worker 節點資訊:
hadoop-2 hadoop-3 hadoop-4 hadoop-5 hadoop-6 hadoop-7 hadoop-8
配置完成後,將 spark 複製到叢集中的每一臺節點。
啟動:
./start-thriftserver.sh --master yarn
日誌中無異常資訊丟擲則代表啟動成功: