hiveserver2不稳定,监控hiveserver2,hiveserver2重启。
作者:草小诚(wellsmile@foxmail.com)
转载请注原文地址:https://blog.csdn.net/cxcjoker7894/article/details/88314562
公司BI系统对Hive的集成是通过beeline连接hiveserver2服务实现的,在实际使用中,试过了阿里云和腾讯云,hiveserver2都不是很稳定,会间或出现一些断连,内存无法分配,或是直接卡住无反应的问题,前者都会抛出异常,很好处理,所以本文主要针对的是无反应的问题。
思路是设置超时时间,如果单条hive sql超过一定的时间,就认为hiveserver2已死,重启服务,并进行重试,如是循环3次。
云服务商提供的系统服务会通过crontab自动监测,如果服务死亡会重启,所以想要重启hiveserver2只需要杀死即可,这里的7001是我的hiveserver2的端口号,此脚本意为杀掉在7001端口上提供服务的进程:
PS2=$(/bin/netstat -ntlp | grep 7001)
IFS=' '
arr=($PS2)
mv_pid=${arr[6]}
IFS='/'
arr=($mv_pid)
mv_pid_correct=${arr[0]}
kill -9 $mv_pid_correct
之后就可以在系统中进行异常处理,当出现各种异常时调用上述脚本,之后进行重试,最多进行3次重试,若3次都未成功则放弃。
这里采用的是【使用subprocess和shlex获取Hive运行结果】的方式(若下面代码不好理解请先阅读链接再看),超时设置通过subprocess.run()的timeout参数实现。
failed = True
count = 1
while failed and (count<=3):
try:
args = shlex.split(cmd_rendered)
complted_process = subprocess.run(args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=timeout) # 通过timeout参数设置超时
# 如果成功则返回运行结果
if complted_process.returncode == 0:
failed = False
returned_data = complted_process.stdout.decode('utf-8').strip().split('\n')
return returned_data
# 如果抛出异常则进入解决函数
else:
print('HIVE ERROR1: '+cmd_rendered)
print(complted_process.stderr)
self.error_solve(product_name, refer, count)
except Exception as e:
# 如果出现异常或超时,进入解决函数
print('HIVE ERROR2: '+cmd_rendered)
print(e)
logging.exception(e)
self.error_solve(product_name, refer, count)
finally:
count += 1
def error_solve(self, product_name, refer, count):
# 向我的邮箱发送通知邮件
os.system('/bin/echo "{content}" | /bin/mail -s "{title}" {adress}'.format(**{'title': settings.HIVE_WARN_EMAIL_TITLE,
'adress': settings.HIVE_WARN_EMAIL_ADRESS,
'content': 'one sql has been error:\n product: %s \n refer: %s' % (product_name,refer)}))
print('error in %s times' % str(count))
# 运行上面的杀进程脚本
os.system('/home/hadoop/kill_hiveserver2.sh')
# 等待服务重启
time.sleep(10*60)
如此,当出现各种异常,或是单条sql超过timeout所设时长时,会重启hiveserver2服务并再次尝试,使系统数据运行完整。
缺点:这样通过监控来解决,治标不治本,且当数据量大时需要设置较长的timeout,如果是一个快速的sql死亡,也会等待最长timeout才进行重启,而如果为每个sql单独设置timeout,待数据量级变多sql运行时长逐渐增加超过时限时,难以进行修改维护。所以还是设置一个统一的最大timeout,这样势必会浪费一定的时间。