集羣架構
環境
-
機器環境
- java8
- SSH
- 各模塊版本
- Flink: 1.8.x
- Hadoop:2.8.x
- Zookeeper:3.4.x
部署流程
Misc
- 操作賬號:user(教程中配置示例使用的是”root”)
- 操作順序
- SSH免密登陸
- ZooKeeper部署/Hadoop部署(兩者無先後順序)
- Flink部署
- 安裝包
- flink 1.8 包採用 flink-1.8.1-bin-scala_2.11.tgz
下載地址:https://adu-microcar.cdn.bcebos.com/flink-1.8.1-bin-scala_2.11.tgz - flink 1.8 需指定對應的hadoop關聯依賴包:
下載地址:https://adu-microcar.cdn.bcebos.com/flink-shaded-hadoop-2-uber-2.8.3-7.0.jar - hadoop 安裝包
下載地址:http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.8.5/hadoop-2.8.5.tar.gz
- flink 1.8 包採用 flink-1.8.1-bin-scala_2.11.tgz
JDK環境檢查
機器上應該已經裝好JDK,如果沒裝,需協調相關人員進行安裝。
檢查方法
# 通過這兩個命令中的任何一個都可以找到java的安裝位置
$ which java
$ env|grep JAVA_HOME
JAVA_HOME會在後續配置中用到
SSH免密登陸
1、生成公鑰、私鑰
$ ssh-keygen -t rsa
$ chmod 700 ~/.ssh
(同時修改.ssh的父目錄爲755)
2、在各個節點上執行步驟1,並記錄公鑰內容
3、創建authorized_keys文件,將所有節點的公鑰寫到該文件
$ touch authorized_keys
4、將authorized_keys文件分發至各節點~/.ssh目錄下
## 分發至example01.baidu.com節點
$ scp authorized_keys [email protected]:~/.ssh
## 在example01.baidu.com上
$ chmod 600 authorized_keys
5、驗證(無論免密是否已經由別人安裝,此步務必執行)
測試各個機器之間的免密是不是好的,這一步雖然麻煩,但是非常有必要,能避免後續踩坑。
經常遇到免密配置之後,第一次連接依然需要確認的情況。
尤其注意,本機到本機的免密也需要驗證一下。
$ ssh user@node2
$ exit
$ ssh user@node3
$ exit
ZooKeeper
Flink Job Manager存在單點問題,使用ZooKeeper實現Job Manager HA。
3節點的ZooKeeper集羣完全可以滿足生產環境的要求,在機器允許的情況下,建議部署5個節點以獲取更高的可靠 性。5節點集羣可以隨時下線其中一個節點進行維護而不影響生產環境。
此步驟暫未驗證,Zookeeper複用了已有服務。
1、DownLoad Zookeeper
2、配置conf/zoo.cfg文件,示例如下
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/root/flink-example/zookeeper-3.4.14/data
clientPort=2181
server.1=example01.baidu.com:2888:3888
server.2=example02.baidu.com:2888:3888
server.3=example03.baidu.com:2888:3888
server.4=example04.baidu.com:2888:3888
server.5=example05.baidu.com:2888:3888
3、在{dataDir}目錄下創建myid文件,該文件內容只有一行,一個數字,爲該節點對應的server.{id}中的 id。
example01.baidu.com節點myid文件示例如下:
1
4、在各節點上重複步驟1~3
5、啓動服務
java -cp zookeeper-3.4.14.jar:lib/slf4j-api-1.7.25.jar:lib/slf4j-log4j12-1.7.25.jar:lib/log4j-1.2.17.ja r:conf org.apache.zookeeper.server.quorum.QuorumPeerMain conf/zoo.cfg
6、驗證(非必須)
$ bin/zkCli.sh -server 127.0.0.1:2181
Hadoop
使用HDFS作爲Flink的State Backends。
1、Download Hadoop
2、配置etc/hadoop/core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://node2:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/root/software/hadoop-2.8.5/hadoop_tmp</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
</configuration>
3、配置etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/root/software/hadoop-2.8.5/hdfs/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/root/software/hadoop-2.8.5/hdfs/datanode</value>
</property>
<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:/root/software/hadoop-2.8.5/hdfs/namesecondary</value>
</property>
<property>
<!--hdfs NameNode節點地址-->
<name>dfs.http.address</name>
<value>node2:50070</value>
</property>
<property>
<name>dfs.secondary.http.address</name>
<!--hdfs secondary NameNode節點地址-->
<value>node2:50090</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
</configuration>
4、配置etc/hadoop/mapred-site.xml
$ cp mapred-site.xml.template mapred-site.xml
增加如下內容
<configuration>
<!--指定mapreduce運行框架-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<!--歷史服務的通信地址-->
<value>node2:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<!--歷史服務的web ui地址-->
<value>node2:19888</value>
</property>
</configuration>
5、配置etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<!--yarn resourceManager地址-->
<value>node2</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>${yarn.resourcemanager.hostname}:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>${yarn.resourcemanager.hostname}:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname}:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>${yarn.resourcemanager.hostname}:8090</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>${yarn.resourcemanager.hostname}:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>${yarn.resourcemanager.hostname}:8033</value>
</property>
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/root/software/hadoop-2.8.5/hadoop_tmp/yarn/local</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/root/software/hadoop-2.8.5/hadoop_tmp/logs</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://node2:19888/jobhistory/logs/</value>
<description>URL for job history server</description>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<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>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>512</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>1</value>
</property>
</configuration>
6、配置etc/hadoop/slaves。將所有worker節點都寫進文件,如果只配置一個節點,就是隻在這個節點上有datenode和nodeManager
node2
node3
7、配置etc/hadoop/hadoop-env.sh
# 搜索到JAVA_HOME,修改成線上安裝的jdk路徑
export JAVA_HOME=/root/software/jdk1.8.0_131
8、配置etc/hadoop/yarn-env.sh
# 搜索到JAVA_HOME,修改成線上安裝的jdk路徑
export JAVA_HOME=/root/software/jdk1.8.0_131
9、配置etc/hadooop/mapred-env.sh
# 搜索到JAVA_HOME,修改成線上安裝的jdk路徑
export JAVA_HOME=/root/software/jdk1.8.0_131
10、然後通過scp命令將文件發送到其他所有機器
# 多機器地址保持一致
$ scp -r hadoop-2.8.5 root@node3:/root/software/
11、格式化namanode(只在第一次啓動集羣之前操作)
$ bin/hdfs namenode -format
操作完成後會發現生成了/root/software/hadoop-2.8.5/hdfs/namenode目錄,下面有初始化的namenode信息。如果需要將集羣數據重置,可以將下面的數據全部刪除(datanode數據也刪除,每個機器上都清除數據),重新格式化namenode。
12、啓動dfs
$ sbin/start-dfs.sh
停止dfs(不必要)
$ sbin/stop-dfs.sh
Test
$ bin/hdfs dfs -mkdir /aa
$ bin/hdfs dfs -ls /
訪問NameNode UI: http://node2:50070
13、啓動yarn
$ sbin/start-yarn.sh
訪問Yarn UI:http://node2:8088
停止yarn
$ sbin/stop-yarn.sh
14、全部啓動
$ sbin/start-all.sh
全部停止
$ sbin/stop-all.sh
15、配置環境變量(方便使用),在/etc/profile文件中增加如下配置:
export HADOOP_HOME=root/software/hadoop-2.8.5
export PATH=$PATH:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin
Flink
使用Standalone + HA的方式部署Flink集羣。
(配置文件各機器上相同,可配置一份後分發)
1. Download Flink,解壓縮。
將flink-shaded-hadoop-2-uber-2.8.3-7.0.jar包放到lib目錄下。
2. 配置conf/flink-conf.yaml文件。原文件中大部分配置都被註釋了,每個配置項上面都有註釋說明。可以直接用下面的配置內容覆蓋文件內容,並對相關內容進行修改
# jobmanager的地址,在HA模式下這個參數會被接管,配置不生效。只有在standalone模式下才會生效,如果用域名不生效,可以改成ip地址。
jobmanager.rpc.address: localhost
# jobmanager和taskmanager通信的端口
jobmanager.rpc.port: 6123
# jobmanager的堆大小
jobmanager.heap.size: 4096m
# taskmanager的堆大小
taskmanager.heap.size: 2048m
# 每個taskmanager啓動的slot個數
taskmanager.numberOfTaskSlots: 3
# taskmanager啓動後是否直接預分配內存,批處理模式下使用這個參數可避免動態內存擴展,但是流式計算模式下不要設置爲true
taskmanager.memory.preallocate: false
# 默認並行度
parallelism.default: 1
# web頁面的端口,還有個rest.port,默認也是8081,不知道是不是改了名稱了,不過這麼設置沒有問題。不設置默認也是8081
web.port: 8081
# web頁面上提交的jar包存放位置
web.upload.dir: /root/software/flink-1.8.1/data/temp
# 存放flinkjobmanager和taskmanager的進程id
env.pid.dir: /root/software/flink-1.8.1/tmp/pid
# 完成的任務保存在hdfs目錄下
jobmanager.archive.fs.dir: hdfs://node2-ip/flink/completed-jobs/
historyserver.archive.fs.dir: hdfs://node2-ip/flink/history/completed-jobs/
# flink的狀態數據存儲
state.backend: filesystem
state.backend.fs.checkpointdir: hdfs://node2-ip/flink/checkpoints
# checkpoint在hdfs中的存儲位
state.checkpoints.dir: hdfs://node2-ip/flink/checkpoint
taskmanager.tmp.dirs: /root/software/flink-1.8.1/taskmanagertmp
# 啓用HA
high-availability: zookeeper
high-availability.storageDir: hdfs://node2-ip/flink/ha
high-availability.zookeeper.quorum: zk-ip:2181
high-availability.zookeeper.path.root: /flink
# The cluster-id ZooKeeper node, under which all required coordination data for a cluster is placed.
# important: customize per cluster
high-availability.cluster-id: /flink_cluster_one
3. 配置conf/masters文件。配置所有的jobmanager(非HA模式下,只需要配置一個jobmanager)
node2:8081
node3:8081
4. 配置conf/slaves文件。
此文件直接置空,直接進行下一步。如果想理解爲什麼,可以看一下本步的內容。
此文件用於配置所有的taskmanager所在機器,每配置一臺機器,就會在該機器上啓動一個taskmanager;同一臺機器可以重複配置,配置多次就會啓動多個taskmanager。文件爲空,則不會啓動taskmanager。
node2
node3
這個配置最好直接置空,不要使用。因爲每次使用 bin/start-cluster.sh 的時候就會讀取本配置文件,重新生成一遍taskmanager,多次執行之後會使taskmanager的個數倍增。
那麼taskmanager怎麼啓動?很簡單,繼續往下看。
5. 啓動集羣
$ bin/start-cluster.sh
此命令的效果:
根據conf/masters的配置啓動jobmanager;根據conf/slaves啓動taskmanager。
6. 關閉集羣(非必須)
$ bin/stop-cluster.sh
7. 訪問web頁面
http:node2:8081
可以看到已經啓動的taskmanager和slot個數。如果conf/slaves已經置空,此時的界面如下
使用http://node3:8081也可以訪問,是同一個集羣。
8. 啓動taskmanager
# 連接到要啓動taskmanager的機器上
$ ssh user@node2
$ cd /root/software/flink-1.8.1
$ bin/taskmanager.sh start
# 啓動10個taskmanager
$ for i in {1..3}; do /root/software/flink-1.8.1/bin/taskmanager.sh start; done
# 查看啓動結果
$ ps aux|grep TaskManager|grep -v grep |wc -l
這時候看web頁面上,taskmanager個數和slot個數都已經發生了變化。slot個數爲taskmanager個數的3倍,這是我們在conf/flink-conf.yaml中用 taskmanager.numberOfTaskSlots: 3 配置的。
9. Test
跑個demo
$ ./bin/flink run ./examples/batch/WordCount.jar
增/刪資源
增/刪 job manager
1. 增加 job manager 在現有flink節點上直接啓動job manager即可
$ bin/jobmanager.sh start
2. 移除 job manager
在job manager所在節點上停止job manager即可
$ bin/jobmanager.sh stop
# 上面的方法有可能會失效,那就進入bin目錄再執行。暫不知原因。
$ cd bin
$ ./jobmanager.sh stop
增/刪 task manager
1. 增加 task manager
在現有flink節點上直接啓動task manager即可
$ bin/taskmanager.sh start
2. 移除 task manager
在現有flink節點上直接停止task manager即可
$ bin/taskmanager.sh stop
增加節點
1. 新節點與所有zookeeper節點配置SSH免密登陸
2. 啓動task manager
$ bin/taskmanager.sh start
3. 將新節點添加到conf/masters文件和conf/slavers文件中
移除節點
1. 關閉 job manager
$ bin/jobmanager.sh stop
2. 關閉 task manager
$ bin/taskmanager.sh stop
3. 從conf/masters文件和conf/slavers文件中移除節點
保活腳本
1、保活腳本software-check-restart.sh
#!/bin/bash
export JAVA_HOME=/root/software/jdk1.8.0_131
export JRE_HOME=$JAVA_HOME/jre
declare -A namedict
namedict=(['redis']="REDIS_PROCESS_ERROR" \
['/root/software/zookeeper']="ZOOKEEPER_PROCESS_ERROR" \
['/root/software/hadoop-2.8.5']="MYSQL_PROCESS_ERROR" \
['StandaloneSessionClusterEntrypoint']="JOBMANAGER_PROCESS_ERROR" \
['TaskManagerRunner']="TASKMANAGER_PROCESS_ERROR")
disk_error_code="DISK_OVER_THRESHOLD_ERROR"
mem_error_code="MEM_OVER_THRESHOLD_ERROR"
cpu_error_code="CPU_OVER_THRESHOLD_ERROR"
local_host=`hostname --fqdn`
local_ip=`ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | tr -d "addr:"`
check() {
process=$1
echo "`date` : check process $process $2"
cnt=`ps -ef | grep $process | grep -v grep | wc -l`
return $cnt
}
double_check() {
check $1
ret=$?
# echo $ret
if [ "$ret" -eq "0" ]
then
sleep 1
check $1
ret=$?
# echo $ret
fi
return $ret
}
check_and_restart() {
double_check $1
ret=$?
required_num=$2
if [ "$ret" -lt "$required_num" ]
then
echo "need start $1, use cmd: $3"
gap_num=`echo $required_num $ret | awk '{print $1-$2}'`
echo "need to start $1 for $gap_num times"
for i in `seq 1 $gap_num`;
do
eval $3
done
log_error_code=${namedict[$1]}
echo "$log_error_code"
else
echo "$1 exist"
fi
}
check_and_restart StandaloneSessionClusterEntrypoint 1 "/root/software/flink-1.8.1/bin/start-cluster.sh"
check_and_restart TaskManagerRunner 35 "/root/software/flink-1.8.1/bin/taskmanager.sh start"
# check_and_restart namenode.NameNode 1 "/root/software/hadoop-2.8.5/sbin/start-all.sh"
將文件放在/root/software/tools目錄下(沒有目錄先創建目錄)
# check_and_restart是一個function
# 第一個參數是要保活的進程關鍵字
# 第二個參數是該進程要保證有幾個在運行,根據需要修改個數
# 第三個參數是:如果進程個數不夠,應該執行什麼命令進行啓動。
check_and_restart StandaloneSessionClusterEntrypoint 1 "/root/software/flink-1.8.1/bin/start-cluster.sh"
check_and_restart TaskManagerRunner 35 "/root/software/flink-1.8.1/bin/taskmanager.sh start"
# check_and_restart namenode.NameNode 1 "/root/software/hadoop-2.8.5/sbin/start-all.sh"
將保活腳本分發到Flink集羣的所有機器上
$ scp -r /root/software/tools user@node3:/root/software/
腳本發送出去之後,將主節點上的namenode.NameNode 監測打開註釋。因爲只有主節點上有NameNode,其他節點沒有。
# 一般所有節點上都會啓動jobmanager,所以這一行可以每個節點都有;如果不是,只能在/root/software/flink-1.8.1/conf/masters文件中配置了的所有機器上執行這一行
check_and_restart StandaloneSessionClusterEntrypoint 1 "/root/software/flink-1.8.1/bin/start-cluster.sh"
# Flink集羣的所有節點都需要執行這一行,但是35這個數字需要根據機器情況進行調整,儘量不要超過CPU個數
check_and_restart TaskManagerRunner 35 "/root/software/flink-1.8.1/bin/taskmanager.sh start"
# 只在hadoop配置的主節點打開這一行的註釋。
check_and_restart namenode.NameNode 1 "/root/software/hadoop-2.8.5/sbin/start-all.sh"
2、配置crontab
* * * * * root bash /root/software/tools/software-check-restart.sh >> /root/software/tools/software-check-restart.log 2>&1