美文网首页
数据库连接池研究实战(python版)

数据库连接池研究实战(python版)

作者: hugoren | 来源:发表于2018-11-01 15:44 被阅读0次

为什么使用连接池

减少socket的三次减少,减少数据库连接开销.....

开源or 自已撸一个

常见的开源
https://github.com/hugoren/sqlalchemy 的自带pool 或queuePool
https://github.com/hugoren/TorMySQL
还有一个很早就不维护,这里就不说了

自已撸一个,好处多多,可以深入各种知识点,出了问题,也比较好hlod住,但也是bug多多,可能是特适合你目前的业务场景用,因为只经过你一个人使用,需要特多业务场景和时间检验。

开源的源码分析

从源码来看,它们都具有相同的点,都是采用pymysql, 再自已实现一个连接池


image.png
tomysql的连接池

https://github.com/hugoren/TorMySQL/blob/master/tormysql/pool.py
采用deque做pool的存储队列

image.png
sqlalchemy的连接池

https://github.com/hugoren/sqlalchemy/blob/master/lib/sqlalchemy/pool.py

https://github.com/hugoren/sqlalchemy/blob/master/lib/sqlalchemy/util/queue.py

image.png

自已弄一个连接池

目的

做开发的都知道基于进程或线程的方式,cpu上下文是一个很重的开销, py 又是在GIL的方式下运行,想要一个很好的并发,就有人想出了协程异步方式
以下是以 greenlet做任务, tornado的ioloop做异步回调的撸一个线程池

原理

池,说白点就是一个存储的容器,可以是list,也可以queue,py高性能双端队列就是数collections的deque

扩展成其它数据库的连接池

只要继承pool,重写create_raw_conn就行了

完整的例子
https://github.com/hugoren/pool/blob/master/mysql_pool.py

class ConnectionPool(Pool):
    def __init__(self, max_size=32, keep_alive=7200, mysql_params={}):
        super(ConnectionPool, self).__init__(max_size=max_size, params=mysql_params)
        self._keep_alive = keep_alive

    def create_raw_conn(self):
        conn = Connection(**self._conn_params)
        if self._keep_alive:
            self._ioloop.add_timeout(time.time() + self._keep_alive, self._ping, conn)
        return conn

    @green
    def _ping(self):
        for conn in self._pool:
            conn.ping()
            self.release(conn)
        self._ioloop.add_timeout(time.time() + self._keep_alive, self._ping, conn)

参考
https://github.com/zhu327/greentor/blob/maaster/greentor/mysql.py

相关文章

网友评论

      本文标题:数据库连接池研究实战(python版)

      本文链接:https://www.haomeiwen.com/subject/qjlxxqtx.html