文章内容

2019/10/27 16:10:50,作 者: 黄兵

在Python中使用Mysql数据库连接池

最近大量数据库操作,运行程序一段时间之后,数据库连接会断开,具体问题描述可参考这篇文章:MySQL大量操作断开连接

具体解决方案可以参考这篇文章:关于大并发mysql连接引起数据库错误OperationalError: (2003, "Can't connect to MySQL server on 'x.x.x.x (99)")分析

python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接mysql数据库请求时,都是独立的去请求访问,相当浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此,实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用的目的。

这样就可以避免导致端口耗尽,与数据库服务器断开连接。

具体实现代码在这片文章中已经很详细了,在此不多说。

文章地址:Python实现Mysql数据库连接池

下面是一些查询的示例:

def query_duplicate_ip(self, ip):
    """
    查询重复IP,避免浪费IP-API次数
    :param ip:
    :return 如果存在记录,返回结果,如果没有记录返回False:
    """

    # 申请资源
    mysql = Mysql()
    sql = "SELECT * FROM ip_query_result WHERE ip = '{query_ip}';".format(query_ip=ip)
    try:
        query_ip_result = mysql.get_one(sql)
        # 查询完成之后释放连接
        mysql.dispose()
    except (MySQLdb.Error, MySQLdb.Warning) as e:
        self._logger_ip_filter.error(
            ' 执行query_duplicate_ip函数的时候出现错误,具体错误内容: {error_message}'.format(error_message=e))
        return False

    if query_ip_result:
        return query_ip_result
    else:
        return False

上面是获取单条记录的使用方式。

    def clean_counters(self):
        """保存访客原始数据,用于后面深度学习"""
        start = time.time()
        # 间隔1分钟
        end = start - (1 * 60)
        get_visit_time_line = self._redis_conn.lrange('visit_time_line', 0, -1)
        for item in get_visit_time_line:
            if float(item) > end:
                continue
            else:
                get_ip = self._redis_conn.hget("time:" + item, "ip")
                get_url = self._redis_conn.hget("time:" + item, "url")
                get_user_agent = self._redis_conn.hget("time:" + item, "user_agent")
                mysql = Mysql()
                sql = "INSERT INTO visit_time_line_original(time, ip, url,user_agent) VALUES (%s, %s, %s, %s)"
                try:
                    mysql.insert_one(sql, (item, get_ip, get_url, get_user_agent))
                    mysql.dispose()                   
                except (MySQLdb.Error, MySQLdb.Warning) as e:
                    self._logger_save_data.error('保存Redis到数据库的时候出现错误,具体错误内容: {error_message} '.format(error_message=e))           

上面是插入单条记录的调用方式,mysql.insert_one(sql, (item, get_ip, get_url, get_user_agent)) 这里是插入具体的值。


连接池对性能的提升表现在:

1.在程序创建连接的时候,可以从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度

2.关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁地打开和关闭连接


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 -  在Python中使用Mysql数据库连接池

分享到:

发表评论

评论列表