`
flynewton
  • 浏览: 62596 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

30分钟3300%性能提升——python+memcached网页优化小记

阅读更多

关键字: python , 缓存 , memcached , 优化

 转自:http://obmem.info/?p=717

本来我一直不知道怎么来更好地优化网页的性能,然后最近做python和php同类网页渲染速度比较时,意外地发现一个很简单很白痴但是我一直没发现的好方法(不得不BS我自己):直接像某些php应用比如Discuz论坛那样,在生成的网页中打印出“本页面生成时间多少多少秒”,然后在不停地访问网页测试时,很直观地就能发现什么操作会导致瓶颈,怎样来解决瓶颈了。

 于是我发现SimpleCD在生成首页时,意外地竟然需要0.2秒左右,真真不能忍:对比Discuz论坛首页平均生成才0.02秒,而Discuz论坛的首页页面无疑比SimpleCD的主页要复杂不少;这让我情何以堪啊,因为这必然不是Python语言导致的差距,只能说是我完全没做优化而Discuz程序优化得很好的后果。

优化分析

其实不用分析也能知道肯定是数据库在拖累,SimpleCD在生成首页时需要在sqlite的三个数据库中进行42多次查询,是历史原因导致的极其低效的一个设计;但是这40多次查询中,其实大部分是非常快的查询,仔细分析一下就有两个是性能大户,其他都不慢。

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

  1. SELECT count(*) FROM verycd  

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

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

  1. SELECT verycdid,title,brief,updtime FROM verycd  
  2.     ORDER BY updtime DESC LIMIT 20;  

因为在updtime上面做了索引,所以其实真正查询时间也就是搜索索引的时间而已。然则为什么这个操作会慢呢?因为我的数据是按照publish time插入的,按update time进行显示的话就肯定需要在至少20个不同的地方做I/O,这么一来就慢了。解决的方法就是让它在一个地方做I/O。也就是,除非数据库加入新数据/改变原有数据,否则把这条语句的返回结果缓存起来。这么一来又快了20倍:)

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

  1. SELECT owner FROM LOCK WHERE id=XXXX;  
  2. SELECT hits FROM stat WHERE id=XXXX;  

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

总之这也不是问题,跟刚才的解决方法一样,统统缓存

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

Memcached终于出场

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

memcached是很强大的工具,因为它可以支持分布式的共享内存缓存,大站都用它,对小站点来说,只要出得起内存,这也是好东西;首页所需要的内存缓冲区大小估计不会超过10K,更何况我现在也是内存土豪了,还在乎这个?

安装:略

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

 

vi /etc/memcached.conf
/etc/init.d/memcached restart

在python的网页应用中使用之

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

memcache其实就是一个map结构,最常使用的就是两个函数了:

  • 第一个就是set(key,value,timeout),这个很简单就是把key映射到value,timeout指的是什么时候这个映射失效
  • 第二个就是get(key)函数,返回key所指向的value

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

  1. sql = 'select count(*) from verycd'  
  2. c = sqlite3.connect('verycd.db').cursor()  
  3.    
  4. #原来的处理方式  
  5. c.execute(sql)  
  6. count = c.fetchone()[0]  
  7.    
  8. #现在的处理方式  
  9. from hashlib import md5  
  10. key=md5(sql)  
  11. count = mc.get(key)  
  12. if not count:  
  13.     c.execute(sql)  
  14.     count = c.fetchone()[0]  
  15.     mc.set(key,count,60*5#存5分钟  

其中md5是为了让key分布更均匀,其他代码很直观我就不解释了。

优化结果和结论

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

说memcached是妖孽,并不是因为memcached应用了之后性能狂升——这本是意料之中的事情,不这样反而才奇怪——而是因为我基本上没花多少时间就实现了这么妖孽的效果,至少我花的时间并不比写这篇blog的时间多。那么方便的使用方法和那么显著的性能提升状况真是让人咋舌。

分享到:
评论

相关推荐

    Python + Memcached:分布式应用程序中的高效缓存.docx

    Python + Memcached:分布式应用程序中的高效缓存

    tomcat8+memcached session共享

    标题中的“tomcat8+memcached session共享”指的是在Tomcat 8服务器中利用Memcached进行session共享的技术实践。在分布式系统中,session共享是一个重要的问题,因为用户在访问不同的服务器节点时,需要保持登录状态...

    python-memcached python-memcached

    10. **性能优化**:Python-memcached库设计得非常轻量级,它使用最少的网络通信开销,以提高与Memcached服务器之间的通信效率。 Python-memcached库的使用方法相对简单,通常需要导入库,创建客户端,然后通过...

    Spring4+SpringMVC+mysql+memcached【同时支持mybatis+hibernate两种底层操作框架】

    在高并发场景下,通过将频繁访问的数据暂存到内存中,Memcached可以显著提升响应速度,尤其适用于读多写少的应用。 5. **MyBatis**:MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。...

    Tomcat+MemcachedRedis集群

    Tomcat+MemcachedRedis集群,有视频实战以及源码。包含Tomcat性能优化,Redis基础入门以及使用场景,性能优化

    nginx+tomcat7+memcached session会话保持

    在构建高性能、高可用性的Web应用系统时,会话保持是一个关键环节,它涉及到用户登录状态、购物车信息等重要数据的持久化处理。本文将详细介绍如何在Nginx、Tomcat7和Memcached的环境下实现会话保持,确保用户在多台...

    nginx+tomcat7+memcached所需jar.zip

    nginx+tomcat7+memcached所需jar.zipnginx+tomcat7+memcached所需jar.zipnginx+tomcat7+memcached所需jar.zipnginx+tomcat7+memcached所需jar.zip

    springMVC+mybatis+jackson+memcached

    在这个示例中,Memcached被用作临时存储,保存经常访问的数据,减少对数据库的频繁访问,从而提升应用性能。 整合这四者的过程大致如下: - 首先,你需要在项目中添加Spring MVC、MyBatis、Jackson和Memcached的...

    nginx+tomcat+memcached例子

    【标题】"nginx+tomcat+memcached例子"揭示了一个集成Web服务器技术的场景,其中Nginx作为前端代理服务器,Tomcat作为后端Java应用服务器,而Memcached则作为一个分布式内存缓存系统来提高整体性能。这个组合常用于...

    Nginx+Tomcat+Memcached集群Session共享实例

    Nginx+Tomcat+Memcached集群Session共享实例,Nginx 1.81 + tomcat1 + tomcat2 + Memcached 完整可运行 访问根目录下 test.jsp 可看效果

    tomcat6+session+memcached

    6. **性能优化**:使用Memcached进行Session共享可以减少服务器之间的通信开销,提高响应速度,但需要考虑Session的过期策略、并发访问等问题。 通过以上知识点的讲解,我们可以了解到如何在Tomcat6环境中使用Java ...

    session+memcached所需jar

    session+memcached Memcached配置需要下载以下jar包并放在tomcat的lib目录下 如果tomcat过多不建议session同步,server间相互同步session很耗资源,高并发环境容易引起Session风暴。请根据自己应用情况合理采纳...

    python-memcached-latest.tar

    Python-Memcached是一个Python接口,用于与Memcached内存缓存系统进行交互。Memcached是一种高性能、分布式内存对象缓存系统,用于减少数据库负载,通过在内存中存储数据来加速网络应用。这个`python-memcached-...

    搭建linux+php+memcached架构的网站.zip

    搭建一个基于Linux、PHP和Memcached的网站架构是一项常见的任务,尤其对于那些希望提升网站性能、减少...通过按照这些指南进行操作,开发者可以成功地建立一个高效的Web服务架构,利用Memcached来优化数据库性能。

    Nginx+Tomcat7+Memcached集群Session共享

    Nginx+Tomcat7+Memcached集群Session共享 完整例子 主要是利用memcached-session-manager(下面简称msm)开源tomcat插件改变tomcat原始的session存储机制,将session的存储放到分布式缓存memcache中,从而实现对...

    tomcate7+memcached所需jar包

    而Memcached则是一种高性能、分布式内存对象缓存系统,常用于减轻数据库的负载,提升Web应用的响应速度。将Tomcat与Memcached结合使用,可以构建出高效且可扩展的Web服务。 在"tomcate7+memcached所需jar包"这个...

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 nginx配置

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 nginx配置

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 tomcat部分

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 tomcat部分

    nginx+apache+mysql+php+memcached+squid搭建门户网站

    - **Memcached**:安装完成后需配置缓存大小等相关参数,以提高Web应用性能。 #### 六、安装Apache、PHP、eAccelerator、php-memcache - **Apache**:安装过程中需要注意启用MPM模式,以提升处理并发请求的能力。 ...

    python-memcached

    7. **预加载机制**:Python-Memcached库还包含了预加载功能,可以在程序启动时预先加载一部分常用数据到缓存中,提升应用性能。 8. **持久化**:虽然Memcached不支持数据持久化,但可以通过配合其他工具(如Redis或...

Global site tag (gtag.js) - Google Analytics