1 背景
一臺服務(wù)器的端口數(shù)是有限的資源犀呼,如果端口被大量占用則會存在未知的故障飒硅。
案例:
線上HiveServer2發(fā)生故障: 大量任務(wù)hang住, 經(jīng)排查是因?yàn)榉?wù)器沒有可用的端口分配造成的涎嚼。
進(jìn)一步排查發(fā)現(xiàn),存在大量狀態(tài)為CLOSE_WAIT
的50010
端口連接刮吧。
而50010
端口是DN的移必,由此推斷應(yīng)該是存在流未關(guān)閉的情況。
2 定位
2.1 查看當(dāng)前端口數(shù)量使用情況
~]$netstat -tanp | grep "CLOSE_WAIT" | wc -l
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
43957
2.2 查看大量鏈接都是哪個進(jìn)程的
~]$ netstat -tanp | grep "CLOSE_WAIT" | awk '{print $NF}' | awk -F'/' '{print $1}' | sort | uniq -c
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
22476 63459
21484 63523
看下是什么進(jìn)程:
~]$ ps -ef | grep 63459
hadoop 5796 96249 0 17:21 pts/0 00:00:00 grep --color=auto 63459
hadoop 63459 1 99 Mar04 ? 39-01:46:41 /usr/local/jdk1.8.0_77//bin/java ...(省略) hive-service-1.2.1-325.jar org.apache.hive.service.server.HiveServer2
~]$ ps -ef |grep 63523
hadoop 5979 96249 0 17:21 pts/0 00:00:00 grep --color=auto 63523
hadoop 63523 1 99 Mar04 ? 41-10:04:18 /usr/local/jdk1.8.0_77//bin/java...(省略)hive-service-1.2.1-325.jar org.apache.hive.service.server.HiveServer2
可以看出是HiveServer2進(jìn)程遭殉。
2.3 查看都是什么連接
看下HiveServer2進(jìn)程都是什么連接:
~]$ netstat -tanp | grep "CLOSE_WAIT" | grep -E '63459|63523' | awk '{print $5}' | awk -F':' '{print $1,$NF}' | sort | uniq -c | sort -nk1
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
1 10.11.11.11 38673
...
10703 10.11.11.12 50010
10716 10.11.11.13 50010
10803 10.11.11.14 50010
50010端口連接有多少呢石挂?
~]$ netstat -tanp | grep 50010 | wc -l
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
43973
可以看出是大量的50010端口連接, 50010是DN的端口险污,由此可見存在訪問DN但未釋放連接的情況痹愚。
2.4 根因分析
2.4.1 是否是Hive引擎自身bug ?
首先,如果Hive引擎自身bug拯腮,這個問題早就應(yīng)該暴露出來窖式。
其次,Hive引擎連接泄漏的bug已經(jīng)修過好多了疾瓮,尤其是FileSystem
相關(guān)的脖镀,所以可能性不大。
最后狼电,我們查閱了社區(qū)相關(guān)issue蜒灰,沒有相關(guān)問題。
由于Hive提供了開放的UDF接口肩碟,從經(jīng)驗(yàn)判斷不規(guī)范的UDF也是有可能導(dǎo)致這個問題的强窖。
2.4.2 實(shí)錘定位UDF
我們抓取當(dāng)前日志加載的UDF函數(shù)包:
~]$ grep "Added resources" hive.log | awk '{print $NF}' | sort | uniq -c
經(jīng)分析抓取嫌疑最大的UDF并反編譯用戶UDF包發(fā)現(xiàn),用戶代碼邏輯存在讀取hdfs文件的情況削祈,且讀取文件后翅溺,未關(guān)閉流。
至此真想大白髓抑。
3 反思
Hive提供了特別開放的UDF接口咙崎,用戶可以自定義UDF實(shí)現(xiàn)任何你想到的邏輯(包括System.exists(1), 曾出現(xiàn)過用戶在UDF中調(diào)用System.exists(1)導(dǎo)致HiveServer2服務(wù)進(jìn)程退出的情況),開放的同時帶來了很大的安全隱患吨拍,尤其是采用HS2集中式服務(wù)的環(huán)境來說褪猛。
為保障服務(wù)的穩(wěn)定性,我們做了這么幾件事:
- 1)做服務(wù)器端口使用情況的監(jiān)控
- 2)HS2在UDF中禁用System.exists
- 3)在集中式HS2服務(wù)中羹饰,自定義UDF的發(fā)布需要有嚴(yán)格的代碼審查流程伊滋。
其中,第二點(diǎn)是需要對Hive源碼進(jìn)行改造的队秩。