Spark的HiveThriftServer2进程耗尽文件句柄的问题
最近做了个POC, 每5分钟定期从spark streaming 的checkpoint取出rdd输出到hdfs的parquet目录, 然后通过连接池的hive jdbc长连接, 挂parquet到一个长期运行的HiveThriftServer2服务的外表partition上, 供web应用通过hive jdbc连接查询, 一开始几小时看起来没问题, 但是每经过十几个小时, HiveThriftServer2的driver进程就会出现 java.io.FileNotFoundException: [some path] (Too many open files)的错误, 导致所有hive客户端无法查询, 新的partition也挂不上去, 实际上服务已经不可用了.
初步判断是文件句柄没有回收,达到了系统ulimit上限造成的.
为了验证猜测, 找出HiveThriftServer2的进程号 pid, 比如3397
ps -ef|grep HiveThriftServer2
#这里获得了pid是3397
# ls一下看打开了啥文件
ls -l /proc/3397/fd
观察上面ls -l命令的输出发现打开了大量 /tmp/[username]/operation_logs目录下的文件句柄, 那些文件几乎都是空的.
用watch命令观察一段时间, 每隔30s调用一次命令看打开的句柄数, tee -a是保存这段时间的句柄数到文件.
watch -n 30 ls proc/3397/fd|wc|tee -a fds.log
检查了一下,这些文件几乎全是空文件. 为什么HiveThriftServer2进程不会释放这些看起来没啥用的文件句柄呢? 这些文件只是记录操作日志而已啊.
上网搜索了很久, 都没有找到通过配置的方式关闭HiveThriftServer2记录session operation logs的办法, 但是就知道是记录客户端请求的操作.
怀着试试看的心情,杀掉与HiveThriftServer2建立jdbc长连接的客户端进程, 看到服务端的fd数应声而降.
于是想到一个临时的办法, 修改jdbc客户端连接池配置, 我用的是c3p0,
initialPoolSize, maxPoolSize, minPoolSize: 1 #反正这个客户端只需要用到一个连接,所以,缩减到1
idleConnectionTestPeriod:0 #不做idle检查