目录
一、问题说明
BI平台出现了查询时快时慢的问题,查看监控发现获取连接部分耗时飙升,相关监控如下:
正常情况下获取连接耗时P99都在100ms以内,但是从某天开始,其耗时飙升到峰值时需要262k毫秒,严重拖慢了查询耗时。
二、原因查明
1. 数据库连接池
系统中使用的C3P0连接池,连接参数部分只设置了jdbcUrl、username、password、maxPoolSize和minPoolSize。 其中,maxPoolSize为20,minPoolSize为1。
2. Impala连接参数
Impala中fe_service_threads可以用来设置单个coordinater最大连接数,未对该参数作改动,默认为64,其具体含义为:
-
fe_service_threads值分别对Beeswax pool(impala shell等)、Hive Server2pool(jdbc\hue等)生效,即当配置值为64时,表示该节点最大可支持128个客户端连接,其中Beeswax pool 64个,hiveserver2 pool 64个;fe_service_threads配置是对节点(coordinater)而言地,如当集群存在2个coordinater节点,并且fe_service_threads的配置为64时,集群最大可提供256个客户端连接;
-
fe_service_threads限制包括空闲连接在内的所有客户端连接,并不是单位时间的查询并发数。
-
同一时间connection和session的对应关系是一一对应地,当手动关闭session时,连接会在下一次查询提交时重建session,不会引起错。
-
session关闭可能connection未关闭,session存在connection一定存在。
3. 应用近期改动
由于公司最近推进容器化部署,第一阶段需进行混合部署,即发布一定数量的容器化服务并且不下线已有虚拟机服务,因此提供服务的机器数量从4台变为了8台。
4. 集群中连接建立数量
使用如下命令查看各IP在 Impala 查询服务端口 21050(对于mysql则为3306)上建立连接数量情况。
sudo netstat -nat | grep 21050 | grep ESTABLISHED | awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn
总共8台线上机器连接Impala集群,集群中有四台Coordinater,查看发现每台Coordinater 21050端口连接数量都在80及以上,这已经超出了Impala最大连接数量了。
结合以上原因,推测是增加服务机器后引起,将提供服务的机器数量从8台降低为4台之后,线上服务获取OLAP查询引擎连接耗时回归正常区间。
三、问题复现
开启初始线程数64、最大线程数64、最小线程数64的服务,连接四台Coordinater,这样在发起查询时会产生大量的Connection,使得端口连接建立数超过Impala集群单Coordinater最大允许连接数。
服务启动后,查看监控发现getConnection耗时确实又上去了。
直接访问本地压测程序查询接口,结果响应很快,不存在查询缓慢的情况;使用Web页面查询,偶尔结果响应很慢。
当把压测程序关闭后,端口连接建立数量恢复正常,此时查询未再出现变得十分缓慢的情况。
猜测是因为后端开启了多个连接线程池,每个线程池在每台Coordinater建立的连接数量不同。当在Web进行查询时,随机被发往8台机器中任意一台,然后任意一台又将请求发往集群中4台Coordinater的任意一个。
而某台机器的连接池中Connection建立数量较少,新请求过来需要建立新的连接,但当前Impala Connection 已有连接数
超过最大连接数
,因此getConnection阻塞等待成功获取到连接。其中阻塞等待超时时间与--accepted_client_cnxn_timeout
参数有关。
四、问题解决
核心其实就两点,增大集群最大连接数 或者 减小应用连接池最大值大小,最终目的是使得 服务机数量*连接池最大连接数 <= Impala机器最大连接数。
具体操作:
- 应用连接池端:
- 减少应用端开启连接数量,即降低连接池最大连接数(需要注意连接数与性能间的平衡点)。
- 缩小
acquireIncrement
参数,减小每次需要创建新连接时,额外创建的连接数量。 - 关闭超过最小连接数的闲置连接,通过设置
maxIdleTimeExcessConnections
可实现。 - 缩小
acquireRetryAttempts
参数,避免过多重试导致请求迟迟不返回。
- Impala集群端:
- 修改
--fe_service_threads
参数,用于调大Impala端最大连接数,使其等于 服务机器数* 最大线程数。 - 缩小
--accepted_client_cnxn_timeout
参数,以缩短当集群达到最大连接数后 客户端需创建新连接时等待的超时时间。 - 缩小
--disconnected_session_timeout
参数,以便快速清除断开连接的会话。如果客户端在没有驱动程序明确关闭会话的情况下断开连接(例如,由于网络故障),断开连接的会话和与其关联的查询可能保持打开状态并继续消耗资源,直到断开连接的会话超时,因此该参数值不适合过大。
- 修改
启示:
- 对于第三方工具,了解其可调参数 和 默认数值是必要的
- 第三方工具默认参数不一定是最优的,要根据自己应用的情况去调整
- 增加服务部署机器时,需要注意对集群增大的负载压力,寻找扩大集群最大连接数量 和 查询性能直接的平衡点
- 合理设置应用程序连接池大小及闲置抛弃等参数
五、附录
1.资料
Apache Impala:https://impala.apache.org/docs/build/html/topics/impala_client.html
C3P0文档:https://www.mchange.com/projects/c3p0-versions/c3p0-0.9.5.2/#maxConnectionAge