redis实战-添加商户缓存

为什么要使用缓存

  • 言简意赅:速度快,好用
  • 缓存数据存储于代码中,而代码运行在内存中,内存的读写性能远高于磁盘,缓存可以大大降低用户访问并发量带来的服务器读写压力
  • 实际开发中,企业的数据量,少则几十万,多则几千万,这么大的数据量,如果没有缓存来作为避震器系统是几乎撑不住的,所以企业会大量运用缓存技术
  • 但是缓存也会增加代码复杂度和运营成本
  • 缓存的作用
    1.降低后端负载
    2.提高读写效率,降低响应时间
  • 缓存的成本
    1.数据一致性成本
    2.代码维护成本
    3.运维成本(一般采用服务器集群,需要多加机器,机器就是钱)
    在这里护主要说redis缓存

图解

先从Redis中查询,如果没有查到,再去MySQL中查询,同时查询完毕之后,将查询到的数据也存入Redis,这样当下一个用户来进行查询的时候,就可以直接从Redis中获取到数据
在这里插入图片描述

商户缓存流程

  • 代码思路:如果Redis缓存里有数据,那么直接返回,如果缓存中没有,则去查询数据库,然后存入Redis
    在这里插入图片描述

缓存更新策略

  • 缓存更新是Redis为了节约内存而设计出来的一个东西,主要是因为内存数据宝贵,当我们想Redis插入太多数据,此时就可能会导致缓存中数据过多,所以Redis会对部分数据进行更新,或者把它成为淘汰更合适
  1. 内存淘汰:Redis自动进行,当Redis内存大道我们设定的max-memery时,会自动触发淘汰机制,淘汰掉一些不重要的数据(可以自己设置策略方式)
  2. 超时剔除:当我们给Redis设置了过期时间TTL之后,Redis会将超时的数据进行删除,方便我们继续使用缓存
  3. 主动更新:我们可以手动调用方法把缓存删除掉,通常用于解决缓存和数据库不一致问题
    在这里插入图片描述

数据库和缓存不一致解决方案

由于我们的缓存数据源来自数据库,而数据库的数据是会发生变化的,因此,如果当数据库中数据发生变化,而缓存却没有同步,此时就会有一致性问题存在,其后果是

  • 用户使用缓存中的过时数据,就会产生类似多线程数据安全问题,从而影响业务,产品口碑等

那么如何解决这个问题呢?有如下三种方式

  1. Cache Aside Pattern 人工编码方式:缓存调用者在更新完数据库之后再去更新缓存,也称之为双写方案主要方案
  2. Read/Write Through Pattern:缓存与数据库整合为一个服务,由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。但是维护这样一个服务很复杂,市面上也不容易找到这样的一个现成的服务,开发成本高
  3. Write Behind Caching Pattern:调用者只操作缓存,其他线程去异步处理数据库,最终实现一致性。但是维护这样的一个异步的任务很复杂,需要实时监控缓存中的数据更新,其他线程去异步更新数据库也可能不太及时,而且缓存服务器如果宕机,那么缓存的数据也就丢失了

综上所述,在企业的实际应用中,还是方案一最可靠,但是方案一的调用者该如何处理呢?

在这里插入图片描述
三个问题:
1. 删除缓存还是更新缓存?
2. 如何保证缓存与数据库的操作同时成功或者失败?
3. 先操作缓存还是先操作数据库?

  1. 删除缓存还是更新缓存?
  • 如果采用方案一,假设我们每次操作完数据库之后,都去更新一下缓存,但是如果中间并没有人查询数据,那么这个更新动作只有最后一次是有效的,中间的更新动作意义不大,所以我们可以把缓存直接删除,等到有人再次查询时,再将缓存中的数据加载出来
    对比删除缓存与更新缓存
    更新缓存:每次更新数据库都需要更新缓存,无效写操作较多
    删除缓存:更新数据库时让缓存失效,再次查询时更新缓存
  1. 如何保证缓存与数据库的操作同时成功/同时失败?
  • 单体系统:将缓存与数据库操作放在同一个事务
  • 分布式系统:利用TCC等分布式事务方案
  1. 先操作缓存还是先操作数据库?
  • 我们来仔细分析一下这两种方式的线程安全问题

  • 先删除缓存,再操作数据库
    删除缓存的操作很快,但是更新数据库的操作相对较慢,如果此时有一个线程2刚好进来查询缓存,由于我们刚刚才删除缓存,所以线程2需要查询数据库,并写入缓存,但是我们更新数据库的操作还未完成,所以线程2查询到的数据是脏数据,出现线程安全问题
    在这里插入图片描述

  • 先操作数据库,再删除缓存
    线程1在查询缓存的时候,缓存TTL刚好失效,需要查询数据库并写入缓存,这个操作耗时相对较短(相比较于上图来说),但是就在这么短的时间内,线程2进来了,更新数据库,删除缓存,但是线程1虽然查询完了数据(更新前的旧数据),但是还没来得及写入缓存,所以线程2的更新数据库与删除缓存,并没有影响到线程1的查询旧数据,写入缓存,造成线程安全问题
    在这里插入图片描述
    虽然这二者都存在线程安全问题,但是相对来说,后者出现线程安全问题的概率相对较低,所以我们最终采用后者先操作数据库,再删除缓存的方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/37074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

找不到mfc100.dll文件怎么办?推荐这7个解决方法快速解决mfc100.dll丢失问题

使用电脑中,会遇到各种各样的问题,比如找不到mfc100.dll,或mfc100.dll丢失导致软件程序无法继续运行,就是日常中比较常见的问题之一,今天我教大家遇到这个mfc100.dll丢失问题时候,要怎么解决,以…

【List集合排序】

List集合排序Demo import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor;import java.util.*;/*** list order demo*/ public class ListOrderDemo {public static void main(String[] args) {List<String> lis…

以太网帧格式是如何识别有效负载类型的

注&#xff1a;机翻&#xff0c;未校对。 识别以太网帧有效负载 Identifying Ethernet Frame Payloads Ethernet frames contain payload data encapsulated within header and trailer fields used to deliver packets over Layer 2 networks. This article provides an ov…

套接字通信类的封装

在掌握了基于TCP的套接字通信流程之后&#xff0c;为了方便使用&#xff0c;提高编码效率&#xff0c;可以对通信操作进行封装&#xff0c;本着有浅入深的原则&#xff0c;先基于C语言进行面向过程的函数封装&#xff0c;然后再基于C进行面向对象的类封装。 1. 基于C语言的封装…

Linux基础篇——学习Linux基本工具安装教程视频链接

本篇文章就是记录一下学习Linux需要用到的基本工具的视频教程链接&#xff0c;方便以后查看 VMware15.5安装 安装视频教程&#xff1a;VMware15.5安装教程 centos7.6安装&#xff08;这个视频教程真的很nice&#xff09; 视频教程&#xff1a;centos7.6 虚拟机克隆、快照、…

ansible 模块扩展

uri模块 在Ansible中&#xff0c;uri模块是一个用于发送HTTP、HTTPS、FTP等请求的模块&#xff0c;可以用于获取网页内容、下载文件、上传文件等。本质上&#xff0c;它是一个HTTP客户端模块。 使用uri模块&#xff0c;需要指定一些参数来定义HTTP请求。下面是一些uri模块的常…

学习平台推荐_菜鸟教程官网

网址&#xff1a; 菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01;菜鸟教程(www.runoob.com)提供了编程的基础技术教程, 介绍了HTML、CSS、Javascript、Python&#xff0c;Java&#xff0c;Ruby&#xff0c;C&#xff0c;PHP , MySQL等各种编程语言的基础知识。 同…

Nginx-2

一、高级配置 1.1网页状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状…

opencv实现surface_matching记录

1 说明 使用的cv版本为4.7.0 , surface_matching功能是附加在contrib中的,并未直接包含在opencv 4.7.0中,因此编译的时候需要考虑contrib。 VS版本为2022, CMake版本为3.30-rc4. 2 编译opencv(含contrib) 参见: Win10 下编译 OpenCV 4.7.0详细全过程,包含xfeatures2…

Open3D (C++) 点云边界提取

边界提取 一、算法原理1、详细流程2、主要函数3、参考文献二、代码实现三、结果展示四、注意事项本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、详细流程 该算法完全复刻自PCL。 2、主要函数 /// \…

算法入门(上)

什么是算法&#xff1f; 算法&#xff08;Algorithm&#xff09;是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 给定一个问题&#xff0c;能够解决这个问题的算法是有很多种的。算式中的问题是千奇百怪…

C++为什么将 0.1f 更改为 0 性能会降低 10 倍

一、浮点数与整数的表示差异 在计算机内部&#xff0c;浮点数和整数的表示方式截然不同。浮点数遵循IEEE 754标准&#xff0c;通过符号位、指数位和尾数位来存储和表示数值&#xff0c;而整数则是直接的二进制表示。这种表示上的差异导致了它们在内存占用、处理速度以及精度上…

Debian/Ubuntu Linux安装OBS

先决条件 建议使用 xserver-xorg 1.18.4 或更新版本&#xff0c;以避免 OBS 中某些功能&#xff08;例如全屏投影仪&#xff09;出现潜在的性能问题。在 Linux 上使用 OBS Studio 需要 OpenGL 3.3&#xff08;或更高版本&#xff09;支持。在终端中输入以下内容来检查系统支持…

Halcon测量助手

模糊测量:基于模糊逻辑 模糊逻辑&#xff1a;模仿人脑的不确定性概念判断、推理思维方式&#xff0c;对于模型未知或不能确定的描述系统&#xff0c;以及强非线性、大滞后的控制对象&#xff0c;应用模糊集合和模糊规则进行推理&#xff0c;表达过渡性界限或定性知识经验&…

MySQL基础进阶:编写复杂查询

编写复杂查询 1. 子查询2. IN运算符3. 子查询VS连接4. ALL关键字5. ANY关键字6. 相关子查询7. EXISTS运算符8. SELECT子句中得子查询9. FROM子句中得子查询 1. 子查询 子查询&#xff1a; 任何一个充当另一个SQL语句的一部分的 SELECT 查询语句都是子查询&#xff0c;子查询是…

GMSB文章八:微生物中介分析

欢迎大家关注全网生信学习者系列&#xff1a; WX公zhong号&#xff1a;生信学习者Xiao hong书&#xff1a;生信学习者知hu&#xff1a;生信学习者CDSN&#xff1a;生信学习者2 介绍 中介分析&#xff08;Mediation Analysis&#xff09;是一种统计方法&#xff0c;用于研究一…

C# Benchmark

创建控制台项目&#xff08;或修改现有项目的Main方法代码&#xff09;&#xff0c;Nget导入Benchmark0.13.12&#xff0c;创建测试类&#xff1a; public class StringBenchMark{int[] numbers;public StringBenchMark() {numbers Enumerable.Range(1, 20000).ToArray();}[Be…

大语言模型(LLMs)全面学习指南,初学者入门,一看就懂!

大语言模型&#xff08;LLMs&#xff09;作为人工智能&#xff08;AI&#xff09;领域的一项突破性发展&#xff0c;已经改变了自然语言处理&#xff08;NLP&#xff09;和机器学习&#xff08;ML&#xff09;应用的面貌。这些模型&#xff0c;包括OpenAI的GPT-4o和Google的gem…

杨幂跨界学术圈:内容营销专家刘鑫炜带你了解核心期刊的学术奥秘

近日&#xff0c;知名艺人杨幂在权威期刊《中国广播电视学刊》上发表了一篇名为《浅谈影视剧中演员创作习惯——以电视剧<哈尔滨一九四四>为例》的学术论文&#xff0c;此举在学术界和娱乐圈均引起了广泛关注。该期刊不仅享有极高的声誉&#xff0c;还同时被北大中文核心…

数据库-数据完整性-用户自定义完整性实验

NULL/NOT NULL 约束&#xff1a; 在每个字段后面可以加上 NULL 修饰符来指定该字段是否可以为空&#xff1b;或者加上 NOT NULL 修饰符来指定该字段必须填上数据。 DEFAULT约束说明 DEFAULT 约束用于向列中插入默认值。如果列中没有规定其他的值&#xff0c;那么会将默认值添加…