百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

大厂面试官:Redis中缓存数据更新策略有哪些?

nanshan 2024-12-12 14:06 13 浏览 0 评论

缓存是一把双刃剑,在带来性能提升的同时,也会带来一些问题。首先就是缓存一致性的问题,因为我们把数据同时保存在缓存和数据库当中,当我们修改了数据库之后,缓存是无法感知到数据变化的,这个时候缓存中保留的就是旧数据,那么用户来查询的时候查到的就是旧数据。这在很多业务场景下是不被允许的。所以今天咱们就一起讨论一下企业中常用的几种缓存更新策略。

一、内存淘汰(无需编码)

这个机制实际上是Redis用来解决内存不足的问题的,因为Redis是基于内存的,内存是比较珍贵的资源,在使用Redis的时候往往会设置一个内存上限,当Redis中的数据达到这个上限时,会触发Redis的内存淘汰策略。

使用这种方式的好处就是不用自己维护缓存数据,当Redis中缓存数据大小达到我们设置的最大值时,自动淘汰部分数据,下次查询的时候再次更新,这种策略的数据一致性是最差的,因为触发淘汰机制的时机是不可控的,而且就算触发了,也不能保证会淘汰掉要更新的缓存数据。所以用这种方式解决一致性问题完全就是看缘分了。但好处就是代码的维护成本为0,我们只需要修改一下配置文件即可。

二、超时剔除(无需编码)

给缓存数据加上TTL过期时间,到期后自动删除缓存。下次查询更新缓存。

手动给缓存数据加上过期时间,到期后自动删除缓存,下次查询时更新,这种方式也有很大的概率产生数据一致性问题,过期时间是固定的,如果一条缓存数据刚刚存入Redis,这个时候刚好更新了数据库,那么在这个缓存数据过期之前,数据库和缓存中的数据都是不一致的。这种方式比内存淘汰策略好那么一点点,数据一致性问题出现的最大时间就是我们设置的过期时间。如果业务对数据的一致性要求不是很高,那么我们可以设置一个在业务允许范围内的过期时间,用这种方式实现数据最终一致性。

三、主动更新(需要编码)

需要我们手动编写业务逻辑,在修改数据库的同时,更新缓存。主动更新策略有三种

1. Cache Aside Pattern:由缓存的调用者,在更新数据库的同时更新缓存。

2. Read/Write Through Pattern:缓存和数据库整合为一个服务,由服务来维护一致性。调用者调用服务,不用关心一致性问题。

3. Write Behind Caching Pattern:调用者只操作缓存,由其他线程异步的将缓存数据持久化到数据库,最终保持一致。

在企业中使用最多的主动更新策略是 Cache Aside Pattern。也就是我们自己编码来保证数据的一致性。

操作缓存和数据库时有三个问题需要我们考虑:

1. 删除缓存还是更新缓存

1)更新缓存:每次更新数据库都更新缓存,无效写操作比较多。

这种方式的缺点很明显,举个例子:假如我更新了100次数据库,然后又同时更新了100次缓存,但是在更新的时候并没有人来查这个数据,那么我更新这100次缓存好像也没啥用吧,相当于前99次都是无用功,只有最后一次才是有用的。这就是无效写操作过多的原因。

2)删除缓存:更新数据库时让缓存失效,查询时再更新缓存。(延迟加载)一般选择这个方案

这个方案比较合理一点,可以避免过多的无效写操作,缓存删除后,只要没人来查询这条数据,数据就不会被写入缓存,这样就可以避免大量无效的写操作。

2. 如何保证缓存与数据库的操作同时成功或失败

1)单体系统,将缓存与数据库操作放在一个事务中。

2)分布式系统,利用TCC等分布式事务方案。

3. 先操作缓存还是数据库

1. 先删除缓存,再操作数据库

这种方式存在很明显的问题,假设有两个并发操作,线程A更新,线程B查询。线程A先删除缓存,然后还没来得及更新数据库,CPU资源被线程B抢走,线程B查询缓存发现没有命中(因为已经被线程A删除了),查询数据库,然后把结果写入到缓存中。这个时候线程A终于抢到CPU资源了,然后更新数据库,此时就会造成数据不一致问题。

2. 先操作数据库,再删除缓存(使用最多的方式)

这种处理方式使用的频率是最高的,因为出错的概率非常小,只有一种比较极端的情况才会出现数据一致性问题。

同样有两个并发请求,线程A查询、线程B更新,当线程A查询的时候,缓存刚好失效,然后就去查询数据库拿到数据,在准备写入缓存的时候,CPU资源被线程B抢走,线程B开始更新数据库,然后删除缓存(这一步其实等于无用,因为缓存已经过期)。此时线程A再次获取到CPU资源,然后写入缓存,此时写入的是更新前的旧数据,会产生数据一致性问题。

看起来这确实也是一个问题,但是我们仔细分析一下这种情况都需要满足哪些条件:

1. 并发读写操作

2. 读缓存时,缓存刚好失效

3. 写数据库操作要比写缓存快

写数据库是操作磁盘,写缓存是操作内存的,所以不太可能会出现写磁盘的速度快于写内存的。因此使用这种方式出现数据一致性的概率是很小的。

3.延时双删策略

延迟双删策略是分布式系统中数据库存储和缓存数据保持一致性的常用策略,但它不是强一致。其实不管哪种方案,都避免不了Redis存在脏数据的问题,只能减轻这个问题,要想彻底解决,得要用到同步锁和对应的业务逻辑层面解决。

前面两种方案的不足点我们进行了分析,第二种方式的使用频率比较高,但是也有一些小缺陷,虽然说发生的概率很低,但是这个概率到了线上会不会发生也不好说,所以就有了延时双删策略对第二种方式做补充。

所谓延时双删就是先进行缓存清除,再执行数据库操作,最后(延迟N秒)再执行缓存清除。延迟N秒的时间要大于一次写操作的时间,这个延时N秒就是了完善保证第二种策略中不足,可以保证线程A的写缓存和线程B的修改数据库、删除缓存都执行完毕,然后再删除缓存一次,就可以保证后面再来的查询请求可以查询到最新数据。

ps: 一般的延时时间设置为3S左右,具体情况要根据业务场景取最佳值。

总结

1. 内存淘汰:不用自己维护,利用Redis内存淘汰机制,自动删除部分缓存数据,这些被删除的数据在下一次被查询时更新。这种方式一致性最差。

2.超时剔除:给缓存数据加上过期时间 ,到期后自动删除,下次查询时更新,数据一致性问题大概率会出现。维护成本比较低。

3.主动更新:编写业务逻辑,在修改数据库的同时更新缓存,一致性比较好,维护成本比较高。一般采用先操作数据库再更新缓存的方式。

一般在数据一致性要求比较低的场景下可以使用内存淘汰机制,比如商城首页的分类信息,这些东西基本上是不会变化的。如果一致性要求比较高,我们可以采用主动更新+超时剔除兜底的方式来处理。

相关推荐

0722-6.2.0-如何在RedHat7.2使用rpm安装CDH(无CM)

文档编写目的在前面的文档中,介绍了在有CM和无CM两种情况下使用rpm方式安装CDH5.10.0,本文档将介绍如何在无CM的情况下使用rpm方式安装CDH6.2.0,与之前安装C5进行对比。环境介绍:...

ARM64 平台基于 openEuler + iSula 环境部署 Kubernetes

为什么要在arm64平台上部署Kubernetes,而且还是鲲鹏920的架构。说来话长。。。此处省略5000字。介绍下系统信息;o架构:鲲鹏920(Kunpeng920)oOS:ope...

生产环境starrocks 3.1存算一体集群部署

集群规划FE:节点主要负责元数据管理、客户端连接管理、查询计划和查询调度。>3节点。BE:节点负责数据存储和SQL执行。>3节点。CN:无存储功能能的BE。环境准备CPU检查JDK...

在CentOS上添加swap虚拟内存并设置优先级

现如今很多云服务器都会自己配置好虚拟内存,当然也有很多没有配置虚拟内存的,虚拟内存可以让我们的低配服务器使用更多的内存,可以减少很多硬件成本,比如我们运行很多服务的时候,内存常常会满,当配置了虚拟内存...

国产深度(deepin)操作系统优化指南

1.升级内核随着deepin版本的更新,会自动升级系统内核,但是我们依旧可以通过命令行手动升级内核,以获取更好的性能和更多的硬件支持。具体操作:-添加PPAs使用以下命令添加PPAs:```...

postgresql-15.4 多节点主从(读写分离)

1、下载软件[root@TX-CN-PostgreSQL01-252software]#wgethttps://ftp.postgresql.org/pub/source/v15.4/postg...

Docker 容器 Java 服务内存与 GC 优化实施方案

一、设置Docker容器内存限制(生产环境建议)1.查看宿主机可用内存bashfree-h#示例输出(假设宿主机剩余16GB可用内存)#Mem:64G...

虚拟内存设置、解决linux内存不够问题

虚拟内存设置(解决linux内存不够情况)背景介绍  Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级。所以,程序和数据如果在内存的话,会有非常快的读写速度。但是,内存...

Elasticsearch性能调优(5):服务器配置选择

在选择elasticsearch服务器时,要尽可能地选择与当前业务量相匹配的服务器。如果服务器配置太低,则意味着需要更多的节点来满足需求,一个集群的节点太多时会增加集群管理的成本。如果服务器配置太高,...

Es如何落地

一、配置准备节点类型CPU内存硬盘网络机器数操作系统data节点16C64G2000G本地SSD所有es同一可用区3(ecs)Centos7master节点2C8G200G云SSD所有es同一可用区...

针对Linux内存管理知识学习总结

现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的。对于内存部分需要知道:地址映射内存管理的方式缺页异常先来看一些基本的知识,在进程看来,内存分为内...

MySQL进阶之性能优化

概述MySQL的性能优化,包括了服务器硬件优化、操作系统的优化、MySQL数据库配置优化、数据库表设计的优化、SQL语句优化等5个方面的优化。在进行优化之前,需要先掌握性能分析的思路和方法,找出问题,...

Linux Cgroups(Control Groups)原理

LinuxCgroups(ControlGroups)是内核提供的资源分配、限制和监控机制,通过层级化进程分组实现资源的精细化控制。以下从核心原理、操作示例和版本演进三方面详细分析:一、核心原理与...

linux 常用性能优化参数及理解

1.优化内核相关参数配置文件/etc/sysctl.conf配置方法直接将参数添加进文件每条一行.sysctl-a可以查看默认配置sysctl-p执行并检测是否有错误例如设置错了参数:[roo...

如何在 Linux 中使用 Sysctl 命令?

sysctl是一个用于配置和查询Linux内核参数的命令行工具。它通过与/proc/sys虚拟文件系统交互,允许用户在运行时动态修改内核参数。这些参数控制着系统的各种行为,包括网络设置、文件...

取消回复欢迎 发表评论: