Redis(1.8)Redis与mysql的数据库同步(缓存穿透与缓存雪崩)
【1】缓存穿透与缓存雪崩
【1.1】缓存和数据库间数据一致性问题
分布式环境下(单机就不用说了)非常容易出现缓存和数据库间的数据一致性问题,针对这一点的话,只能说,如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存。
我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。
合适的策略包括 合适的缓存更新策略,更新数据库后要及时更新缓存、缓存失败时增加重试机制,例如MQ模式的消息队列。
【1.2】缓存击穿(缓存穿透)问题
缓存击穿表示恶意用户模拟请求很多缓存中不存在的数据(数据库也不存在,导致查询为null),由于缓存中都没有,导致这些请求短时间内直接落在了数据库上,导致数据库异常。
这个我们在实际项目就遇到了,有些抢购活动、秒杀活动的接口API被大量的恶意用户刷,导致短时间内数据库宕机了,好在数据库是多主多从的,hold住了。
把数据库查询为null的情况,也缓存到redis中去,给其 key 赋值 '' 空,到时候在程序里再次查询的时候,该key就存在了,直接返回空字符串或Null给查询端。
使用互斥锁排队
业界比价普遍的一种做法,即根据key获取value值为空时,锁上,从数据库中load数据后再释放锁。若其它线程获取锁失败,
则等待一段时间后重试。这里要注意,分布式环境中要使用分布式锁,单机的话用普通的锁(synchronized、Lock)就够了
布隆过滤器(推荐)
bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。
【1.3】缓存雪崩问题
缓存在同一时间内大量键过期(失效),接着来的一大波请求瞬间都落在了数据库中导致连接异常。
解决方案:
1、也是像解决缓存穿透一样加锁排队,实现同上;
2、建立备份缓存,缓存A和缓存B,A设置超时时间,B不设值超时时间,先从A读缓存,A没有读B,并且更新A缓存和B缓存;
【1.4】缓存并发问题
这里的并发指的是多个redis的client同时set key引起的并发问题。比较有效的解决方案就是把redis.set操作放在队列中使其串行化,必须的一个一个执行,具体的代码就不上了,当然加锁也是可以的,至于为什么不用redis中的事务,留给各位看官自己思考探究。
【2】Redis与Mysql数据同步解决方案
方案1(普通)
读:读redis,没有数据就读mysql,将MySQL数据保存到缓存中。
写:写mysql,同时让redis缓存失效(删除key,过期)
缺点:数据量巨大,更新频繁的数据写入无能为力。比如数量巨大,每个变跟状态又很频繁,这样很容易把数据库写挂。
方案2(binlog)
基于binlog使用mysql_udf_redis,将数据库中的数据同步到Redis。
缺点: mysql_udf_redis是有人实现的同步数据到Redis的功能,需要学习成本,第三方的插件不稳定。
方案3(MQ或定时任务)
MQ.队列同步,变跟数据2份,使用消息队列,一份给Redis消费,一份给Mysql消费。
定时任务 后台定时任务,定时刷新Redis中信息到数据库。
【2.1】数据库与缓存读写模式策略
【2.2】数据库与缓存双写情况下导致数据不一致问题
场景一
场景一解决方案
场景二
场景二解决方案
这里有一个优化点,如果发现队列里有一个查询请求了,那么就不要放新的查询操作进去了,用一个while(true)循环去查询缓存,循环个200MS左右,如果缓存里还没有则直接取数据库的旧数据,一般情况下是可以取到的。
(1)读请求时长阻塞
由于读请求进行了非常轻度的异步化,所以一定要注意读超时的问题,每个读请求必须在超时间内返回,该解决方案最大的风险在于可能数据更新很频繁,导致队列中挤压了大量的更新操作在里面,然后读请求会发生大量的超时,最后导致大量的请求直接走数据库,像遇到这种情况,一般要做好足够的压力测试,如果压力过大,需要根据实际情况添加机器。
(2)请求并发量过高
这里还是要做好压力测试,多模拟真实场景,并发量在最高的时候QPS多少,扛不住就要多加机器,还有就是做好读写比例是多少
(3)多服务实例部署的请求路由
可能这个服务部署了多个实例,那么必须保证说,执行数据更新操作,以及执行缓存更新操作的请求,都通过nginx服务器路由到相同的服务实例上
(4)热点商品的路由问题,导致请求的倾斜
某些商品的读请求特别高,全部打到了相同的机器的相同丢列里了,可能造成某台服务器压力过大,因为只有在商品数据更新的时候才会清空缓存,然后才会导致读写并发,所以更新频率不是太高的话,这个问题的影响并不是很大,但是确实有可能某些服务器的负载会高一些。
参考:
Redis缓存穿透、缓存雪崩、redis并发问题分析
redis做mysql的缓存,怎么把redis数据和mysql数据同步?
Redis(1.8)Redis与mysql的数据库同步(缓存穿透与缓存雪崩)的更多相关文章
- redis与mysql性能对比、redis缓存穿透、缓存雪崩
写在开始 redis是一个基于内存hash结构的缓存型db.其优势在于速读写能力碾压mysql.由于其为基于内存的db所以存储数据量是受限的. redis性能 redis读写性能测试redis官网测试 ...
- Redis缓存雪崩、缓存穿透、缓存击穿、缓存降级、缓存预热、缓存更新
Redis缓存能够有效地加速应用的读写速度,就DB来说,Redis成绩已经很惊人了,且不说memcachedb和Tokyo Cabinet之流,就说原版的memcached,速度似乎也只能达到这个级别 ...
- Redis缓存穿透、缓存雪崩、缓存击穿好好说说
前言 Redis是目前非常流行的缓存数据库啦,其中一个主要作用就是为了避免大量请求直接打到数据库,以此来缓解数据库服务器压力:用上缓存难道就高枕无忧了吗?no,no,no,没有这么完美的技术, 缓存穿 ...
- Redis缓存穿透、缓存击穿以及缓存雪崩
作为一个内存数据库,redis也总是免不了有各种各样的问题,这篇文章主要是针对其中三个问题进行讲解:缓存穿透.缓存击穿和缓存雪崩.并给出一些解决方案.这三个问题是基本问题也是面试常问问题. 这篇文章我 ...
- Redis 缓存击穿(失效)、缓存穿透、缓存雪崩怎么解决?
原始数据存储在 DB 中(如 MySQL.Hbase 等),但 DB 的读写性能低.延迟高. 比如 MySQL 在 4 核 8G 上的 TPS = 5000,QPS = 10000 左右,读写平均耗时 ...
- 一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.简述MySQL中索引类型对数据库的性能的影响 2.RDB和AOF机制 3.Redis的过期键的删除策略 4.Redis ...
- Redis缓存穿透和缓存雪崩以及解决方案
Redis缓存穿透和缓存雪崩以及解决方案 Redis缓存穿透和缓存雪崩以及解决方案缓存穿透解决方案布隆过滤缓存空对象比较缓存雪崩解决方案保证缓存层服务高可用性依赖隔离组件为后端限流并降级数据预热缓存并 ...
- 预防Redis缓存穿透、缓存雪崩解决方案
最近面试中遇到redis缓存穿透.缓存雪崩等问题,特意了解下. redis缓存穿透: 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有.这样就导致用户查询的时候,在缓存中找不到,每次都要去 ...
- Redis 缓存穿透,缓存击穿,缓存雪崩的解决方案分析
设计一个缓存系统,不得不要考虑的问题就是:缓存穿透.缓存击穿与失效时的雪崩效应. 一.什么样的数据适合缓存? 分析一个数据是否适合缓存,我们要从访问频率.读写比例.数据一致性等要求去分析. 二.什么 ...
随机推荐
- 【线性代数】Linear Algebra Big Picture
Abstract: 通过学习MIT 18.06课程,总结出的线性代数的知识点相互依赖关系,后续博客将会按照相应的依赖关系进行介绍.(2017-08-18 16:28:36) Keywords: Lin ...
- 阿里云Ubuntu安装LNMP环境之PHP7
在QQ群很多朋友问阿里云服务器怎么安装LNMP环境,怎么把项目放到服务器上面去,在这里,我就从头开始教大家怎么在阿里云服务器安装LNMP环境. 在这之前,我们先要知道什么是LNMP. L: 表示的是L ...
- node中fs内置模块
Node.js内置的fs模块就是文件系统模块,负责读写文件. 和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法. 回顾一下什么是异步方法.因为JavaScript的单线程 ...
- 7.19T2
小 B 的树 题目背景及题意 小 B 有一颗树,它的形态与 OI 中的树相同,有 n 个节点,n-1 条边,每条边长度为 1 随着时间的流逝这棵树长大了,每条边有 50%的概率长度变为 2 小 B ...
- single-pass单遍聚类方法
一.通常关于文本聚类也都是针对已有的一堆历史数据进行聚类,比如常用的方法有kmeans,dbscan等.如果有个需求需要针对流式文本进行聚类(即来一条聚一条),那么这些方法都不太适用了,当然也有很多其 ...
- bat 通过命令以管理员方式运行程序
@echo off mode con lines= cols= % mshta vbscript:CreateObject()(window.close)&&exit cd /d &q ...
- linux下编译利用CMakeLists.txt 编译C++写的opencv程序
https://hihozhou.com/blog/2017/05/11/linux-compile-opencv-c++-file.html cmake . make -j8
- php 中 使用foreach为数组增加键值对
php 中的 foreach 在php中,使用foreach来遍历数组的频率很高,并且其性能要高于 list() 和 each() 结合来遍历数组: 当遍历二位数组的第一层数组,并要给第二位数组增加一 ...
- 4.Java JSON使用
Java 中 JSON 的使用 分类 编程技术 本章节我们将为大家介绍如何在 Java 语言中使用 JSON. 类库选择 Java中并没有内置JSON的解析,因此使用JSON需要借助第三方类库. 下面 ...
- 禁用显示GC 会有什么问题?-XX:+DisableExplicitGC
-XX:+DisableExplicitGC