背景

  • 通过beeline无法连接sparksql thrift服务;10000端口存在,yarn applicationMaster跳转页面正常

    1. ${SPARK_HOME}/bin/beeline
    2. !connect jdbc:hive2://10.3.71.124:10000
    • 错误信息如下:(java.net.SocketException: Connection reset (state=08S01,code=0) )
      1. 0 [main] INFO org.apache.hive.jdbc.Utils - Supplied authorities: 10.3.71.124:10000
      2. 1 [main] INFO org.apache.hive.jdbc.Utils - Resolved authority: 10.3.71.124:10000
      3. 95 [main] INFO org.apache.hive.jdbc.HiveConnection - Will try to open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:10000
      4. 20100 [main] INFO org.apache.hive.jdbc.HiveConnection - Could not open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:10000
      5. 20101 [main] INFO org.apache.hive.jdbc.HiveConnection - Transport Used for JDBC connection: null
      6. Error: Could not open client transport with JDBC Uri: jdbc:hive2://10.3.71.124:10000: \
      7. java.net.SocketException: Connection reset (state=08S01,code=0)
  • yarn applicationMaster页面点击JDBC/ODBC Server页面

    1. · Started at: 2020/05/13 14:15:33
    2. · Time since start: 2 days 1 hour 50 minutes
    3. 500 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中进行配置管理,常用参数有:

  1. hive.server2.thrift.min.worker.threads #最小工作线程数,默认为5。
  2. hive.server2.thrift.max.worker.threads #最大工作线程数,默认为500。
  3. hive.server2.thrift.port #TCP 的监听端口,默认为10000。
  4. hive.server2.thrift.bind.host #TCP绑定的主机,默认为localhost。

也可以设置环境变量HIVE_SERVER2_THRIFT_BIND_HOST和HIVE_SERVER2_THRIFT_PORT覆盖hive-site.xml设置的主机和端口号。

  1. hive.server2.thrift.port 10000
  2. hive.server2.thrift.bind.host 192.168.48.130

从Hive-0.13.0开始,HiveServer2支持通过HTTP传输消息,该特性当客户端和服务器之间存在代理中介时特别有用。与HTTP传输相关的参数如下:

  1. hive.server2.transport.mode #默认值为binary(TCP),可选值HTTP。
  2. hive.server2.thrift.http.port #HTTP的监听端口,默认值为10001。
  3. hive.server2.thrift.http.path #服务的端点名称,默认为 cliservice。
  4. hive.server2.thrift.http.min.worker.threads #服务池中的最小工作线程,默认为5。
  5. hive.server2.thrift.http.max.worker.threads #服务池中的最小工作线程,默认为500。

排查client连接泄露

  • 在thrift服务所在机器统计与10000建立连接的对应端口号、ip

    • 确定最多的IP,到该机器通过得到端口列表定位到具体的PID
    • 确定PID对应的服务
      1. #!/bin/bash
      2. for port in `cat ./ports.txt`;
      3. do
      4. pid=`lsof -i:$port | grep -v PID | awk '{print $2}'`
      5. ps -ef | grep $pid >> ./pids.txt
      6. done
  • 通过连接统计发现数据集成微服务有465个连接

  • 但是,从设计上面来说,连接thrift这个操作目前只有一个地方:dataChannel;并且其完全被数据管理微服务进行功能封装表达;即与thrift server建立的连接应该只有数据管理微服务

**

排查

  • 按照理论设计,所以只需要查询那些服务依赖了dataChannel或者更底层的HiveDriver;经排查数据集成微服务的确依赖了dataChannel
  • 查找具体那块代码逻辑使用了dataChannel里面的逻辑;经沟通,整库迁移模块创建目标表调用了HiveChannel
    • 创建了HiveChannel,并没有进行相关连接关闭
      • 可能是没有意识到HiveChannel需要手动进行连接关闭(对象销毁)
    • 缺陷修复:按照理论设计,直接使用数据管理提供的feign接口进行目标表创建

验证

  • 启动thrift服务(连接数设置为6)

    1. ${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 ```

    1. - 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