目录
一、背景
我们公司是将AWS EMR集群作为长期使用的机器,因为创建流程简单而且管理容易,但是EMR集群里的Master实例组配置不能修改(例如从单节点集群改成高可用集群),只能通过销毁重建。
二、流程
-
查看任务进程
使用指令jps查看目前Master实例
其中参数
-m:输出main method的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
jps -ml
其中需要关注的是
263092 org.apache.hadoop.mapreduce.v2.hs.JobHistoryServer
264319 org.apache.hadoop.hdfs.server.namenode.NameNode
363455 org.apache.hadoop.util.RunJar /usr/lib/hive/lib/hive-metastore-2.3.2-amzn-2.jar org.apache.hadoop.hive.metastore.HiveMetaStore
370104 org.apache.spark.deploy.history.HistoryServer
79671 org.apache.hadoop.yarn.server.resourcemanager.ResourceManager
-
编写脚本查询历史接入的IP
以下面的NameNode进程为例:
264319 org.apache.hadoop.hdfs.server.namenode.NameNode
根据进程号查看该进程目前连接的IP地址
使用指令netstat -anpt | grep 264319
其中参数
-a (all)显示所有选项,默认不显示LISTEN相关
-n 拒绝显示别名,能显示数字的全部转化成数字。
-t (tcp)仅显示tcp相关选项
-p 显示建立相关链接的程序名
netstat -anpt | grep 264319
tcp 0 0 master节点ip:端口号 0.0.0.0:* LISTEN 264319/java
tcp 0 0 master节点ip:端口号 接入的IP:接入的端口号 ESTABLISHED 264319/java
这样就能看到目前该服务所使用的端口号
部分进程是平时一直开启,但连接过来的IP仅持续一小段时间后再断开,所以需要编写脚本,持续记录接入的IP信息
#!/bin/bash
step=1 #间隔的秒数
for (( i = 0; i < 60; i=(i+step) )); do
netstat -anpt|grep 端口号 |grep ESTABLISHED |grep 进程号 >> /var/lib/hadoop-hdfs/established.txt
sleep $step
done
exit 0
需要编写脚本记录接入IP的进程有:
NameNode
HiveMetaStore
HistoryServer
JobHistoryServer
HiveServer2
-
编写脚本流程
使用ps -ef指令查看进程的启动角色
ps -ef |grep 进程号
例如:
ps -ef |grep NameNode
hdfs 5983 1 22 2020 ? 170-12:16:39 org.apache.hadoop.hdfs.server.namenode.NameNode
可以看到,启动NameNode的用户是hdfs
根据进程切换到对应的用户再创建脚本
创建脚本文件
#先检查脚本文件是否存在,若存在则修改成其他的脚本名字
ll established_HistoryServer.sh
#再创建空的脚本文件
touch established_HistoryServer.sh
#检查脚本文件是否创建成功
ll established_HistoryServer.sh
打开脚本文件
vi established_HistoryServer.sh
按 i 进入编辑模式
复制以下代码
※注意修改3处位置
- 进程号
- 端口号
- 输出的文本名字 ※注意不要与其他脚本输出的文件名相同
#!/bin/bash
#用于捕获访问 XX服务 XX端口号 的IP地址
step=1 #间隔的秒数
for (( i = 0; i < 60; i=(i+step) )); do
netstat -anpt|grep 进程号 |grep 端口号 |grep ESTABLISHED >> ./输出的文档名字.txt
sleep $step
done
exit 0
脚本中代码的意义如下
查看当前的所有网络链接
netstat -anpt
查对应进程号的记录
grep 进程号
查NameNode端口号的数据
grep 端口号
查处于ESTABLISHED状态的数据
※ESTABLISHED的意思是建立连接。表示两台机器正在通信。
grep ESTABLISHED
将结果输出到当前脚本路径下的文档
>> ./输出的文档名字.txt
按 esc 退出编辑模式
输入 :wq 保存并退出
退出编辑模式后,输入
cat 脚本名.sh
查看执行脚本
输入
ls `pwd`/脚本名.sh
查看脚本的绝对路径
-
开启定期执行脚本指令
使用
crontab -e
修改 crontab 文件
不要修改其他记录
追加下面的内容
※意义为每分钟执行一次
* * * * * 脚本的绝对路径.sh
输入 :wq 保存并退出
输入
chmod 777 脚本名.sh
将脚本的属性改成777,不然可能无法执行
执行时间周期的写法可以参考下面文档
※若输出为空,即没有捕获到IP时,创建的txt文件的更新日期不会变
查看crontab 的执行情况:
tail -20 /var/log/cron
cron文件记录着执行的脚本和用户
-
分析输出的数据
用下面的指令分析这个进程的链接IP的个数
cat 输出的文档名字.txt |awk '{print $5}' |awk -F":" '{print $1}' | sort |uniq -c |sort -n
其中该指令中
将文本按空格切割后,输出第5个字段
※没有-F默认以空格作为分隔符
awk '{print $5}'
定义切割符:-F":",将文本切割后,输出第1个字段
awk -F":" '{print $1}'
将输出的IP进行排序
sort
uniq :删除文本文件中重复出现的行列
参数-c:在每列旁边显示该行重复出现的次数
uniq -c
将输出的重复出现的次数和IP进行排序
sort -n
然后再一个个排查IP所对应的业务,要求他们修改请求的服务地址,不然销毁集群后会报错
-
清空记录文件
为了重新记录接入的IP,需要清空输出的文件
使用下面的指令:
cat /dev/null > 输出的文档名字.txt
其中
null文件为特殊系统文件,内容为空
/dev/null
【>】为覆写后面的文档
> 输出的文档名字.txt
别的统计接入IP的方法:
使用抓包的方法,捕获所有接入的IP
tcpdump -nn -q -l | awk '{print $3,gensub(":","","g",$5)}' | grep -v ^10.1.191.22 | awk '{print gensub("\\.",":",4,$1),gensub("\\.",":",4,$2)}' |awk '{ ip = $0 ; if(!d[ip]) { print ip; d[ip]=1; fflush(stdout) }}' >> tcpdump_port
- 抓包
- 将输出的数据整形成 ip.端口 ip.端口
- 去除自身发出的请求记录
- 再整形成 ip:端口 ip:端口
- 把输出的内容定义为IP,且不重复输出
此外,为了在后台执行 tcpdump 指令,使用screen指令创建会话
screen -S tcpdump_HistoryServer
其中 -S 是为了给会话设定名字
参考 linux screen 命令详解 - David_Tang - 博客园
进入会话后,执行上按键盘ctrl + a + d 断开(detach)会话,保持后台运行
使用指令查看所有的会话
screen -ls
使用指令链接回会话
screen -r 会话前面的数字
三、修改调度机配置
-
hiveserver2
当使用链接串来访问hiveserver2时,作业会通过有HiveServer2服务的调度机提交到EMR集群中,再访问当前集群的HiveMetaStore服务,所以光看接入过来的IP是无法查看到具体是哪个作业
所以需要查看HiveServer2服务的机器的日志,查看有哪些作业申请过来
首先查看机器上的HiveServer2服务
jps -ml |grep HiveServer2
查到对应进程号后,查看log所在日志
ps -ef|grep 进程号 |grep log
看到日志路径在
/mnt/var/log/hive/hiveserver2
使用以下指令分析这台机器中接入过的IP
cat hive-HIVESERVER.log* |grep ipAddress |awk '{print $8}'|awk -F"," '{print $4}' |awk -F":" '{print $2}' | sort |uniq -c |sort -n | tr '"' ' '
-
HiveMetaStore
部分作业不经过hiveserver2进行任务调度,而是直接根据调度机中spark的配置,使执行任务的datanode直接连接到集群的metastore服务
所以需要查看metastore.log中的表是什么,然后再去查执行作业的跳板机
cd /mnt/var/log/hive
cat metastore.log* |grep -a tableName |grep logInfo |awk '{print $10}' |awk -F":" '{print $2}' |awk -F"," '{print $1}' | sort |uniq -c|sort -n
zcat metastore.log.*.gz |grep tableName |grep logInfo |awk '{print $10}' |awk -F":" '{print $2}' |awk -F"," '{print $1}' | sort |uniq -c|sort -n
如果不是对表进行查询,而是直接查询元数据的话,是没有tableName 的,需要下面这代码进行分析接入的IP
对于metastore.log
grep ip= metastore.log |awk '{print $8}'|sort |uniq -c|sort -n
对于历史metastore.log
zcat metastore.log.2* |grep ip= |awk '{print $8}'|sort |uniq -c|sort -n
-
Hdfs服务
集群的hdfs有在被当成单独的hdfs集群使用,所以还需要排查是否有人在读写该集群的hdfs文件
如果没有开启审计日志,则需要去开启
开启方法后面补
日志路径通常保存在这里
/var/log/hadoop-hdfs/hdfs-audit.log
使用以下指令去排查具体使用集群hdfs服务的IP
grep ip hdfs-audit.log |awk '{print $8}'|sort |uniq -c|sort -n
也可以使用以下指令去排查具体访问的文件路径
grep src hdfs-audit.log |awk '{print $10}'|sort |uniq -c|sort -n
要排除Spark或者Hive的中间文件的话使用以下指令
grep src hdfs-audit.log |grep -v -E '/var/log/spark/apps/.|/var/log/hadoop-yarn/apps|/tmp/hadoop-yarn/staging/history/done' |awk '{print $10}'|sort |uniq -c|sort -n
登录接入过来的IP机器,检查默认HDFS集群是什么,如果是待销毁集群的hdfs则需要修改core-site.xml的配置
hdfs dfs -df -h
操作步骤:
先检查对应的hdfs-site.xml中dfs.nameservices是否有配置替换用的Hdfs集群
vi /etc/hadoop/conf/hdfs-site.xml
<property>
<name>dfs.nameservices</name>
<value>要销毁的集群hdfs</value>
</property>
这种就是没有配置,需要备份原文件后,修改成替换用的Hdfs集群
再备份core-site.xml配置文件
cp /etc/hadoop/conf/core-site.xml /etc/hadoop/conf/core-site.xml_bak
修改配置文件
vi /etc/hadoop/conf/core-site.xml
修改以下位置
<name>fs.defaultFS</name>
<value>hdfs://待销毁集群的hdfs</value>
改成
<value>hdfs://替换用的hdfs</value>
检查HDFS集群是否成功
hdfs dfs -df -h
-
Hive服务
配置路径:
/etc/hive/conf
配置文件路径:
/etc/hive/conf/hive-site.xml
操作步骤:
先备份配置文件
cp /etc/hive/conf/hive-site.xml /etc/hive/conf/hive-site.xml_bak
修改配置文件
vi /etc/hive/conf/hive-site.xml
修改以下2个位置
<name>fs.defaultFS</name>
<value>hdfs://待销毁集群hdfs</value>
改成
<value>hdfs://替换用的hdfs</value>
<name>hive.metastore.uris</name>
<value>thrift://待销毁集群metastore连接串</value>
改成
<value>thrift://替换用集群metastore连接串</value>
使用指令登陆到hiveserver2后,查看数据库来验证配置是否成功
show databases;
-
Spark服务
配置路径:
/etc/spark/conf
配置文件路径:
/etc/spark/conf/hive-site.xml
操作步骤:
先备份配置文件
cp /etc/spark/conf/hive-site.xml /etc/spark/conf/hive-site.xml_bak
修改配置文件
vi /etc/spark/conf/hive-site.xml
修改以下2个位置
<name>fs.defaultFS</name>
<value>hdfs://待销毁集群hdfs</value>
改成
<value>hdfs://替换用的hdfs</value>
<name>hive.metastore.uris</name>
<value>thrift://待销毁集群metastore连接串</value>
改成
<value>thrift://替换用集群metastore连接串</value>
备份spark-defaults.conf,将里面还有待销毁集群信息的地方全部进行修改
cp /etc/spark/conf/spark-defaults.conf /etc/spark/conf/spark-defaults.conf_bak
使用指令登陆到livyserver后,验证配置是否成功
show databases;
四、停止服务
在停止服务之前需要通知业务一声
停止服务指令参考
《如何在 Amazon EMR 中重启服务》
查看metastore服务
status hive-hcatalog-server
※HCatalog底层依赖于Hive Metastore
停止服务
stop hive-hcatalog-server
查看服务是否停止
status hive-hcatalog-server
遇到问题需要重新启动服务
start hive-hcatalog-server
同理:ResourceManager服务
status hadoop-yarn-resourcemanager
stop hadoop-yarn-resourcemanager
status hadoop-yarn-resourcemanager
或
systemctl status hadoop-yarn-resourcemanager.service
systemctl stop hadoop-yarn-resourcemanager.service
systemctl status hadoop-yarn-resourcemanager.service
同理:Namenode服务
status hadoop-hdfs-namenode
stop hadoop-hdfs-namenode
status hadoop-hdfs-namenode
或
systemctl status hadoop-hdfs-namenode.service
systemctl stop hadoop-hdfs-namenode.service
systemctl status hadoop-hdfs-namenode.service
同理:historyserver服务
status hadoop-mapreduce-historyserver
stop hadoop-mapreduce-historyserver
status hadoop-mapreduce-historyserver
五、销毁集群
登录EMR页面,将【终止保护】设置成关闭后,再选择【终止】即可
建议:因为EMR集群销毁后是不能回滚的,所以在销毁前先修改安全组,使没有任何业务或者机器能访问该集群,这样静置一段时间后再销毁。但由于这样静置一样需要向AWS付费,所以是否静置需要自行决定。