简介: 针对数据库连接池到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. 17_详解YUV

    本文的主角是多媒体领域非常重要的一个概念:YUV. 简介 YUV,是一种颜色编码方法,跟RGB是同一个级别的概念,广泛应用于多媒体领域中. 也就是说,图像中每1个像素的颜色信息,除了可以用RGB的方式 ...

  2. drf(视图组件)

    一. 前言 Django REST framwork 提供的视图的主要作用 1. 控制序列化器的执行(检验.保存.转换数据) 2. 控制数据库查询的执行 二. 两个视图基类 两个视图基类: APIVi ...

  3. re_signin 【ctfshow_元旦水友赛】Reserve

    题目: IDA反编译 主函数 1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 char s2[144] ...

  4. KingbaseES 数据库逻辑优化规则

    SQL 优化的过程可以分为逻辑优化和物理优化两个部分.逻辑优化主要是基于规则的优化,简称 RBO(Rule-Based Optimization).物理优化会为逻辑查询计划中的算子选择某个具体的实现, ...

  5. 06 PSP成熟度模型【软件过程与管理】

    PSP成熟度模型(Personal Software Process) 个体度量过程 PSP3 周期开发 个体计划过程 PSP2 代码评审 设计评审 PSP2.1 设计模板 个体质量管理过程 PSP1 ...

  6. 关于Guava ForwardingMap

    ForwardingMap是什么? ForwardingMap 是一个装饰器 负责把所有的map操作转发到所代理的map. 操作转发是直接的,不经任何中间操作的. 对方法的覆写要慎重,比如关联的put ...

  7. 05 Ajax请求(扩展,延伸)

    05 Ajax请求(扩展,延伸) 首先, 我们用Flask创建一个后台服务器(自己做网站了哈) 目录结构: 服务端: from flask import Flask, render_template, ...

  8. OpenHarmony 官网文档有哪些上新?下篇:设备开发文档上新

    为了方便社区开发者更易获取 OpenAtom OpenHarmony(以下简称"OpenHarmony")相关文档,暨上篇应用开发文档上新内容,SIG Docs  小组同步准备了设 ...

  9. 分析即服务(AaaS)是什么?终于有人讲清楚了

    随着世界数据领域的地位和规模的不断扩大,大数据.人工智能和云计算正在结合起来,以分析即服务的形式为企业提供急需的喘息机会 . 让我们简要回顾一下 2010 年以来发生的事情. 这十年来我们见证了许多技 ...

  10. 【VMware vCenter】使用Reduced Downtime Update (RDU)升级更新vCenter Server。

    Reduced Downtime Upgrade (RDU) 减少停机时间更新是用于vCenter Server更新升级的一种新的方式,顾名思义,主要目的就是为了减少在vCenter Server更新 ...