zoukankan      html  css  js  c++  java
  • eventlet dbpool for postgresql &mysql

    并发编程利器Eventlet

     Eventlet是由第二人生(Secondlife)开源的高度伸缩性的Python网络编程库.


    根据官方介绍大致特性如下:
    • 非阻塞I/O模型
    • 协程(Coroutines)使得开发者可以采用阻塞式的开发风格,却能够实现非阻塞I/O的效果
    • 隐式事件调度,使得可以在Python解释器或者应用程序的某一部分去使用Eventlet


    关于协程,大致可以理解成允许子程序可以多次暂停和恢复执行,是实现多任务的一种有效手段,具体见这里


    在Python的世界里,实现了nonblocking I/O的产品并不算少.比如内置的Asyncore和著名的Twisted.相比之下,Eventlet是更容易上手和使用的。


    举个例子

    import eventlet
    pool = eventlet.GreenPool()
    while True:    pool.spawn(func,args)

    上面这段代码,几乎就是使用eventlet的范式:
    • GreenPool 用来实现协程,保证并行;
    • Spawn     用来调用相应的函数,完成具体业务.
    每个func之间切换,实施“你运行一会、我运行一会”,并且在进行切换时必须指定何时切换以及切换到哪,当出现阻塞时,就显式切换到另一 段没有被阻塞的代码段执行,直到原先的阻塞状况消失以后,再人工切换回原来的代码段继续处理.


    Eventlet内置提供了一个基于上述原理实现的数据库连接池,目前仅支持MySQL和PostgreSQL.为了测试其性能如何,我参考了gashero的这篇文章,并简化了测试方案.


    测试对象分别是MySQLdb(MySQL驱动的Python封装),Eventlet.db_pool,DBUtils


    测试代码如下:
    import time
    import random
    import MySQLdb
    import eventlet.db_pool as db_pool
    from DBUtils.PooledDB import PooledDB

    conn_kwargs={'host':'192.168.8.84','user':'root','passwd':'','db':'logs'}
    sql="""SELECT * FROM test WHERE id=%d"""
    pooled=db_pool.ConnectionPool(MySQLdb,**conn_kwargs)
    pooldb=PooledDB(MySQLdb,**conn_kwargs)

    def query(conn):
        cur=conn.cursor()
        cur.execute(sql%(random.randint(1,1000)))
        data=cur.fetchall()
        return cur

    def print_now():
        print time.strftime("%H:%M:%S")
        return

    def test1(times):
        print_now()
        for i in range(0,times):
            conn=MySQLdb.connect(**conn_kwargs)
            r = query(conn)
            r.close()
            conn.close()
        print_now()
        return

    def test2(times):
        print_now()
        for i in range(0,times):
            conn=pooled.get()
            try:
                query(conn)
            finally:
                pooled.put(conn)
        print_now()
        return

    def test3(times):
        print_now()
        for i in range(0,times):
            conn=pooldb.connection()
            r=query(conn)
            r.close()
            conn.close()
        print_now()
        return


    然后进入Python解释器交互环境
    Python -i db-pool-test.py
    >>> test1(10000) //MySQLdb
    16:04:34
    16:11:25
    >>> test2(10000) //Event
    16:12:35
    16:15:22
    >>> test3(10000) //DBUtils
    16:15:28
    16:18:09

    总体来看,和传统的MySQLdb相比,性能有了很大的提升,和DBUtils差别并不是很明显.


    协程凶猛啊!

    2 comments:

    s7v7nislands said...

    不知道你的mysql服务器有没有开query cache,如果开了感觉这样的结果不是很科学。你有没有考虑过select语句的结果被服务器cache的,所以后面运行时cache命中率较高。

    Guang Feng said...

    嗯嗯,说的很对,不过我测试的时候 关掉了cache

    Post a Comment

  • 相关阅读:
    三.Python数据类型详述
    二.Python基础语法和数据类型
    一.Python特点
    Hive之explode和lateral view
    javascript之函数作用域
    javascript之函数使用
    javascript之函数定义
    javascript之变量
    Html之元素
    Html之页面
  • 原文地址:https://www.cnblogs.com/lexus/p/1844632.html
Copyright © 2011-2022 走看看