为Python加快 – python+memcached
当前位置:以往代写 > Python教程 >为Python加快 – python+memcached
2019-06-14

为Python加快 – python+memcached

为Python加快 – python+memcached

原来我一直不知道怎么来更好地优化网页的机能,然后最近做python和php同类网页渲染速度较量时,意外地发明一个很简朴很呆子可是 我一直没发明的好要领(不得不BS我本身):直接像某些php应用好比Discuz论坛那样,在生成的网页中打印出“本页面生成时间几多几多秒”,然后在 不断地会见网页测试时,很直观地就能发明什么操纵会导致瓶颈,奈何来办理瓶颈了。

于是我发明SimpleCD在 生成首页时,意外地竟然需要0.2秒阁下,真真不能忍:比拟Discuz论坛首页平均生成才0.02秒,而Discuz论坛的首页页面无疑比 SimpleCD的主页要巨大不少;这让我情何故堪啊,因为这一定不是Python语言导致的差距,只能说是我完全没做优化而Discuz措施优化得很好 的效果。

其实不消阐明也能知道必定是数据库在拖累,SimpleCD在生成首页时需要在sqlite的三个数据库中举办42多次查询,是汗青原因导致的极其低效的一个设计;可是这40多次查询中,其实大部门长短常快的查询,仔细阐明一下就有两个是机能大户,其他都不慢。

第一个大户就是:获取数据个数

SELECT count(*) FROM verycd

这个操纵每次都要花不少时间,这是因为每次数据库都要锁住然后遍历一遍主键统计个数的缘故,数据量越大耗时就越大,耗时为O(N),N为数据库巨细;实际 上办理这个问题很是容易,只要随便在哪存一个当前数据的个数,只有在增删数据的时候窜改就行了,这样时间就是O(1)的了

第二个大户就是:获取最新更新的20个数据列表

SELECT verycdid,title,brief,updtime FROM verycd

    ORDER BY updtime DESC LIMIT 20;

因为在updtime上面做了索引,所以其实真正查询时间也就是搜索索引的时间罢了。然则为什么这个操纵会慢呢?因为我的数据是凭据publish time插入的,按update time举办显示的话就必定需要在至少20个差异的处所做I/O,这么一来就慢了。办理的要领就是让它在一个处所做I/O。也就是,除非数据库插手新数据 /改变原有数据,不然把这条语句的返回功效缓存起来。这么一来又快了20倍:)

接下来的是20条小case:取得宣布人和点击数信息

SELECT owner FROM LOCK WHERE id=XXXX;

SELECT hits FROM stat WHERE id=XXXX;

这里为什么没用sql的join语句来省点事呢?因为架构原因这些数据放在差异的数据库里,stat是点击率一类的数据库,因为需要频繁的插入所以用 mysql存储;而lock和verycd是需要大量select操纵的数据库,因为mysql悲剧的索引利用环境和分页效率而存放在了sqlite3数 据库,所以无法join -.-

总之这也不是问题,跟适才的办理要领一样,统统缓存

所以纵观我这个例子,优化网页机能可以一言以蔽之,缓存数据库查询,即可。我相信大部门网页应用都是这样:)

终于轮到memcached了,既然规划缓存,用文件做缓存的话照旧有磁盘I/O,不如直接缓存到内存内里,内存I/O可就快多了。于是memcached顾名思义就是这么个东东。

memcached是很强大的东西,因为它可以支持漫衍式的共享内存缓存,大站都用它,对小站点来说,只要出得起内存,这也是好对象;首页所需要的内存缓冲区巨细预计不会高出10K,更况且我此刻也是内存土豪了,还在乎这个?

设置运行:因为是单机没啥好配的,改改内存和端口就行了

vi /etc/memcached.conf

/etc/init.d/memcached restart

在python的网页应用中利用之

import memcache

mc = memcache.Client(['127.0.0.1:11211'], debug=0)

memcache其实就是一个map布局,最常利用的就是两个函数了:

  • 第一个就是set(key,value,timeout),这个很简朴就是把key映射到value,timeout指的是什么时候这个映射失效

  • 第二个就是get(key)函数,返回key所指向的value

  • 于是对一个正常的sql查询可以这么干

    sql = 'select count(*) from verycd'
    
    c = sqlite3.connect('verycd.db').cursor()
    
     
    
    # 本来的处理惩罚方法
    
    c.execute(sql)
    
    count = c.fetchone()[0]
    
     
    
    # 此刻的处理惩罚方法
    
    from hashlib import md5
    
    key=md5(sql)
    
    count = mc.get(key)
    
    if not count:
    
        c.execute(sql)
    
        count = c.fetchone()[0]
    
        mc.set(key,count,60*5) #存5分钟

    个中md5是为了让key漫衍更匀称,其他代码很直观我就不表明白。

    优化过语句1和语句2后,首页的平均生成时间已经低落到0.02秒,和discuz一个量级了;再颠末语句3的优化,最终功效是首页生成时间低落到了0.006秒阁下,颠末memcached寥寥几行代码的优化,机能提高了3300%。终于可以挺直腰板来看Discuz了)

      关键字:

    在线提交作业