美文网首页
数据库连接池研究实战(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