三臺阿里雲伺服器搭建完全分散式hadoop叢集並實現sparkstreaming詳細步驟
本文基於三臺阿里雲ECS例項搭建完全分散式hadoop叢集,並整合flume + kafka + sparkstreaming實現實時流處理。詳細步驟會在本文後續一一寫出,包括在搭建叢集過程中遇到的坑以及應對辦法。
前言
三臺ECS主機的規劃如下:
外網ip | 內網ip | 角色 | |
主機1 | 47.101.148.34 | 172.19.173.4 | slave1 |
主機2 | 47.101.148.131 | 172.19.173.5 | slave2 |
主機3 | 106.14.199.161 | 172.19.173.3 | master |
版本控制
- jdk:1.8
- scala:2.11.8
- hadoop:3.1.1
- zookeeper:3.4.12
- hbase:1.4.6
- spark:2.1.0
- kafka:2.11-0.10.1.0
- flume:1.8.0
- maven:3.5.4
【防坑】scala版本一定要和kafka版本對應,避免類似2.12字首的scala和2.11字首的kafka一起安裝。
hosts檔案修改
三臺主機都需要修改。
編輯hosts檔案:
vi /etc/hosts
新增以下節點:
172.19.173.3 master 172.19.173.4 slave1 172.19.173.5 slave2
這樣就配置好了域名,在後面配置需要ip時我們可以直接用域名來方便地替換ip。
接下來修改主機名(xxx為剛剛在hosts配置的節點名)
hostnamectl set-hostname xxx
改完重啟,執行hostname檢視是否生效。
【防坑】叢集節點最好在同一個子網內,因為其在安全性方面並沒有做充分的設計,其設計之初就假定叢集執行在一個安全可信的環境。例如一個是192.168.1.1,另一個就要設定為192.168.1.x。要不然後續會出很多麻煩,比如namenode給你啟動失敗。
【防坑】還要記得同步時間。不過用阿里雲提供的centos7.4不用同步,預設自動同步。
配置SSH免密登入
三臺主機都需要配置。
生成SSH的公鑰,命令如下,三臺主機都要執行一次:
ssh-keygen -t rsa
讓輸入內容直接回車即可,執行以後會在 /home/.ssh/(家目錄/.ssh) 下生成id_rsa和id_rsa.pub檔案。
將主機slave1和slave2在上一步驟生成的id_rsa.pub檔案傳到主機master的 /home/.ssh/ 下面,為了防止覆蓋,重新命名為id_rsa.pub.slave1和id_rsa.pub.slave2:
scp id_rsa.pub [email protected]:~/.ssh/id_rsa.pub.slave1
scp id_rsa.pub [email protected]:~/.ssh/id_rsa.pub.slave2
在主機master的 /home/.ssh/ 目錄下分別將id_rsa.pub、id_rsa.pub.slave1和id_rsa.pub.slave2追加到authorized_keys檔案中:
cat id_rsa.pub >> authorized_keys
cat id_rsa.pub.slave1 >> authorized_keys
cat id_rsa.pub.slave2 >> authorized_keys
將authorized_keys檔案回傳到各臺主機中:
scp authorized_keys [email protected]:~/.ssh
scp authorized_keys [email protected]:~/.ssh
測試連通性,分別在各臺主機試試ssh localhost、ssh master、ssh slave1、ssh slave2,均直接出現歡迎介面表示成功。
【防坑】如果是centos系統,還必須修改.ssh和.ssh/authorized_keys檔案許可權,要不會有許可權錯誤。以下命令三臺主機都要執行一次:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
JDK8的安裝配置
三臺主機都需要安裝,在linux系統中,第三方軟體最好都安裝在/usr/local或/opt下,本文軟體都安裝在/usr/local下,後續不再說明。
到官網下載jdk,我下載的是jdk1.8.0-181版本,並拷到各臺阿里雲伺服器中,拷完後解壓:
tar -zxvf jdk-8u181-linux-x64.tar.gz
設定環境變數:
vi /etc/profile
新增以下內容:
JAVA_HOME=/usr/local/jdk1.8.0_181
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
新增完儲存退出後執行source使環境生效:
source /etc/profile
hadoop的安裝配置
三臺主機都需要安裝。這裡推薦兩個網站,大資料各個元件都可以在這裡找到並下載,速度比官網要快很多:
後續不再說明。
三臺主機都安裝hadoop,這裡的版本為hadoop-3.1.1
安裝完成後進入/usr/local/hadoop-3.1.1/etc/hadoop,需要修改的配置檔案為:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml、slaves、hadoop-env.sh、yarn-env.sh,因為這些配置檔案均位於資料夾hadoop-3.1.1/etc/hadoop中,所以只需修改master的配置檔案,然後同步資料夾hadoop-3.1.1/etc/hadoop到slave1和slave2中即可。
core-site.xml
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://master:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop-3.1.1/tmp</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop-3.1.1/hdfs/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop-3.1.1/hdfs/datanode</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
<description>need not permissions</description>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>master:50070</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
<property>
<description>The address of the applications manager interface in the RM.</description>
<name>yarn.resourcemanager.address</name>
<value>${yarn.resourcemanager.hostname}:8032</value>
</property>
<property>
<description>The address of the scheduler interface.</description>
<name>yarn.resourcemanager.scheduler.address</name>
<value>${yarn.resourcemanager.hostname}:8030</value>
</property>
<property>
<description>The http address of the RM web application.</description>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname}:18088</value>
</property>
<property>
<description>The https adddress of the RM web application.</description>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>${yarn.resourcemanager.hostname}:18090</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>${yarn.resourcemanager.hostname}:8031</value>
</property>
<property>
<description>The address of the RM admin interface.</description>
<name>yarn.resourcemanager.admin.address</name>
<value>${yarn.resourcemanager.hostname}:8033</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapred.job.tracker</name>
<value>master:9001</value>
</property>
</configuration>
workers(本來沒有這個檔案,新建這個檔案,然後新增以下內容)
slave1
slave2
【防坑】hadoop3中不用slaves檔案,變成了workers檔案,如果是hadoop2還是用slaves檔案。
hadoop-env.sh、yarn-env.sh
export JAVA_HOME=/usr/local/jdk1.8.0_181
將修改好配置檔案的hadoop目錄從master拷貝至slave1和slave2,這樣slave節點就不用重新再配置了:
scp -r /usr/local/hadoop-3.1.1 [email protected]:/usr/local
scp -r /usr/local/hadoop-3.1.1 [email protected]:/usr/local
接下來執行hadoop,啟動hadoop的命令都只在master上執行。
1、首次使用,清空master的hdfs和tmp資料:
rm -rf /usr/local/hadoop-3.1.1/hdfs/*
rm -rf /usr/local/hadoop-3.1.1/tmp/*
2、master格式化namenode:
/usr/local/hadoop-3.1.1/bin/hdfs namenode -format
3、master啟停hdfs:
/usr/local/hadoop-3.1.1/sbin/start-dfs.sh
/usr/local/hadoop-3.1.1/sbin/stop-dfs.sh
驗證是否啟動成功,在master輸入 jps,應當存在namenode和secondary namenode,在slave上輸入jps,應當存在datenode。
【防坑】如果執行指令碼報如下錯誤:
ERROR: Attempting to launch hdfs namenode as root
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting launch.
Starting datanodes
ERROR: Attempting to launch hdfs datanode as root
ERROR: but there is no HDFS_DATANODE_USER defined. Aborting launch.
Starting secondary namenodes [localhost.localdomain]
ERROR: Attempting to launch hdfs secondarynamenode as root
ERROR: but there is no HDFS_SECONDARYNAMENODE_USER defined. Aborting launch.
解決方案:
(缺少使用者定義而造成的)因此編輯啟動和關閉。
分別修改以下兩個檔案:
vi sbin/start-dfs.sh
vi sbin/stop-dfs.sh
頂部空白處新增以下四行:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
再次啟動指令碼。
4、master啟停yarn:
/usr/local/hadoop-3.1.1/sbin/start-yarn.sh
/usr/local/hadoop-3.1.1/sbin/stop-yarn.sh
在master輸入 jps,應當存在resourcemanager。
在slave1和slave2輸入jps,應當存在nodemanager。
【防坑】注意,阿里雲上不能配置8088埠,會有黑客定期掃描Yarn ResourceManager並植入挖礦程式。
【防坑】如果啟動時報如下錯誤:
Starting resourcemanager
ERROR: Attempting to launch yarn resourcemanager as root
ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Aborting launch.
解決方案:
(也是由於缺少使用者定義)
是因為缺少使用者定義造成的,所以分別編輯開始和關閉指令碼。
分別修改以下兩個檔案:
vi sbin/start-yarn.sh
vi sbin/stop-yarn.sh
頂部新增以下三行:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
再次啟動指令碼。
zookeeper叢集的安裝配置
三臺主機都安裝zookeeper,版本為zookeeper-3.4.12
1、建立資料目錄:
mkdir usr/local/zookeeper-3.4.12/data
2、進入conf目錄建立並修改zoo.cfg檔案:
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
修改後的內容如下:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/usr/local/zookeeper-3.4.12/data
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=0.0.0.0:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
【防坑】zoo.cfg 的修改,各個主機下對應的 server.x 中的 ip 設定為 0.0.0.0。
3、在資料目錄/usr/local/zookeeper-3.4.12/data下面新建名為myid的檔案,各個主機對應的內容是不同的,master的內容是1,slave1的內容是2,slave2的內容是3,分別對應zoo.cfg中server.x中的x。
4、設定環境變數:
vi /etc/profile
新增以下內容並source使環境生效:
export ZOOKEEPER_HOME=/usr/local/zookeeper-3.4.12
export PATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf
5、啟停zookeeper
/usr/local/zookeeper-3.4.12/bin/zkServer.sh start
/usr/local/zookeeper-3.4.12/bin/zkServer.sh stop
三臺主機都執行啟動命令,啟動完後命令行輸入jps,顯示QuorumPeerMain為正常。
檢視各個主機的狀態:
sh bin/zkServer.sh status
可以看到哪臺主機是leader,哪臺是follower。
HBase的安裝配置
三臺主機都安裝HBase,版本為hbase-1.4.6
安裝成功後執行以下操作。
1、修改conf目錄下的三個檔案:hbase-env.sh、hbase-site.xml、regionservers:
hbase-env.sh
export JAVA_HOME=/usr/local/jdk1.8.0_181
export HBASE_MANAGES_ZK=true
export HBASE_LOG_DIR=/usr/local/hbase-1.4.6/logs
hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:9000/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>master,slave1,slave2</value>
</property>
<property>
<name>hbase.master.maxclockskew</name>
<value>180000</value>
<description>Time difference of regionserver from master</description>
</property>
</configuration>
regionservers
slave1
slave2
2、master啟停hbase
usr/local/hbase-1.4.6/bin/start-hbase.sh
usr/local/hbase-1.4.6/bin/stop-hbase.sh
master輸入jps,顯示HMaster為正常。
slave輸入jps,顯示HRegionServer為正常。
Spark的安裝配置
三臺主機都安裝Spark,版本為spark-2.1.0-bin-hadoop2.7
安裝成功後執行以下操作。
1、建立並修改conf目錄下的配置檔案 spark-env.sh,slaves:
spark-env.sh
cp spark-env.sh.template spark-env.sh
vi spark-env.sh
修改後的內容為:
export JAVA_HOME=/usr/local/jdk1.8.0_181
export HADOOP_HOME=/usr/local/hadoop-3.1.1
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HBASE_HOME=/usr/local/hbase-1.4.6
slaves
cp slaves.template slaves
vi slaves
修改後的內容為:
slave1
slave2
2、master啟停spark:
/usr/local/spark-2.1.0-bin-hadoop2.7/sbin/start-all.sh
/usr/local/spark-2.1.0-bin-hadoop2.7/sbin/stop-all.sh
master鍵入jps,顯示Master為正常。
slave鍵入jps,顯示Worker為正常。
scala和maven的安裝配置
1、安裝scala和maven
安裝scala,版本為scala-2.11.8。
安裝maven,版本為apache-maven-3.5.4。
2、設定環境變數,vi /etc/profile,新增以下內容並source使環境生效:
export M2_HOME=/usr/local/apache-maven-3.5.4
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$M2_HOME/bin:$PATH
export PATH="$PATH:/usr/local/scala-2.11.8/bin"
Kafka的安裝配置
三臺主機都安裝kafka,版本為kafka_2.11-0.10.1.0
安裝成功後執行以下操作。
1、進入Kafka的config目錄,修改server.properties:
broker.id=1 #約定master為1,slave1為2,slave2為3
listeners=PLAINTEXT://172.19.173.3:9092 #阿里雲內網ip
advertised.listeners=PLAINTEXT://106.14.199.161:9092 #阿里雲外網ip
zookeeper.connect=172.19.173.3:2181,172.19.173.4:2181,172.19.173.5:2181
2、啟動kafka
三臺主機都開啟kafka。進入各臺主機下的kafka目錄,執行命令:
bin/kafka-server-start.sh config/server.properties &
【防坑】阿里雲ECS突發例項2G記憶體太小起不來,需要修改kafka下的kafka-server-start.sh和zookeeper-server-start.sh,找到KAFKA_HEAP_OPTS="-Xmx1G -Xms1G",Xms最小記憶體,Xmx最大記憶體,預設都為1G,根據需要自行修改。
kafka相關命令彙總:
- 開啟kafka:bin/kafka-server-start.sh config/server.properties &
- 建立Topic test:bin/kafka-topics.sh --create --zookeeper 172.19.173.3:2181,172.19.173.4:2181,172.19.173.5:2181 --replication-factor 2 --partitions 2 --topic test
- 檢視新建的Topic:bin/kafka-topics.sh --describe --zookeeper 172.19.173.3:2181,172.19.173.4:2181,172.19.173.5:2181 --topic test
- 檢視所有Topic:bin/kafka-topics.sh --list --zookeeper 172.19.173.3:2181,172.19.173.4:2181,172.19.173.5:2181
- 在終端生產資訊:bin/kafka-console-producer.sh --broker-list 172.19.173.4:9092 --topic test
- 在終端消費資訊:bin/kafka-console-consumer.sh --bootstrap-server 172.19.173.5:9092 --topic test --from-beginning
flume的安裝配置
任意一臺主機安裝flume,版本為apache-flume-1.8.0-bin
安裝成功後執行以下操作。
1、進入flume目錄,修改conf/flume-env.sh:
export JAVA_HOME=/usr/local/jdk1.8.0_181
export JAVA_OPTS="-Xms128m -Xmx256m -Dcom.sun.management.jmxremote"
2、新增配置檔案flume-conf.properties,修改內容如下(此處我隨便建了一個/tmp/logs/kafka.log檔案,tail -F表示監聽這個檔案追加的內容):
agent.sources = s1
agent.channels = c1
agent.sinks = k1
#配置s1
agent.sources.s1.type=exec
agent.sources.s1.command=tail -F /tmp/logs/kafka.log
agent.sources.s1.channels=c1
#配置c1
agent.channels.c1.type=memory
agent.channels.c1.capacity=10000
agent.channels.c1.transactionCapacity=100
#配置k1
agent.sinks.k1.type= org.apache.flume.sink.kafka.KafkaSink
agent.sinks.k1.kafka.bootstrap.servers=172.19.173.3:9092,172.19.173.4:9092,172.19.173.5:9092
agent.sinks.k1.kafka.topic=test
agent.sinks.k1.serializer.class=kafka.serializer.StringEncoder
agent.sinks.k1.channel=c1
3、設定環境變數,vi /etc/profile,新增以下內容並source使環境生效:
export FLUME_HOME=/usr/local/apache-flume-1.8.0-bin
export PATH=$PATH:$FLUME_HOME/bin
4、進入flume安裝目錄,啟動flume
bin/flume-ng agent --conf-file conf/flume-conf.properties -c conf/ --name agent -Dflume.root.logger=INFO,console
sparkstreaming整合kafka
三臺主機都要執行
1、自己找以下這4個檔案分別放入三臺主機spark目錄下的jars中:
- kafka_2.11-1.0.0.jar
- spark-streaming-kafka-0-10_2.11-2.1.0.jar
- kafka-clients-1.0.0.jar
- zkclient-0.10.jar
2、然後cd到hbase安裝目錄的lib下,以下jar檔案統一copy一份放到spark安裝目錄的jars中:
- hbase*.jar(所有hbase開頭的jar)
- metrics-core-2.2.0.jar
- htrace-core-3.1.0-incubating.jar
【防坑】注意:在利用spark程式往hbase中寫資料時,如果缺少metrics-core-2.2.0.jar這個jar,spark程式會一直卡在stage階段並一直嘗試構建stage,但不會報任何錯,等了大概半小時後,程式報錯:
java.lang.NoClassDefFoundError: com/yammer/metrics/core/Gauge: 5 times, server with issue: null
3、進入spark目錄下的bin,執行指令:
./spark-submit --master spark://master:7077 --driver-memory 512M --executor-memory 512M --total-executor-cores 2 --class "com.main.Monitor" ~/SparkDemo.jar
SparkDemo.jar為自己寫的測試jar