1. 程式人生 > 其它 >大資料環境搭建

大資料環境搭建

本文整理了 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

hadoop-2hadoop-3 這 3 個節點組建 zookeeper 叢集。

本文所使用的 zookeeper 版本為:3.5.8

  1. 解壓縮:

    tar -zxvf apache-zookeeper-x.x.x-bin.tar.gz
    
  2. 建立 data 資料夾用於存放 zookeeper 的資料:

    cd apache-zookeeper
    
    mkdir data
    
  3. 建立配置檔案 zoo.cfg(從 zoo_sample.cfg 複製得到),zookeeper 預設以 zoo.cfg 作為配置檔案啟動:

    cd apache-zookeeper/conf

    cp zoo_sample.cfg zoo.cfg

  4. 修改配置檔案 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 為相應節點的編號。

  5. 啟動 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
  1. 解壓 hadoop 安裝包:

    tar -zxvf hadoop-2.10.0.tar.gz
    
  2. 編輯 /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
    
  3. 編輯 hadoop/etc/hadoop/hadoop-env.sh,配置 JAVA_HOME

    # The java implementation to use.
    export JAVA_HOME=/opt/jdk1.8.0_281
    
  4. 驗證一下 hadoop 是否安裝成功:

  5. 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>
    
  6. 配置叢集 master 節點:

    編輯 hadoop/etc/hadoop/master 檔案,選擇 hadoop-1 節點為 master:

    hadoop-1
    
  7. 配置叢集 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 環境變數

  8. 啟動 journalnode

    分別在每個 journalnode 節點(hadoop-1,hadoop-2,hadoop-3)啟動 journalnode 程序:

    cd hadoop/sbin
    
    hadoop-daemon.sh start journalnode
    
  9. 格式化 HDFS 檔案系統

    在第一個 namenode 節點(hadoop-1)輸入以下命令格式化 HDFS 檔案系統

    hadoop namenode -format
    

    出現以下結果就算成功

  10. 格式化 ZKFC

    任選一個 namenode 節點格式化 ZKFC

    hdfs zkfc -formatZK
    

    出現以下資訊說明格式化成功:

  11. 啟動 namenode:

    啟動主 namenode(hadoop-1):

    ./sbin/hadoop-daemon.sh start namenode
    

    在備用 namenode(hadoop-2)上同步元資料:

    hadoop namenode -bootstrapStandby
    

    出現以下資訊說明元資料同步成功:

  12. 啟動 hdfs

    在第一個 namenode 節點(hadoop-1)啟動 hdfs:

    ./sbin/start-dfs.sh
    

    執行個 hdfs 命令測試一下是否啟動成功:

    hdfs dfs -ls /
    

    如果沒有異常輸出就代表啟動成功。

  13. 啟動 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

  1. 配置 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
    
  2. 配置 hive-site.xml

    <configuration>
      <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://10.4.53.180:3306/hive?createDatabaseIfNotExist=true&amp;serverTimezone=GMT%2B8&amp;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>
    
  3. 將 mysql 驅動拷貝到 hive/lib 目錄下

  4. 初始化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

  1. 配置環境變數:

    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
    
  2. 修改配置檔案:

    編輯 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
    
  3. 將配置好的 spark scp 到其他各個節點

  4. 啟動 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.xmlhdfs-site.xml 放到 Spark 的配置目錄下。

我們不是向 hive/lib 目錄上傳了一個 mysql 驅動嘛,還需要再把這個驅動程式拷貝到 spark/jars 目錄下,否則會丟擲找不到驅動程式的異常。

  1. 啟動Thirftserver:

    ./sbin/start-thriftserver.sh
    

    如果啟動成功,預設會監聽10000埠:

  2. 使用 beeline 連線試試看:

  3. 部署 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
    

    日誌中無異常資訊丟擲則代表啟動成功: