美文网首页程序员
该用缓存还是得用缓存

该用缓存还是得用缓存

作者: panyanyany | 来源:发表于2019-02-05 20:30 被阅读21次

后台用了一年多,现在查询报表变得很卡,大概要15~180秒,运营经常反映报表加载不出来,我去服务器一看日志,原来查询花了200多秒,nginx直接超时了……

先优化一下 SQL

我的想法是优化报表的 SQL 语句,因为我发现查个 sql 居然加起来要 10几秒。

我们的 sql 分为2条,一条是先查总数,这是为了下一步分页用。另一条是查详情。

查总数的 sql 我看了下,index 都有用到,但是在 explain 中多出了 using temporary; using file sort; 这2项。于是我把 group by date 去掉,这2项就没了。

于是吭哧吭哧地把数据都加载出来,然后在代码里 group by,虽然比较费内存和 CPU,但总比让数据库做好啊对不对?

后来想着对第二条也这样优化,但是发现不行,因为第二条有个分页,不 group by 的话,就没法分页了……这个暂时没想到替代方法。可怜代码已经写了2小时了,只好先不用了。

代码写完了,本地测试一下,发现查询速度从 9s 降到 1s,果然有效!
于是赶紧弄上服务器,然后一试,变成 32s 了!而且 cpu 、内存狂涨!
无语了,赶紧回滚了。

事后分析,大概是因为数据量太大,服务器也处理不过来了……

试试缓存?

这事只好作罢,心里想,慢点就慢点吧,反正也是自己人用。
但是渠道那边又来找了,说是我们的 api 拉取超时了。这下就比较难办了,渠道那边超时,可能会影响我们正常的业务。况且这种现象如果听之任之,最终可能引发雪崩效应,到时就麻烦了。

但是现在数据库优化很蛋疼,怎么办呢?这时还是应该从业务角度考虑,渠道要的数据并不是实时数据,所以完全可以用缓存顶一下嘛。

django 的话,直接用 django-cacheops 就行了,挺好用的,直接在 queryset 后面加个 .cache() 就可以启用缓存了,当然配置里面要设置一下,不然它默认对所有查询都缓存就不好了,毕竟运营要看到的是实时数据。

代码改好了,部署上去,加载时间立即缩短了10倍!而且不是光 api 接口,连报表的查询也大大缩短了!真是意外的惊喜啊。

所以从这件事可以总结出2个道理:

  1. sql 查询变慢了,不一定是这条 sql 本身,可能是慢查询太多,导致它被拖累了
  2. 缓存一定要用上,减少数据库的压力是非常有必要的。

redis 的问题

不过,刚高兴没多久呢,也就1、2分钟吧,接口就报 500 错误了,异常信息提示 Connection closed by server ,郁闷,赶紧回滚。然后就在本地测,结果一点问题没有。我猜可能是配置不一样,但具体是哪个参数我也不知道了。

然后就是上网查资料,发现一个参数 timeout 貌似有用。分别在本地和服务器端看了下,原来本地 timeout = 0,服务器是 timeout = 60 。把它改过来之后,终于正常了。

不过呢,最近遇到的 redis 的问题挺多的,比如服务器上经常遇到 use of closed network connection ,这个就挺郁闷的,完全不知道怎么下手。

现在疏理一下,timeout 是 redis 用来控制客户端连接的。如果 timeout > 0 的话,如果客户端持续 timeout 秒没有活动,redis 就会关闭这个连接。

如果设置成 timeout = 0,就表示永远不关闭。

问题在于,admin 服务器请求量小,确实可能 60s 里没有活动,redis 可以关闭它,但是广告服务器请求量很大,为什么还是会关闭呢?

相关文章

  • 该用缓存还是得用缓存

    后台用了一年多,现在查询报表变得很卡,大概要15~180秒,运营经常反映报表加载不出来,我去服务器一看日志,原来查...

  • [译]HDFS的中心化缓存 (Centralized Cache

    原文 概览 HDFS上的中心化缓存是一个显式的缓存机制, 使得用户可以指定哪个路径被缓存. Namenode和拥有...

  • 面试官:Redis 如何实现每周热评功能?说说思路!

    思路分析 做每周热议,应该用缓存来做,如果直接查库的话,会对数据库造成压力。用缓存做的话,用Redis 来做缓存的...

  • Android缓存机制——LruCache

    一、Android中的缓存策略 Android的缓存,主要的就是内存缓存和硬盘缓存。 不管是内存缓存还是硬盘缓存,...

  • LruCache源码解析

    在做缓存时,我们首先会做添加和获取缓存功能,而不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了之后...

  • 第3章 下载缓存

    第3章 下载缓存 3.1 缓存还是不缓存 当爬取目的不是为了获取即时的,最新的数据时,可以使用缓存。缓存之后可以离...

  • 库存是先删缓存还是先改db

    库存是先删缓存还是先改db 先改db再淘汰缓存 缓存失效 A读db数据是旧值 B改数据并淘汰缓存 A写入旧值到缓存...

  • 淘汰缓存还是修改缓存

    问:KV缓存都缓存了一些什么数据?答:(1)朴素类型的数据,例如:int(2)序列化后的对象,例如:User实体,...

  • 缓存更新策略 - 一致性

    [TOC] 参考 Cache Aside Pattern 究竟先操作缓存,还是数据库? 缓存更新的套路 使用缓存的...

  • redis-mysql缓存不一致,双写

    redis-缓存不一致,双写 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存。又或者是先删除缓存...

网友评论

    本文标题:该用缓存还是得用缓存

    本文链接:https://www.haomeiwen.com/subject/glwvsqtx.html