现在流行的网站开发中关村在线
news/
2025/9/30 19:57:39/
文章来源:
现在流行的网站开发,中关村在线,seo的基本步骤,加强廉政教育网站建设简介#xff1a; 针对数据库连接池到DRDS连接探活的优化 1. 问题背景
近期在给某专有云客户进⾏云产品应⽤性能优化分析时#xff0c;发现了⼀个有趣的关于DRDS使⽤层⾯的问题#xff0c;这⾥给⼤家分享⼀下。 使⽤过DRDS产品的同学都知道在DRDS中#xff0c;未分库分表的… 简介 针对数据库连接池到DRDS连接探活的优化 1. 问题背景
近期在给某专有云客户进⾏云产品应⽤性能优化分析时发现了⼀个有趣的关于DRDS使⽤层⾯的问题这⾥给⼤家分享⼀下。 使⽤过DRDS产品的同学都知道在DRDS中未分库分表的数据表会存储在“0号库”上对于这些表操作的SQL会被分发到“0号库”上执⾏。所以⼀般情况下0号库所在实例的压⼒会⽐其它实例的压⼒稍⼤⼀些。近期分析该客户的数据库性能时发现客户使⽤的DRDS下0号库所在的RDS实例的压⼒明显⽐其它RDS实例⾼出许多。 图1SQL语句平均每秒执行次数及事务数
2. 原因分析
通过查看0号库所在的RDS实例的执⾏SQL发现有⼤量的 SELECT x 的查询语句。检查应⽤侧代码后发现这个查询语句是应⽤侧连接池配置的连接探活SQL所有的连接池实现⼏乎都有这个功能可以通过探活SQL检测连接当前是否可⽤。 那么问题来了 为什么只有0号库所在RDS上会有⼤量此类的语句 DRDS中不带表名的⽐如 SELECT xSQL和show命令都会被下发到0号库执⾏。 对于客户端来说这种连接检测是否有⽤
答案⼀定是有⽤的因为如果因⽹络闪断或其它原因导致的连接状态不可⽤即使获取到了连接对象也不能进⾏数据访问操作。所以这个检测是有必要的但对于使⽤DRDS作为数据源的场景来说⽬前配置的检测⽅式是存在问题的。 对于传统的数据库使⽤⽅式客户端是直接连接到底层数据库的如下图。探活SQL是直接发到连接的数据库执⾏这种场景下使⽤ SELECT x 检测客户端到数据库的连接是没有问题的。 图2客户端连接到数据库
⽽对于使⽤DRDS作为数据源的场景来说探活语句在发送到DRDS服务后会被转发到0号库执⾏这就意味着这个探活SQL实际上检测的是客户端--DRDS--0号库的链路是否正常。 图3客户端通过DRDS连接到数据库
这⼀点可以从DRDS上看 SELECT x 的执⾏计划得到证实如下 图4执⾏结果1
实际上这样的数据源连接检测是没有意义的。因为 第⼀数据源后端实际上只检测了DRDS到0号库的连接状态DRDS到其它分库的连接状态并未检测。但真正执⾏SQL时DRDS是有可能将解析后的SQL下发到其它分库上执⾏的。 第⼆客户端探活SQL的作⽤主要是为了保证客户端连接池与数据源之间的连接是可⽤的。对于数据源背后的情况应该由数据源本身维护即由DRDS本身到RDS的连接池保障连接可⽤性⽽不应该通过客户端的探活功能来保证。
3. 解决方法
明⽩以上内容后我们解决问题的⽅案就⽐较清楚了实际上我们只需要让客户端连接池检测客户端到DRDS的连接状态即可。那有没有这样的检测⽅法呢 答案当然是有的经过与DRDS研发同学确认将探活SQL修改为 SELECT x FROM dual 即可。 修改后再次在DRDS查看执⾏计划如下 图5执⾏结果2
在应⽤侧修改连接池的探活SQL配置后从0号库所在实例上看已经看不到探活SQL的执⾏记录⽽且从修改前和修改后0号库所在实例的压⼒来看效果也⽐较明显0号库的压⼒相⽐之前下降了⼤概80%左右。 图6SQL语句平均每秒执行次数及事务数2
4. 连接池参数配置
⾄此0号库压⼒过⾼的问题解决了下⾯我们聊聊为什么会有⼤量的探活语句出现。 探活机制实际上是数据源连接池通⽤的⼀种检测机制可以检测连接池内的连接对象是否真的可⽤。拿Druid连接池举例探活SQL是通过数据源的 validationQuery 属性配置的。与之相关的配置属性还有testOnBorrow、testWhileIdle、testOnReturn、timeBetweenEvictionRunsMillis、 minEvictableIdleTimeMillis。官⽅解释如下 testOnBorrow申请连接时执⾏ validationQuery 配置的探活语句检测连接是否有效。 testWhileIdle申请连接的时候检测如果空闲时间⼤于timeBetweenEvictionRunsMillis 执⾏ validationQuery 检测连接是否有效。 testOnReturn归还连接时执⾏ validationQuery 检测连接是否有效。 timeBetweenEvictionRunsMillis有两个含义 1)Destroy线程检测连接的间隔时间如果连接空闲时间⼤于等于 minEvictableIdleTimeMillis 则关闭物理连接。 2)testWhileIdle 的判断依据详细看 testWhileIdle 属性的说明。 minEvictableIdleTimeMillis连接保持空闲⽽不被驱逐的最⼩时间。
⽂章前⾯描述的出现⼤量探活SQL的情况是因为应⽤将连接池的testOnBorrow设置成了true所以在每次应⽤获取连接时都会执⾏ validationQuery 配置的探活语句检测连接是否有效。虽然通过前⾯的优化步骤已经降低了0号库的压⼒使探活语句不下发到0号库执⾏。但探活语句仍会在DRDS实例上执⾏DRDS实例的压⼒并未减轻。通过上⾯对Druid数据源属性配置的说明可以了解到如果将 testOnBorrow 或 testOnReturn 打开会对系统性能有⼀定的影响因为每次都会在获取连接时多执⾏⼀次查询来检测连接是否可⽤。因此推荐使⽤如下的配置 testWhileIdletrue【如果获得的连接为“空闲连接”则会进⾏探活检测如果检测失败会将此连接从连接池移除尝试重新从连接池获取连接】 timeBetweenEvictionRunsMillis60000【Destroy线程每隔1分钟对连接池内部的空闲时间 minEvictableIdleTimeMillis的连接进⾏探活检测如果检测失败会将连接从连接池移除】 minEvictableIdleTimeMillis60000【如果连接闲置1分钟则认为此连接为“空闲连接“】
这样设置完成后只有在获取到“空闲连接”时才会进⾏探活检测⼤⼤降低了业务⾼峰时段的探活频率。同时也可通过适当缩短minEvictableIdleTimeMillis 的值兼顾由于⽹络闪断或其它原因导致的连接不可⽤的情况减少业务出错的概率在系统性能和可⽤性之间找到⼀个平衡点。
作者刘维
原文链接
本文为阿里云原创内容未经允许不得转载
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923214.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!