服务器之如何更好的是使用开发缓存

很多项目服务端最开始的性能瓶颈不出现在语言也不出现在框架,通常是出现在数据库上,具体表现为数据库慢查询、死锁、数据库连接数占满等。当遇到数据库读写频繁的业务,缓存是必不可少的了。但是缓存该怎么做才能使利用率更高,减少或避免脏读呢?本篇就以自己的经验来谈谈如何更好的使用缓存。
先说说自己的项目和经历。
项目类似于微博APP,最开始的时候使用php语言yii2框架搭建,直接连数据库的。当时代码写的飞快要什么查什么爽爽的。时间长了用户量和生产内容越来越多,数据库开始庞大起来。查询效率好像慢了很多哦,怎么办?好!那就看慢查询日志,建索引。又过了一段时间,用户量和日活还是不断上涨数据库的使用太过频繁。于是,要上缓存了,选用的是Redis。
接下来就是一段比较纠结的挖坑踩坑的日子。拿微博主页列表(Home)、热门列表(Hot)、微博详情(Weibo)3个接口来举例子。其中,主页列表展示的是用户所关注的博主发的微博,所以关注的人不同列表内容也就不同。当时大概是这样做缓存的:主页列表数据以{Home:$用户ID:list}为key,$用户ID是变量;热门列表数据以{Hot:list}为key;微博详情以{Weibo:$微博ID}为key,$微博ID是变量。缓存时间约30秒。那么问题来了,一、假如ID为1的微博出现在主页列表又出现在热门列表又有详情,同一份数据就保存了3份或者更多,增加了内存开销。二、当详情评论数和点赞数增加的时候,其他两份缓存的数量没有增加那么数据不准确出现很多脏读。三、像主页每一个用户几乎不同的列表也表示每个用户进来都要查一遍数据库,缓存就变得几乎没有意义。
那么,回到更好的使用缓存这个主题了,我推荐采用的是——ORM缓存。
ORM(对象-关系映射)不多说,ORM缓存思想即以对象的方式缓存数据。主要形式:以数据库、表名、主键为key,Hash缓存字段和值。memcached没有hash数据结构可以用数据库、表名、主键、字段组成为key将值缓存。
下面说明如何将ORM缓存运用到刚才提到的几个微博接口中。
首先,数据库查询方式整改。例如主页列表,我所关注的用户ID假如有 1、2、3、4、5、6...,假设原来sql语句select xxx,xxx... from weibo where uid in (1,2,3,4,5,6...)将改成select weibo_id from weibo where uid in (1,2,3,4,5,6...)也就是只查询出主键。接着才是去拿数据。查出来的微博ID假如有1001、1002、1003...,按照以数据库、表名、主键为key的规则组合成的key大概是这个样子:dbname:weibo:1001、dbname:weibo:1002、dbname:weibo:1003...然后用循环一条一条的去拿数据,顺序是先查询Redis,没有数据再去数据库拿一行记录然后将数据保存到Redis中。热门列表接口原理也是如此。详情接口更不用说,持有ID直接去查即可。所以,以上变化是之前的列表一次查询变成了1+N次(N是查询到的记录数)查询。这时有人可能疑问这样不是增加了工作量吗?看上去是的,但是分析一下发现,虽然是1+N次查询,只要查到就往缓存里塞,后面数据几乎都是从Redis去拿的,而且这样保证了缓存数据的唯一性,一条数据记录在缓存中对应一份数据,维护起来非常方便,即使多处的地方使用到这条微博,只要修改一处可保证一致的显示结果。唯一需要的是去数据库查一次主键而已。
或许你觉得,以上的解决方式去拿列表主键的时候还是需要去查询一次数据库啊,但要知道索引原理是保存记录的主键,如果索引做的好,这里的查询消耗微乎其微。而且,这个问题也是可以优化解决的。读者们不妨思考一下如何去处理这个问题。在此丢下一个包袱,有需要的话我会再写一篇文章分享解决方案。
读的情况描述完了,到了写数据。其实也蛮简单,因为之前也提过ORM缓存数据的优点之一就是,记录在缓存中只有一份,那么,也就将数据库记录修改和缓存数据修改即可。至于修改数据库和缓存顺序先后其实都可以,保证两个都修改成功即可,当然使用还可以修改完数据后删除缓存等待下一次查询时再放入缓存这样的懒汉模式,我自己使用先修改数据库成功后修改缓存的策略。
我经历的项目中单台服务器在千万级表,几十W日活的情况下还是很稳健的。证明ORM缓存是不错的优化方案。总结下来最重要的有如下几点:1.将数据库的行为单位作为一个数据缓存;2.将查询拆分为1+N次查询;3.不破坏ORM的数据构避,免使用连表查询(也方便以后分表分库,减少不必要的麻烦)
关于服务端如何更好的使用缓存先写到这里,本文是我尝试总结自己的一些服务端开发收获和心得的第一篇文章。平时看简书用移动端比较多,明白在手机上看代码其实不方便,所以写博客将尽量少贴或不贴代码,多说说概念和设计上的东西方便大家在移动端阅读。欢迎大家评论或私信,我们相互讨论学习技术。
 原网页已由QQ浏览器云转码
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值