简介: 针对数据库连接池到DRDS连接探活的优化

1. 问题背景

近期在给某专有云客户进⾏云产品应⽤性能优化分析时,发现了⼀个有趣的关于DRDS使⽤层⾯的问题,这⾥给⼤家分享⼀下。
使⽤过DRDS产品的同学都知道在DRDS中,未分库分表的数据表会存储在“0号库”上,对于这些表操作的SQL会被分发到“0号库”上执⾏。所以⼀般情况下,0号库所在实例的压⼒会⽐其它实例的压⼒稍⼤⼀些。近期分析该客户的数据库性能时,发现客户使⽤的DRDS下0号库所在的RDS实例的压⼒明显⽐其它RDS实例⾼出许多。

图1:SQL语句平均每秒执行次数及事务数

2. 原因分析

通过查看0号库所在的RDS实例的执⾏SQL发现,有⼤量的 SELECT 'x' 的查询语句。检查应⽤侧代码后发现,这个查询语句是应⽤侧连接池配置的连接探活SQL,所有的连接池实现⼏乎都有这个功能,可以通过探活SQL检测连接当前是否可⽤。
那么问题来了:

  1. 为什么只有0号库所在RDS上会有⼤量此类的语句?
    DRDS中不带表名的(⽐如 SELECT 'x')SQL和show命令都会被下发到0号库执⾏。
  2. 对于客户端来说这种连接检测是否有⽤?

答案⼀定是有⽤的,因为如果因⽹络闪断或其它原因导致的连接状态不可⽤,即使获取到了连接对象,也不能进⾏数据访问操作。所以这个检测是有必要的,但对于使⽤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%左右。

图6:SQL语句平均每秒执行次数及事务数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 打开,会对系统性能有⼀定的影响,因为每次都会在获取连接时多执⾏⼀次查询来检测连接是否可⽤。因此推荐使⽤如下的配置:

  • testWhileIdle=true【如果获得的连接为“空闲连接”,则会进⾏探活检测,如果检测失败,会将此连接从连接池移除,尝试重新从连接池获取连接】
  • timeBetweenEvictionRunsMillis=60000【Destroy线程每隔1分钟对连接池内部的空闲时间>= minEvictableIdleTimeMillis的连接进⾏探活检测,如果检测失败,会将连接从连接池移除】
  • minEvictableIdleTimeMillis=60000【如果连接闲置1分钟,则认为此连接为“空闲连接“】

这样设置完成后,只有在获取到“空闲连接”时,才会进⾏探活检测,⼤⼤降低了业务⾼峰时段的探活频率。同时,也可通过适当缩短minEvictableIdleTimeMillis 的值,兼顾由于⽹络闪断或其它原因导致的连接不可⽤的情况,减少业务出错的概率,在系统性能和可⽤性之间找到⼀个平衡点。

作者:刘维

原文链接

本文为阿里云原创内容,未经允许不得转载

针对数据库连接池到DRDS连接探活的优化的更多相关文章

  1. 01_数据库连接池,数据源,ResultSetMetaData,jdbc优化

     一.数据库连接池 1. 什么是连接池 传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接. 这样的方式会导致用户每 ...

  2. C#中SQL Server数据库连接池使用及连接字符串部分关键字使用说明

    (1) 数据库的连接使用后,必须采用close()连接等效的方法关闭连接.只有关闭后,连接才能进入连接池. 参见微软的使用连接池说明:https://msdn.microsoft.com/zh-cn/ ...

  3. spring+mybatis+c3p0数据库连接池或druid连接池使用配置整理

    在系统性能优化的时候,或者说在进行代码开发的时候,多数人应该都知道一个很基本的原则,那就是保证功能正常良好的情况下,要尽量减少对数据库的操作. 据我所知,原因大概有这样两个: 一个是,一般情况下系统服 ...

  4. 配置数据库连接池,Tomcat6.0 连接池的配置

    Tomcat6.0 连接池的配置1.本人当前使用的Tomcat版本为:6.0.20,oracle为稳定的9i版本 2.下文为方便起见,依习惯以%Tomcat_Home%表示Tomcat安装的目录,本人 ...

  5. [原创]java WEB学习笔记80:Hibernate学习之路--- hibernate配置文件:JDBC 连接属性,C3P0 数据库连接池属性等

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. Druid数据库连接池获取连接阻塞(转载)

    一. 背景        17年公司有个项目组在南京做项目的时候,开发框架用的是spring boot ,数据库连接池用的是druid,但老是遇到socket read timeout的错误,不得已放 ...

  7. java学习笔记41(数据库连接池 C3p0连接池)

    在之前的学习中,我们发现,我们需要频繁的创建连接对象,用完之后还需要在关闭资源,因为这些连接对象都是占资源的,但是又不得不创建,比较繁琐,为了解决这种情况,Java出现了数据库连接池: 数据库连接池的 ...

  8. java web学习总结(十六) -------------------数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  9. JAVA基础知识之JDBC——JDBC数据库连接池

    JDBC数据库连接池 数据库的连接和关闭是很耗费资源的操作,前面介绍的DriverManager方式获取的数据库连接,一个Connection对象就对应了一个物理数据库连接,每次操作都要打开一个连接, ...

  10. javaweb学习总结(三十九)——数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

随机推荐

  1. 踩坑经历-jenkins安装使用

    最近在整理之前临时记的笔记,好久之前了,大概记录下. 按照教程安装jenkins,随机选了个不是最新版的docker版本,然后一路下一步,但是到安装推荐插件就没有全部安装成功,我接着走下去想进到&qu ...

  2. 记录--CSS 滚动驱动动画 scroll()

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 CSS 滚动驱动动画 scroll() animation-timeline 通过 scroll() 指定可滚动元素与滚动轴来为容器动画提 ...

  3. 从静态到动态化,Python数据可视化中的Matplotlib和Seaborn

    本文分享自华为云社区<Python数据可视化大揭秘:Matplotlib和Seaborn高效应用指南>,作者: 柠檬味拥抱. 安装Matplotlib和Seaborn 首先,确保你已经安装 ...

  4. js前端 md5加密

    1.在utils目录下新建md5.js 在这里,我把md5()这个方法使用export进行了导出,方便在其他地方使用es6 import 引入使用 /* * JavaScript MD5 1.0.1 ...

  5. 软件发布版本号命名风格(GUN)

    GUN风格: (1)产品初版时,版本号可以为0.1或0.1.0,也可以为1.0或1.0.0: (2)当产品进行了局部修改或bug修正时,主版本号和子版本号都不变,修正版本号+1: (3)当产品在原有的 ...

  6. 【放假第1天】采购季倒计时 2G 50/年,4G 618/3年 云服务器选购攻略 阿里云 腾讯云 京东云对比 搭建网站、数据分析

    ​ 更新日期:4月4日(阿里云价格回调,京东云采购季持续进行) <最新对比表>已更新在文章头部-腾讯云文档,文章具有时效性,请以腾讯文档为准! https://docs.qq.com/do ...

  7. #区间dp#CF1114D Flood Fill

    题目 有一个长度为\(n\)的颜色序列,在游戏前选择一个固定的位置, 若当前轮该位置的颜色为\(x\),那么可以将所有颜色为\(x\)的连通块改为任意颜色, 问最少进行多少轮使得区间\([1,n]\) ...

  8. Noah-MP陆面过程模型建模

    [原文链接]:Noah-MP陆面过程模型建模方法与站点.区域模拟实践技术 [方式]:直播+永久回放+长期答疑群辅助+全套资料 [目标]:了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作 ...

  9. MogDB/openGauss 自定义snmptrapd告警信息

    MogDB/openGauss 自定义 snmptrapd 告警信息 在实际使用中,默认的报警规则信息并不能很好的满足 snmp 服务端的需求,需要定制化报警信息,这里以添加 ip 为例,看似一个简单 ...

  10. HarmonyOS语言基础类库开发指南上线啦!

      语言基础类库提供哪些功能?多线程并发如何实现?TaskPool(任务池)和Worker在实现和使用场景上有何不同? 针对开发者关注的并发等语言基础类库的相关能力,我们在新推出的语言基础类库开发指南 ...