9月7日-8日,相约 2023 腾讯全球数字生态大会!聚焦产业未来发展新趋势! 了解详情
写点什么

程序设计中,如何用好缓存?

  • 2017-01-15
  • 本文字数:1807 字

    阅读完需:约 6 分钟

在文章开头,我们首先约定,本文说的缓存,是通过记录和保存应用程序依赖的响应慢模块返回值,在后续请求中直接使用这些数据以提高响应速度的设计。

缓存是优化系统性能最常用的方式之一,通过在耗时部件(如数据库)之前添加缓存,可以减少实际调用次数,降低响应时间。但是在引入缓存之前,务必三思而后行。本文通过一些引入缓存时的常见错误,对如何用好缓存提供了一些建议。

常见错误

启动时缓存

有时候,我们会发现应用程序启动很慢,最终发现是其中一个依赖的服务响应时间很长,这时该怎么办?

通常来说,遇到这类问题,说明这个依赖服务无法满足需求。如果这是一个第三方服务,控制权不在自己手上,这时我们可能会引入缓存。

此时引入缓存的问题,是缓存失效策略难以生效,因为缓存设计的本意就是尽可能少的请求依赖的服务。

过早缓存

这里提到“早”,不是应用程序的生命周期,而是开发的周期。有的时候我们会看见,一些开发者在开发初期就已经估算出系统瓶颈,并引入缓存。

事实上,这样的做法掩盖了可能进行性能优化的点。反正到时候这个服务的返回值会被缓存住,我干嘛还要花时间去优化这部分代码呢?

集成缓存

SOLID 原则中的“S”代表——单一功能原则(Single responsibility principle)。当应用程序集成缓存模块之后,缓存模块和服务层就有了强耦合,无法在没有缓存模块的参与下单独运行。

缓存所有内容

有的时候为了降低响应延迟,可能会盲目的对外部调用都加上缓存。事实上,这样的行为很容易让开发者和维护者无法意识到缓存模块的存在,最终对底层依赖模块的可靠性做出了错误的评估。

级联缓存

缓存所有内容,或者只是缓存了大部分内容,可能会导致缓存数据中包含其他缓存数据。

如果应用程序中包含这种级联的缓存结构,可能导致的情况是缓存失效时间不可控。最上层的缓存需要等每一级缓存都失效更新之后,最终返回的数据才会彻底更新。

不可刷新缓存

通常情况下,缓存中间件会提供一个刷新缓存的工具。例如 Redis,维护人员可以通过其提供的工具,删除部分数据,甚至刷新整个缓存。

但是,一些临时缓存,可能不会包含这样的工具。例如简单的将数据保存在内容中的缓存,通常不会允许外部工具来修改或者删除缓存内容。这时,如果发现缓存数据异常,维护人员只能采取重启服务的方式,这将大大增加运维成本和响应时间。更有甚者,一些缓存可能会将缓存内容写在文件系统中进行备份。此时除了重启服务,还需要确保应用程序启动之前删除文件系统上的缓存备份。

缓存带来的影响

上面提到了引入缓存可能导致的常见错误,这些问题在无缓存系统中通过不会考虑。

部署一个重度依赖缓存的系统,可能会因为等待缓存失效而花费大量时间。例如通过 CDN 缓存内容,系统发布之后去刷新 CDN 配置、CDN 缓存的内容,可能需要几个小时。

另外,出现性能瓶颈优先考虑缓存,会导致性能问题被掩盖,得不到真正的解决。事实上,很多时候调优代码花费的时间,和引入缓存组件不会相差太多。

最后,对于包含缓存组件的系统,调试成本会大大增加。经常会发生追踪半天代码,结果数据来自缓存,和实际逻辑上应该依赖的组件没有任何关系。同样的问题也可能出现在执行了所有相关测试用例之后,修改到的代码实际没有被测试到。

如何用好缓存?

放弃缓存!

好吧,很多时候缓存是无法避免的。基于互联网的系统,很难完全避免使用缓存,甚至连 http 协议头,都包含缓存配置:Cache-Control: max-age=xxx

了解数据

如果要将数据访问缓存,首先需要了解数据更新策略。只有明确了解数据何时需要更新,才能通过If-Modified-Since头来判断客户端请求的数据是否需要更新,是简单返回304 Not Modified响应让客户端复用之前的本地缓存数据,还是返回最新数据。另外,为了更好利用 http 协议中的缓存,建议给数据区分版本,或者利用 eTag 来标记缓存数据的版本。

优化性能而不是使用缓存

前文提到过,使用缓存往往会将潜在性能问题掩盖。尽可能利用性能分析工具,找到应用程序响应缓慢的真实原因并且修复它。例如减少无效代码调用,根据 SQL 执行计划优化 SQL 等。

总结

缓存是非常有用的工具,但极易被滥用。不到最后一刻不要使用缓存,优先考虑使用其他方式优化应用程序性能。

如果读者还需要其他因为缓存引起的问题,请在下方留言,以便将这些问题添加到列表中。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2017-01-15 18:005598

评论

发布
暂无评论
发现更多内容

RoCE多网卡时,报文可以过去,但是回不来

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟 企业号 5 月 PK 榜

GaussDB(DWS)条件表达式函数返回错误结果集排查

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 5 月 PK 榜

一张图感受真实的 TCP 状态转移

九零后程序员

TCP 网络 Linux Kenel ebpf

一个字牛!腾讯大牛把《数据结构与算法》讲透了,带源码笔记

程序知音

Java 数据结构 算法 后端 数据结构与算法

Java 修改项目名称及其相关信息

Andy

华为ISDP:从ChatGPT说起,企业作业数字化转型需要怎样的平台工具?

科技怪授

腾讯T8架构师基于SpringBoot2.x搭建分布式架构

做梦都在改BUG

Java spring Spring Boot 框架

首页推荐!阿里大佬带你一周刷完Java面试题1700页,offer拿到手软

做梦都在改BUG

Java java面试 Java八股文 Java面试题 Java面试八股文

未来边缘计算:趋于分布式智能

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 5 月 PK 榜

高并发封神之作的《亿级流量高并发》惨遭GitHub免费开源

小小怪下士

Java 程序员 高并发

模板一作业

家有两宝

#架构训练营

PoseiSwap  参赛,参与斯坦福、Nautilus等联合主办的 Hackathon 活动

鳄鱼视界

面试官:SpringBoot可以同时处理多少请求?

做梦都在改BUG

Java spring Spring Boot 框架

Nautilus Chain上线主网,为DeFi和流支付的未来构建基础

石头财经

分布式事务的21种武器 - 6

俞凡

架构 云原生

如何通过Python将JSON格式文件导入redis

华为云开发者联盟

Python redis 华为云 华为云开发者联盟 企业号 5 月 PK 榜

无惧面试!2023最新最全Java面试手册全网首次开放下载

程序员小毕

程序员 多线程 高并发 架构师 java面试

不愧是阿里巴巴内网的“高并发系统设计”学习笔记,全程不讲一句废话!

采菊东篱下

Java 高并发

SpringBoot 整合 MyBatis 组合 Redis 作为数据源缓存

Java你猿哥

Java redis Spring Boot mybatis ssm

Nautilus Chain上线主网,为DeFi和流支付的未来构建基础

BlockChain先知

线程的生命周期和常用方法

Java你猿哥

源码 jdk 线程 多线程 Monitor

低代码的“钱景”——专业的事交给专业的人来做

引迈信息

低代码 JNPF

火爆Github的1000道Java面试题:无死角打击所有Java面试问题,按这个学,找工作完全没问题!

架构师之道

Java 编程

解决缓存与数据库数据不一致的问题,这篇文章告诉你如何做!

做梦都在改BUG

Java 数据库 缓存 一致性

腾讯T4大牛整理的SpringBoot文档,覆盖你认知中的所有操作

程序知音

Java 架构 微服务 springboot Java进阶

【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache抽象详解的核心原理探索

洛神灬殇

spring 缓存 cache 缓存管理

2023华为伙伴大会:ISDP发布伙伴体验中心,邀伙伴探索数智化未来

科技怪授

京东首席系统架构师教你如何搭建高可用高并发系统架构

做梦都在改BUG

Java 高可用 系统架构 高并发

美团T9大牛总结的神仙微服务架构设计模式PDF

做梦都在改BUG

Java 架构 微服务

这个线上BUG,让你彻底搞懂了MySQL的字符集,别问我咋知道的

Java你猿哥

Java MySQL ssm 字符串 字符集

WritingGPT: 基于ChatGPT和AutoGPT打造个人写作团队

俞凡

人工智能

  • 扫码添加小助手
    领取最新资料包
程序设计中,如何用好缓存?_架构_金灵杰_InfoQ精选文章