V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
aizya
V2EX  ›  Java

Java 操作 MySQL 的时候,为什么瞬间会产生大量的 sleep 的连接。

  •  
  •   aizya · 314 天前 · 3124 次点击
    这是一个创建于 314 天前的主题,其中的信息可能已经有所发展或是发生改变。

    持久化用的 Hibernate,连接池用的 Hikari,连接池大小设置为 800 。场景是使用 csv 批量导入上万条记录,每条记录不是简单的保存到数据库,可能会涉及到多次数据库查询或者更新操作。

    在这种前提之下,当我将这些动作都放到一个事务中去处理的时候,后台会报如下的错误:

    Caused by: java.sql.SQLTransientConnectionException: HikariPool-3 - Connection is not available, request timed out after 20001ms.
    21:37:18,591 ERROR [stderr] (default task-3) 	at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:695)
    21:37:18,591 ERROR [stderr] (default task-3) 	at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197)
    21:37:18,591 ERROR [stderr] (default task-3) 	at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162)
    21:37:18,591 ERROR [stderr] (default task-3) 	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
    21:37:18,592 ERROR [stderr] (default task-3) 	at org.hibernate.hikaricp.internal.HikariCPConnectionProvider.getConnection(HikariCPConnectionProvider.java:77)
    21:37:18,592 ERROR [stderr] (default task-3) 	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getConnection(AbstractMultiTenantConnectionProvider.java:36)
    
    

    使用 show processlist 观察 mysql 连接的时候,某个瞬间会产生大量的 sleep 连接。

    现在我的疑问是,sleep 连接是怎么才会产生的? 如果我仅仅只是在循环中执行一万次数据库查询操作,MySQL 连接没有什么波动,而当我在使用事务执行某个耗时任务时(这个任务中会执行查询数据库的操作),就会产生大量的 sleep 连接?

    谁能帮忙解释一下?

    20 条回复    2021-01-22 13:20:50 +08:00
    gjkv86
        1
    gjkv86  
       314 天前 via iPhone
    800 个连接太多了 什么数据库禁得起这么造啊
    kosmosr
        2
    kosmosr  
       314 天前 via Android
    连接池原理,预申请,避免频繁新建销毁连接;而且连接池大小不是越大越好
    CEBBCAT
        3
    CEBBCAT  
       314 天前 via Android
    @gjkv86 800 个很多吗?刚入行的小菜鸡,前两天看到同事在讨论,我们有的 MySQL 实例链接数上限就是 800
    ElmerZhang
        4
    ElmerZhang  
       314 天前
    @CEBBCAT 一般 SQL 优化的比较好的,连接池设置 10 个就够用了。
    我经手过的某系统,单机峰值 QPS 1500,也只使用了不到 10 个连接。
    neoblackcap
        5
    neoblackcap  
       314 天前
    如果是在循环中跑事务,那么显然会出现大量 sleep 。毕竟一个连接只能同时处理一个事务啊。你如果快速地提交,显然连接池的连接不够用,那么就会触发大量连接。
    你要不将事务的作用域扩大一些?比如分批次导入,一次用一个事务导入 100 条这样?
    zoharSoul
        6
    zoharSoul  
       314 天前
    Hikari 建议的连接池大小是 10 还是 15 来着
    xcstream
        7
    xcstream  
       314 天前
    连接池大小设置为 800 噗
    k9982874
        8
    k9982874  
       314 天前 via iPhone
    楼主: 连接池 800,启动!
    mysql: ???我死给你看!
    iceneet
        9
    iceneet  
       314 天前
    ???连接池 800 数据库没挂很厉害了!
    yanzhiling2001
        10
    yanzhiling2001  
       313 天前
    楼上描述的很准确了,连接池 10-15 就够用的,800mysql 没挂都是他性能好
    cloudhuang
        11
    cloudhuang  
       313 天前
    设置线程池,其实一般来说,就设置成 2N | 2N + 1 就可以了,数据库连接池也一样
    jorneyr
        12
    jorneyr  
       313 天前
    看看数据库允许的最大并发连接数是多少。

    此外,800 虽然多,但也不算多,我们数据库连接一般会允许最大 2000 。
    supuwoerc
        13
    supuwoerc  
       313 天前
    @CEBBCAT 震惊
    mmdsun
        14
    mmdsun  
       313 天前 via Android
    MySQL 连接数
    和 Java 数据库连接池不是一个概念吧。


    你把链接池改小一下,存活周期改小。

    另外 hibernate jpa 这类批量导数据需要关闭
    spring.jpa.open-in-view false

    不然 session 保存时间太长一直不结束。
    passerbytiny
        15
    passerbytiny  
       313 天前 via Android
    上万条记录……每条记录……可能会涉及到多次……查询或者更新……将这些动作都放到一个事务……

    你该不会是在循环外面套事务吧,那样的事务太大,压根处理不了。
    WuwuGin
        16
    WuwuGin  
       313 天前
    Connection is not available, request timed out after 20001ms.
    我怀疑是 mysql 挂了,或者某个表挂了,看看是不是会有死锁产生?
    aizya
        17
    aizya  
    OP
       313 天前
    @WuwuGin 谢谢,查了没有死锁。 应该是我在处理的时候,把耗时的逻辑放在事务里面去处理了。 但是又不知道该怎么把里面的逻辑拆分出来。
    keepeye
        18
    keepeye  
       313 天前
    800 有点多,但纯连接应该没事吧,又没跑 sql
    ytll21
        19
    ytll21  
       313 天前
    你们的数据库就给你这一个系统用吗?你这一个系统就用掉了 800 个。。。还给不给其它系统用呀。。。
    CODEWEA
        20
    CODEWEA  
       313 天前
    800 个客户端 你们那个机器行吗?
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2055 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 00:34 · PVG 08:34 · LAX 16:34 · JFK 19:34
    ♥ Do have faith in what you're doing.