当前位置:首页 > 问答 > 正文

红米用Redis缓存了,性能好像快了不少,感觉挺实用的嘛

(来源:用户日常技术分享交流)

红米用Redis缓存了,性能好像快了不少,感觉挺实用的嘛,这事儿还得从前段时间我们那个项目说起,我们做的算是个挺普通的手机应用,就是给红米手机用户提供一些本地化服务和内容推荐的,一开始呢,数据都是从数据库里直接取的,用户一点开某个页面,今日热点”或者“个性化推荐”,后台就得吭哧吭哧地去查数据库,组装数据,然后再返回给手机端显示。

刚开始用户量不大的时候,倒也没觉得有啥问题,页面打开速度虽然不算飞快,但也能接受,可后来用户慢慢多起来了,特别是做了一次市场推广后,访问量一下子涨了不少,这时候问题就暴露出来了,有时候赶上高峰期,比如晚上七八点钟,大家吃完饭都抱着手机刷的时候,服务器就有点顶不住了,数据库的压力特别大,经常能看到CPU占用率飙升,反映到用户那边,最直观的感觉就是——卡,点一下要等好几秒才有反应,甚至有时候直接报错,提示“网络连接失败”或者“服务繁忙”,用户投诉一下子就多了起来,客服那边都快被问爆了,我们技术团队的压力也很大。

我们老大就召集我们开了个会,说这样下去不行,用户体验太差了,得想办法优化,大家讨论来讨论去,有人提议升级服务器硬件,但这成本太高,而且可能只是暂时缓解,不是根本办法,也有人提议优化数据库的SQL查询语句,我们确实也做了一些优化,效果是有一些,但感觉还是不够理想,尤其是在应对那种瞬间的高并发请求时,数据库依然是瓶颈。

后来,我们组里一个比较有经验的同事就提到了Redis,他说,像我们这种读多写少的场景,特别适合引入缓存,他打了个比方,说数据库就像一个大仓库,东西都放在很深的货架上,每次取货都得跑进去找半天,而Redis呢,就像是在仓库门口摆了个临时小货架,把那些最热门、最常被拿取的货物提前摆出来,这样,当大多数人想要热门商品时,直接在门口小货架拿了就走,又快又方便,只有少数人要买冷门商品,才需要进仓库深处去找,这样一来,仓库(数据库)的压力就小多了,门口排队的人(等待响应的用户)也能很快拿到东西。

我们听了觉得这个比喻挺形象的,决定试试,方案大概是这样设计的:当用户第一次请求某个热门数据时,本周应用排行榜”,程序还是老老实实去数据库里查,查完之后,除了返回给用户,还会把这个结果集存一份到Redis里,并设置一个过期时间,比如半小时,那么在接下来的半小时内,如果再有用户(不管是同一个用户还是其他成千上万的用户)来请求同样的“本周应用排行榜”,程序就不再劳烦数据库了,而是直接去Redis里取,Redis是纯内存存储,读写速度极快,比从硬盘读数据的数据库要快好几个数量级。

这么一改,部署上线之后,效果真的是立竿见影,最明显的感觉就是,服务器的负载降下来了,数据库也不再总是“气喘吁吁”了,我们监控了一下后台数据,高峰期数据库的查询次数大幅下降,CPU占用率也恢复了正常水平,从用户端反馈来看,抱怨卡顿和加载慢的投诉几乎没有了,我们自己用测试工具测了一下页面的平均响应时间,比之前提升了大概有五六倍,以前可能要一秒钟才能打开的页面,现在基本上都是毫秒级响应,点一下就出来了,非常流畅。

用Redis也不是说就一劳永逸了,我们也遇到了一些小问题需要处理,缓存数据的一致性:如果后台管理员在数据库里更新了排行榜的数据,但Redis里缓存着的还是旧数据,那用户看到的就不是最新的了,我们解决的办法就是,在管理员更新数据的同时,主动把Redis里对应的缓存数据删除(叫失效),这样下次用户再请求时,发现缓存没了,就会重新去数据库取最新的数据并重新缓存起来,还有就是缓存键的设计,要合理,不能冲突,不然就乱套了。

这次给红米项目加上Redis缓存,算是一个比较成功的优化实践,没用什么特别高深莫测的技术,就是用了这么一个简单实用的工具,就解决了大问题,成本不高,效果却非常显著,确实感觉挺实用的,这也让我们体会到,有时候优化性能不一定非要搞得很复杂,找准关键点,用对合适的工具,就能起到四两拨千斤的效果,现在项目运行得很稳定,我们也在考虑把缓存应用到其他类似的场景里去。

红米用Redis缓存了,性能好像快了不少,感觉挺实用的嘛