python MySQL 链接池 DBUtils

看了很多关于python连接池的文章,文章都写的很好,但唯一的遗憾是没有针对第一次接触链接池的朋友进行介绍的。最近有几个小朋友问我python链接池到底咋用,趁此记录下对链接池的入门理解;

 

链接池,首先他的作用是开一个连接通道,他的使用场景不仅仅是数据库。什么是通道?举个例子,python pymsql连接数据库执行一次查询,第一步程序需要连接数据库,第二步保持这个通道不断开并发送sql,第三步数据库执行后通过这个连接返回结果;

所以,通道也可以看作是一个连接,这点最明显的可以从MySQL show full processlist看出,MySQL show processlist展示的数据是当前数据库所有的连接和该连接的动作,有的是sleep状态,有的是在select等,他们的行数就是数据库此时的链接数,也就相当于数据库开了这么多个对外通道。

既然连接,那么必然有断开的时候,所以当一个窗口sql执行完了,那么新开的窗口在show processlist可能看不到之前的那个sql线程,因为那个线程执行完后连接断开了;

这样的发起连接 关闭连接,对于我们小数量级别几乎没有感知,但是首先要明白,每次新开一个连接数据库,都需要消耗性能,在针对高并发大流量的访问下,比如我们公司年底高峰期,qps达到3000,如果3000个同时重新开启连接那么对性能的消耗就比较大了,为了避免每次都要重新开启连接这种消耗的动作,出现了连接池;

 

链接池的主要作用是,保留一定链接数不和数据库断开,当应用需要访问数据库时,直接通过连接池拿取一个连通的连接,那么就避免了应用新开连接的消耗;

所以这个技术,不仅仅是给数据库用的,针对于此类原理的中间件也有链接池技术;但我们平时用得比较多的还是在数据库上;

所以,针对以上的话,上代码看比较好一点理解:

我新建了一个songsdb库和添加了一张空表;先查看当前连接状态:

 通过python 查询空表后,查看数据库连接池状态:

代码:

import pymysql
from DBUtils.PooledDB import PooledDB,SharedDBConnection

import time

# while True:
pool = PooledDB(
    creator=pymysql,
    maxconnections=300,
    mincached=10,
    maxcached=5,
    maxshared=5,
    blocking=True,
    maxusage=None,
    ping=0,
    host='localhost',
    port=3306,
    database='songsdb',
    user='root',
    password='123456',
    charset='utf8'
)


def func():

    conn = pool.connection()
    cur = conn.cursor()
    cur.execute('select * from t_os_songs_path')
    re = cur.fetchall()
    # time.sleep(100)
    # conn.close()

    print(re)

func()

执行成功,由于是空表,所以返回空:

查看执行后连接状态:

 

 

发现连接数和执行前的连接数一致?猜测原因是因为线程执行完后关闭了连接,并验证;验证方式,查询程序中加上sleep延时,让程序短时间不关闭,验证查询后连接是否会存在;操作,把上面代码的sleep注释取消,延长程序执行时间,并查看数据库连接;
 

 

分析结果我们可以得到以下几个结论:

1、连接不手动关闭的情况下,执行完sql,数据库是不会关闭连接的,连接需要服务端发起关闭

2、服务端不显示的指定close,但是线程执行完后,服务线程被回收,数据库连接也会被关闭

3、显示的close会关闭连接

 那么映射出来,我们能得到信息还有,如果线程不会死掉,有没有显示的关闭连接,那么连接就会一致存在,当链接数超过数据库限制的时候,无法创建新的连接程序会报错,这对程序的严谨性有一定的要求;

那么正题到了,pothon连接池怎么用?

python3的链接池可用的模块有:DBUtils

他有两种模式:

模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程再次使用。当线程终止时,连接自动关闭。
模式二:创建一批连接到连接池,供所有线程共享使用。

模式以对多线程有要求,我比较常用第二个,启用链接池写法如下:

import pymysql
from DBUtils.PooledDB import PooledDB,SharedDBConnection

pool = PooledDB(
    creator=pymysql,pymysql连接数据库模块
    maxconnections=300, 最大连接数
    mincached=10, 最小缓存的空闲链接数
    maxcached=15, 最大缓存的空闲链接数
    maxshared=0,链接池中最多共享的链接数量,0和None表示全部共享
    blocking=True,连接池中如果没有可用连接后,是否阻塞等待
    maxusage=None,连接可被重复使用数,None不限制
    ping=0,检查数据库能否连接
    host='localhost',
    port=3306,
    database='songsdb',
    user='root',
    password='123456',
    charset='utf8'
)

以上就可以启动一个数据库连接池了,但是,我们只要程序线程执行完会自动close连接,为了保持连接的存在,我们需要让连接池线程不结束,所以写个while true:执行如下脚本,查看数据库:

import pymysql
from DBUtils.PooledDB import PooledDB,SharedDBConnection

while True:
    pool = PooledDB(
        creator=pymysql,
        maxconnections=300,
        mincached=10,
        maxcached=15,
        maxshared=15,
        blocking=True,
        maxusage=None,
        ping=0,
        host='localhost',
        port=3306,
        database='songsdb',
        user='root',
        password='123456',
        charset='utf8'
    )

 

数据库开启了不会被关掉的连接,这时候我们程序就启动了一个活动的连接池,接下来其他服务只需要去连接词取连接即可,取的方法如下:

conn = pool.connection()
cur = conn.cursor()

 当然,可以把连接池封装到一个py文件中,其他的文件也可以调用

当然关闭这个连接:

conn.close()

注意这个close是连接词connection的conn的close,不是pymysql的close,这样我们使用完连接后,关闭连接链接池会自动回收提供个下一个服务使用;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值