博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python多线程程序中的MYSQL连接管理研究
阅读量:6278 次
发布时间:2019-06-22

本文共 2457 字,大约阅读时间需要 8 分钟。

项目地址:

研究背景

针对多用户/高并发访问MYSQL数据库这一场景,研究不同Python并发模式(单线程/多线程)和不同MYSQL连接模式(单连接/多连接/连接池)时的程序性能。

研究手段

脚本

  • 初始化MYSQL数据库

    • : 包括创建database,创建table,添加示例(example)等功能。脚本只需执行一次。如果必要,需要修改脚本中的数据库hostname, username和password。
  • 并发读取数据库内容

    • : 单线程,单连接
    • : 单线程,多连接
    • : 多线程,单连接
    • : 多线程,多连接
    • : 多线程,连接池

工具

  • : 一种动态分析工具,测量程序每一步的执行时间。
  • : 一种Linux内置命令,测量程序总的执行时间。
  • : 一种Linux第三方工具,测量程序在多次执行情况下的最大/平均/最小执行时间。

研究结果

单线程程序中,多连接的耗时显著高于单连接

例如,单线程场景下,连续读取1000次MYSQL数据库中的数据,测量单连接和多连接时各自的执行时间:

root@hzettv53:~/workspace/github/python-mysql-examples# time python stsc.pyreal    0m0.234sroot@hzettv53:~/workspace/github/python-mysql-examples# time python stmc.pyreal    0m1.378s复制代码

可以看到,采用单连接时,程序耗时0.234秒;采用多连接(即每次访问都新建一个连接)时,程序耗时1.378秒。后者是前者的近6倍。

进一步分析后可以发现,造成这一现象的原因在于:MYSQL连接的创建是一个时间开销较大的操作。例如,执行命令python -m cProfile -s cumtime stmc.py

ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.039    0.039    1.410    1.410 stmc.py:3(
) 1000 0.005 0.000 1.345 0.001 stmc.py:7(read_user_from_db) 1000 0.013 0.000 0.885 0.001 __init__.py:128(connect) 1000 0.007 0.000 0.871 0.001 connection.py:53(__init__) 1000 0.004 0.000 0.856 0.001 abstracts.py:711(connect)复制代码

可以看到,在多连接情况下,总执行时间1.410秒,其中建立连接这一步(init.py:128(connect))就花了0.885秒,占比接近63%。这说明,创建MYSQL连接是一个时间开销相对较大的步骤。多连接情况下,每次访问MYSQL数据库都会创建一个新的连接,从而大大增加总的执行时间。

MYSQL连接不是线程安全的

执行命令python mtsc.py,程序出现异常。

Exception in thread Thread-102:Traceback (most recent call last):  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner......    if buf[0] == 251:  # \xfbIndexError: bytearray index out of range复制代码

这种异常一般是由多个线程同时操作共享数据出现冲突导致的。当然,由于冲突的多样性,异常表现并不局限于上面这种。

为什么出现异常?因为MYSQL连接不是线程安全的。这意味着,在多线程程序中,MYSQL连接不能由多个线程共享。

多线程程序中,使用连接池比使用多连接更加高效

既然MYSQL不是线程安全的,那么在多线程程序中,我们有两种选择。

(1) 使用多连接,即每个线程使用一个自己创建的连接。

(2) 使用连接池(Connection Pool),即维护一组创建好的数据库连接,由每个线程在需要时从中获取(而不是创建)一个空闲的连接,并且在使用完毕之后放回(而不是关闭)连接。

那么,哪一种方法效率更高呢?

root@hzettv53:~/workspace/github/python-mysql-examples# time python mtmc.pyreal    0m2.347sroot@hzettv53:~/workspace/github/python-mysql-examples# time python mtcp.pyreal    0m1.434s复制代码

通过比较我们可以发现,在多连接情况下,程序执行时间为2.347秒,而在连接池情况下,程序执行时间只要1.434秒,节省了近40%。

这是因为,使用连接池的方式能够减少数据库连接的创建次数,提高数据库连接的使用效率,因而更加高效。

总结

这篇文章针对多用户/高并发访问MYSQL数据库这一场景,研究了不同Python并发模式(单线程/多线程)和不同MYSQL连接模式(单连接/多连接/连接池)时的程序执行效率。

从文中的实验结果可以发现,为了提高MYSQL数据库访问程序的性能:

  • 在能够共享连接的情况下,尽量使用共享连接
  • 在不能共享连接的情况下,使用连接池

更多内容可以访问Github:

转载于:https://juejin.im/post/5d0b17e1f265da1bb003c45f

你可能感兴趣的文章
[arm驱动]linux设备地址映射到用户空间
查看>>
弗洛伊德算法
查看>>
【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
查看>>
精度 Precision
查看>>
Android——4.2 - 3G移植之路之 APN (五)
查看>>
Linux_DHCP服务搭建
查看>>
[SilverLight]DataGrid实现批量输入(like Excel)(补充)
查看>>
秋式广告杀手:广告拦截原理与杀手组织
查看>>
翻译 | 摆脱浏览器限制的JavaScript
查看>>
闲扯下午引爆乌云社区“盗窃”乌云币事件
查看>>
02@在类的头文件中尽量少引入其他头文件
查看>>
JAVA IO BIO NIO AIO
查看>>
input checkbox 复选框大小修改
查看>>
网吧维护工具
查看>>
BOOT.INI文件参数
查看>>
vmstat详解
查看>>
新年第一镖
查看>>
unbtu使用笔记
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
Android程序开发初级教程(一) 开始 Hello Android
查看>>