最近在针对某零碎进行性能优化时,发现了一个hive on spark 模式下应用 HikariCP 数据库连接池造成的资源泄露问题,该问题具备普适性,故顺便拿进去跟大家分享下。

1 问题形容

  • 在微服务中,咱们广泛会应用各种数据库连接池技术以放慢获取数据库连贯并执行数据查问的速度,这实质是一种空间换工夫的无效的性能优化的思路。
  • 推而广之,在大数据场景下通过JDBC拜访HiveServer2并提交数据查问SQL语句时,也很容易想到同样应用数据库连接池技术以放慢作业速度。
  • 然而相比一般的RDBMS,Hive的JDBC连贯更重,以HIVE ON SPARK模式运行作业时更是如此,因为当连贯底层须要执行SQL时,HS2会向YARN申请CONTAINER资源,而后启动分布式的SPARK ON YARN集群并分布式地执行编译好的SQL,当该SQL执行结束后并不会立刻开释SAPRK ON YANR资源,而是会期待一段时间以复用这些 SPARK ON YARN资源执行客户端通过该连贯提交的新的SQL,只有当该JDBC连贯敞开时,或者达到了配置的超时工夫而客户端仍没有提交新的SQL时,才会彻底开释这些 SPARK ON YARN 资源。
  • 当业务代码应用了数据库连接池技术时,因为其敞开JDBC连贯时实质上只是将连贯归还给了连接池而没有真是敞开底层的JDBC连贯,所以连贯背地的 SPARK ON YARN资源并不会被及时开释也就是造成了资源泄露,此时其它作业向YARN申请资源时就须要排队期待,从而影响了其它作业的执行。
  • 本案列中该零碎应用了HikariCP 数据库连接池,且没有配置数据库连贯的闲暇超时时长(idletimeout),真正失效的闲暇超时时长是Hikari源码层面配置的默认值10分钟,所以每个连贯底层的SQL作业执行结束后都须要10分钟才真正开释了背地的SPARK ON YARN资源,从而造成了其它作业对YANR资源的排队和期待。(话说你占着资源却不应用,不就是站着那个啥不干那个啥么~_~)

2 问题解决方案

针对该问题进行剖析,解决方案有多个,如下别离进行形容。

2.1 解决方案1

该计划的思路是彻底摒弃数据库连接池,因为一般而言,大数据作业善于的是大数据量和简单逻辑的解决,其作业执行速大都在分钟级别以上,数据库连接池节俭的1到2秒钟简直微不足道,所以思考到这些应用上的弊病罗唆弃之不必。

2.2 解决方案2

  • 该计划的思路是配置HS2 背地SPARK ON YARN集群的SESSION超时工夫,从而更快地开释 SPARK ON YARN 资源。
  • 然而通过测试并查看源码发现该超时工夫的最小值是30分钟不能设置更小值,所以起不了成果。
  • 相干参数有:

    • hive.spark.session.timeout:默认值30m最小值30m;
    • hive.spark.session.timeout.period:默认值60s最小值60s;

2.3 解决方案3

  • 该计划的思路是配置Spark on yarn的动静资源分配机制,从而使得spark on yarn集群在没有SQL作业须要执行时并不会占用太多YARN资源。
  • 然而因为SPARK 集群至多须要1个CONTAINER以执行DRIVER,所以该计划只能缓解问题不能彻底解决问题。
  • 相干参数有:

    • spark.dynamicAllocation.enabled,须要配置为true;
    • spark.dynamicAllocation.minExecutors:默认为1能够进一步调整为0;

2.4 解决方案4

  • 该计划的思路是配置客户端和HS2 之间的SESSION超时工夫,从而让HS2被动断开客户端的JDBC连贯并开释背地的Spark ON YARN资源。
  • 经测试该计划可行,但批改相干参数须要重启hs2服务过程且该参数的批改会影响所有用户作业,个别集群管理员可能会有异议;
  • 相干参数有:

    • hive.server2.session.check.interval:不同版本默认值不同,比方15m/6h;
    • hive.server2.idle.session.timeout:不同版本默认值不同,比方4h/12h/7d;
    • hive.server2.idle.operation.timeout:不同版本默认值不同,比方2h/6h;
    • hive.server2.idle.session.check.operation:true

如下日志可见,session timeout 被敞开后,spark session 也别清理了:

2.5 解决方案5

  • 该计划的思路是调整数据库连接池的相干参数尤其是最小连接数和闲暇超时工夫,从而更快地更踊跃地被动敞开闲暇的数据库连贯,比方将IdleTimeout配置为30秒,将最小连接数MinimumIdle配置为0,则SQL作业运行结束30秒后就会敞开所有连贯,也就会开释所有SPARK ON YARN资源,从而解决了资源泄露问题;
  • 相干hikariConfig参数有:

    • MinimumIdle:最小连接数;
    • MaximumPoolSize:最大连接数;
    • IdleTimeout:闲暇超时工夫;
    • ConnectionTimeout:获取连贯超时工夫;
    • ValidationTimeout:连贯无效行验证超时工夫;
    • KeepaliveTime:闲暇连贯保活间隔时间;
    • MaxLifetime:连贯最大工夫;
  • 示例代码如下:

3 知识点总结

  • 大数据作业善于的是大数据量和简单逻辑的解决,其作业执行速大都在分钟级别以上,数据库连接池节俭的1到2秒钟简直微不足道,所以大数据作业个别不应用数据库连接池;
  • 当应用数据库连接池时,因为相比一般的RDBMS,Hive的JDBC连贯更重,以 HIVE ON SPARK 模式运行作业时更是如此,所以肯定要及时开释JDBC连贯从而及时开释背地的 YARN资源,从而防止资源泄露问题引起其它作业长时间期待YARN资源;
  • 应用数据库连接池时,为及时开释JDBC连贯从而及时开释背地的YARN资源,个别能够调整数据库连接池的相干参数,尤其是最小连接数和闲暇超时工夫,从而更快地更踊跃地被动敞开闲暇的数据库连贯,比方将IdleTimeout配置为30秒,将最小连接数MinimumIdle配置为0,则SQL作业运行结束30秒后就会敞开所有连贯,也就会开释所有SPARK ON YARN资源,从而解决了资源泄露问题。