背景
通过beeline无法连接sparksql thrift服务;10000端口存在,yarn applicationMaster跳转页面正常
${SPARK_HOME}/bin/beeline!connect jdbc:hive2://10.3.71.124:10000
- 错误信息如下:(java.net.SocketException: Connection reset (state=08S01,code=0) )
0 [main] INFO org.apache.hive.jdbc.Utils - Supplied authorities: 10.3.71.124:100001 [main] INFO org.apache.hive.jdbc.Utils - Resolved authority: 10.3.71.124:1000095 [main] INFO org.apache.hive.jdbc.HiveConnection - Will try to open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:1000020100 [main] INFO org.apache.hive.jdbc.HiveConnection - Could not open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:1000020101 [main] INFO org.apache.hive.jdbc.HiveConnection - Transport Used for JDBC connection: nullError: Could not open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:10000: \java.net.SocketException: Connection reset (state=08S01,code=0)
yarn applicationMaster页面点击JDBC/ODBC Server页面
· Started at: 2020/05/13 14:15:33· Time since start: 2 days 1 hour 50 minutes500 session(s) are online, running 1 SQL statement(s)Session Statistics (500)
- 500个session,有点不正常;通过查看另外一个thrift 服务(才56)
- 在thrift server对应的服务器执行netstat -tunalp |grep 10000 |wc -l 得到连接数为504
分析
设置sparksql thrift连接数
Hiveserver2允许在配置文件hive-site.xml中进行配置管理,常用参数有:
hive.server2.thrift.min.worker.threads #最小工作线程数,默认为5。hive.server2.thrift.max.worker.threads #最大工作线程数,默认为500。hive.server2.thrift.port #TCP 的监听端口,默认为10000。hive.server2.thrift.bind.host #TCP绑定的主机,默认为localhost。
也可以设置环境变量HIVE_SERVER2_THRIFT_BIND_HOST和HIVE_SERVER2_THRIFT_PORT覆盖hive-site.xml设置的主机和端口号。
hive.server2.thrift.port 10000hive.server2.thrift.bind.host 192.168.48.130
从Hive-0.13.0开始,HiveServer2支持通过HTTP传输消息,该特性当客户端和服务器之间存在代理中介时特别有用。与HTTP传输相关的参数如下:
hive.server2.transport.mode #默认值为binary(TCP),可选值HTTP。hive.server2.thrift.http.port #HTTP的监听端口,默认值为10001。hive.server2.thrift.http.path #服务的端点名称,默认为 cliservice。hive.server2.thrift.http.min.worker.threads #服务池中的最小工作线程,默认为5。hive.server2.thrift.http.max.worker.threads #服务池中的最小工作线程,默认为500。
排查client连接泄露
在thrift服务所在机器统计与10000建立连接的对应端口号、ip
- 确定最多的IP,到该机器通过得到端口列表定位到具体的PID
- 确定PID对应的服务
#!/bin/bashfor port in `cat ./ports.txt`;dopid=`lsof -i:$port | grep -v PID | awk '{print $2}'`ps -ef | grep $pid >> ./pids.txtdone
通过连接统计发现数据集成微服务有465个连接
- 但是,从设计上面来说,连接thrift这个操作目前只有一个地方:dataChannel;并且其完全被数据管理微服务进行功能封装表达;即与thrift server建立的连接应该只有数据管理微服务
排查
- 按照理论设计,所以只需要查询那些服务依赖了dataChannel或者更底层的HiveDriver;经排查数据集成微服务的确依赖了dataChannel
- 查找具体那块代码逻辑使用了dataChannel里面的逻辑;经沟通,整库迁移模块创建目标表调用了HiveChannel
- 创建了HiveChannel,并没有进行相关连接关闭
- 可能是没有意识到HiveChannel需要手动进行连接关闭(对象销毁)
- 缺陷修复:按照理论设计,直接使用数据管理提供的feign接口进行目标表创建
- 创建了HiveChannel,并没有进行相关连接关闭
验证
启动thrift服务(连接数设置为6)
${SPARK_HOME}/sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.max.worker.threads=6
- 服务日志输出截取如下 ```basic 10423 [main] INFO org.apache.hive.service.AbstractService - Service:ThriftBinaryCLIService is started. 10423 [main] INFO org.apache.hive.service.AbstractService - Service:HiveServer2 is started. 10423 [main] INFO org.apache.spark.sql.hive.thriftserver.HiveThriftServer2 - HiveThriftServer2 started 10434 [main] INFO org.spark_project.jetty.server.handler.ContextHandler - Started o.s.j.s.ServletContextHandler@6cb759d5{/sqlserver,null,AVAILABLE,@Spark} 10434 [main] INFO org.spark_project.jetty.server.handler.ContextHandler - Started o.s.j.s.ServletContextHandler@2ba9765b{/sqlserver/json,null,AVAILABLE,@Spark} 10435 [main] INFO org.spark_project.jetty.server.handler.ContextHandler - Started o.s.j.s.ServletContextHandler@a36ff0b{/sqlserver/session,null,AVAILABLE,@Spark} 10435 [main] INFO org.spark_project.jetty.server.handler.ContextHandler - Started o.s.j.s.ServletContextHandler@1ecf784f{/sqlserver/session/json,null,AVAILABLE,@Spark} 10493 [Thread-32] INFO org.apache.hive.service.cli.thrift.ThriftCLIService \
Starting ThriftBinaryCLIService on port 10000 with 5…6 worker threads ```
- ThriftBinaryCLIService on port 10000 with 5...6 worker threads # 其中的5...6对应最小、大连接数
- 通过${SPARK_HOME}/bin/beeline进行连接
- 连接5次,第6次连接失败
- 第4次exit,第6次重新连接成功
总结
- 对于资源(数据库、服务连接)使用,尽量使用spring的bean进行管理
- 资源封装的代码应该清晰、明确的在注释里面写明资源开辟(建立连接)与资源销毁(关闭连接)
- 比如,(construct、destroy)、(open、close)方法成对显式出现及调用
- 不建议隐式的调用open,比如在构造函数里面隐式调用open
- 比如,(construct、destroy)、(open、close)方法成对显式出现及调用
