zoukankan      html  css  js  c++  java
  • 记录一次读取memcache缓存的优化

    我们是用mvc做web,大部分数据都用memcache做了缓存

    有2台memcache缓存服务器

    数据并不大。

    某页面响应较慢,大概在4s左右。

    页面本身很简单只是显示一个表单。

    但是layout相对复杂,有很多局部页,并且页面上有若干filter控制权限,局部页上也有

    以上是背景

    主要的业务逻辑是这样的:

    取公司的结构缓存,里面存了公司里所有的人(id)。

    取每个人的缓存,获取一些他的名字,头像之类的详细信息。

    开发环境下,本地程序连本地缓存,读一个用户仅耗时1ms。

    一个50人的公司,耗时50ms,因为各种filter,局部页等地方,都是传递的公司id,所以同样的逻辑可能要跑多次,假设是10次,500ms,是可以接受的范围。

    测试环境,2台缓存服务,局域网。

    读一个人的缓存,耗时上升到4-6ms。

    生产环境,2台缓存服务,局域网。

    读一个人的缓存,耗时上升到6-12ms。

    买糕的,每个提升10倍,整体提升10倍,于是页面响应速度从半秒上升到了5s。

    各种filter和方法都不仅仅在一个页面里使用,都是一些相对原子化的,若干组合成一个完整的业务。

    但是读这么多次,数据是完全一样的,即便是1ms,他也是浪费的。

    能不能在同一个请求中,对同一个缓存,只读一次?!

    祭出HttpContext.Current.Item。每次读缓存时,先判断item里有没有,如果有,就不取缓存服务器读了,直接用这个item里的,如果没有,就读缓存,然后把结果存到item里,相当于在item里对缓存的数据又做了一次缓存。

    好在我们的读缓存是用的一个相对底层的方法,而不是拿来一个缓存客户端就直接使用的,很方便加上。

    另一个好在,当时为了避免内存碎片,我们把若干用户分组存到了memcache里,比如没100个用户1组,一次就能从缓存读出来100个人。

    所以经过上面优化后,只需要读一次缓存就可以取到很多用户。取完全部50用户,理论上最多需要50次;但是实际上可能几次就够了。

    加上对缓存的缓存,就目前我们的业务逻辑来说,响应速度基本可提升10倍。

    在生产环境,页面响应有4-5s 提高到400-500ms,

    而在本机,则可以提高到50ms左右

    ps:

    for 100次读缓存,在for之前和之后拿Stopwatch卡时间,for中的每次读取,分别拿另一个Stopwatch卡时间,并把每次的时间累加

    结果for外层的耗时要比每次的耗时累加多50ms,但是空跑for耗时0(只是不读缓存了,改有的stopwatch的start stop,累加等还有),难道是编辑器已经智能到这个程度了?我没看il代码到底是什么

    不解

    ps2:

    本机连本机缓存,不走局域网,这个好理解。

    但是测试环境是web一台,memcache另外两台,而生产环境是web1台,memcache两台,但是其中1台与web是同一台,也就是说,当memcache的某key做部分hash的时候,他有50%的几率是可以分布到与web同一台的,平均耗时应该是大于本机但是小于测试。

    而实际情况却是生产环境最慢。

    不解。

    ps3:

    测试环境之所以叫测试环境就是因为他基本是完全模拟了生产环境,那在这两种基本相同的情况下,为什么还会有如此差异。如果测试环境慢,反而好理解,因为测试机,包括用的交换机等都不如生产环境的强大。我们的网站访问量很小(刚刚上线,基本只有公司内部人访问),基本可以排除因为生产环境的压力大造成的。

    不解。

  • 相关阅读:
    bzoj4196: [Noi2015]软件包管理器
    bzoj3992: [SDOI2015]序列统计
    bzoj 4178: A
    Spoj 8372 Triple Sums
    hdu contest day1 1007 Tricks Device
    hdu contest day1 1002 Assignment
    2018暑期生活指导第三周
    2018暑期生活指导第二周
    《大道至简》阅读笔记
    2018暑期生活指导第一周
  • 原文地址:https://www.cnblogs.com/czcz1024/p/3205493.html
Copyright © 2011-2022 走看看