問題及原因
搭建過一個hiveserver被ETL程序調(diào)用,hiveserver隔三差五地掛掉重啟,網(wǎng)上查了些資料,這是一個比較普遍的問題,原因基本上都是進(jìn)程內(nèi)存用爆引發(fā)的hiveserver奔潰,內(nèi)存爆掉的原因大概有兩個:
- hiveserver2會加載大量的元數(shù)據(jù),元數(shù)據(jù)多了,內(nèi)存就oom了
- 連接hiverserver2的sql性能慢,查詢時間超長,占用大量內(nèi)存
解決方法
目前內(nèi)存爆掉沒有太好的解決方法,一般的解決方法監(jiān)控和重啟,使用探針程序定時監(jiān)測hiveserver是否工作,如果不工作就重啟。另外啟動多個hiveserver,使用HA工具進(jìn)行切換,本文中采用HAProxy,HAProxy是一個開源的HA工具,可以工作在TCP層和HTTP層。
image.png
實踐方案
軟硬件配置
- 16G內(nèi)存服務(wù)器一臺
- Hive客戶端
- HAProxy
##使用不同的端口啟動三個hiveserver
hiveserver2 --hiveconf hive.server2.thrift.port=10000 &
hiveserver2 --hiveconf hive.server2.thrift.port=10001 &
hiveserver2 --hiveconf hive.server2.thrift.port=10004 &
##crontab定時執(zhí)行的檢查程序
##探針程序,每分鐘執(zhí)行一次,檢查hiveserver是否運行正常
java -jar HiveserverState-jar-with-dependencies.jar -Ddatasource=plumber -Dport=10000
if [ $? -ne 0 ]
then
##內(nèi)存監(jiān)控重定向到文件,查看hiveserver掛的那個時刻內(nèi)存的快照
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf
hive.server2.thrift.port=10000" | grep -v grep | awk '{print $2}' | xargs jstat -gcutil >> mem_stat.log
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf hive.server2.thrift.port=10000" | grep -v grep | awk '{print $2}' | xargs kill -9
nohup hiveserver2 --hiveconf hive.server2.thrift.port=10000 &
echo 'restart Hiveserver 10000 端口成功'
fi
java -jar HiveserverState-jar-with-dependencies.jar -Ddatasource=plumber -Dport=10001
if [ $? -ne 0 ]
then
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf hive.server2.thrift.port=10001" | grep -v grep | awk '{print $2}' | xargs jstat -gcutil >> mem_stat.log
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf hive.server2.thrift.port=10001" | grep -v grep | awk '{print $2}' | xargs kill -9
nohup hiveserver2 --hiveconf hive.server2.thrift.port=10001 &
echo 'restart Hiveserver 10001 端口成功'
fi
java -jar HiveserverState-jar-with-dependencies.jar -Ddatasource=plumber -Dport=10004
if [ $? -ne 0 ]
then
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf hive.server2.thrift.port=10004" | grep -v grep | awk '{print $2}' | xargs jstat -gcutil >> mem_stat.log
ps -ef|grep "org.apache.hive.service.server.HiveServer2 --hiveconf hive.server2.thrift.port=10004" | grep -v grep | awk '{print $2}' | xargs kill -9
nohup hiveserver2 --hiveconf hive.server2.thrift.port=10004 &
echo 'restart Hiveserver 10004 端口成功'
fi
- HA配置如下
listen hive #hive后端定義
bind 0.0.0.0:10003 #ha作為proxy所綁定的IP和端口
mode tcp #以4層方式代理,重要
balance leastconn #調(diào)度算法 'leastconn' 最少連接數(shù)分配,或者 'roundrobin',輪詢分配
maxconn 10240 #最大連接數(shù)
server hive_1 server_ip:10000 check inter 180000 rise 1 fall 2
server hive_2 server_ip:10001 check inter 180000 rise 1 fall 2
server hive_3 server_ip:10004 check inter 180000 rise 1 fall 2
image.png
問題及改進(jìn)
以上方法搭建的hiveserver只是相對高可用,應(yīng)對組內(nèi)的ETL任務(wù)已經(jīng)足夠了。因為只有一臺機(jī)器,所以存在單點故障,在實際生產(chǎn)環(huán)境中,可以使用兩臺機(jī)器作為HAProxy,另外三臺作為hiveserver。
參考文章
http://lanlian.blog.51cto.com/6790106/1305228
http://www.cnblogs.com/smartloli/p/4368676.html