• 缓存雪崩如何解决?

  • 缓存穿透如何解决?

  • 如何确保Redis缓存的都是热点数据?

  • 如何更新缓存数据?

  • 如何处理请求倾斜?

  • 实际业务场景下,如何选择缓存数据结构

缓存雪崩
缓存雪崩简单说就是所有请求都从缓存中拿不到数据,比如大批量数据同一时间过期。对于大批量数据同时过期的场景,可以为数据设置过期时间指定一个时间范围内的随机值,比如一天到一天零一小时之间的随机值,但不适用于集合类型,比如hash。
还有小数场景,比如高峰流量导致Redis集群崩溃;未配置持久化的redis无从节点Cluster集群重启、集群迁移。当Redis集群发生故障时,可先启用内存缓存方案,比如Ehcache,同时根据情况做限流与降级,最后快速重启集群,必须配置持久化策略,根据流量情况扩展集群。
缓存穿透
缓存穿透简单理解就是数据库中也没有对应的记录,永远都不会命中缓存。比如表中的记录只有id从1000到100000,请求查询id为10000000的记录。一般是恶意攻击,针对这种情况最好的处理方式就是判断id的有效范围,其它情况可以针对查询的key缓存一个null值,并设置ttl过期时间。
如何确保Redis缓存的都是热点数据
A、为key设置ttl过期时间
适用于对实时性要求不高的业务场景;适用于可以容忍获取到的是过期数据的业务场景。过期时间会在每次读写key时刷新。为确保缓存中不遗留垃圾数据,一般都会为key设置过期时间,除了那些不会改变且一直会用到,也不会更新的数据,比如笔者前几篇文章提到的IP库。
B、选择缓存淘汰策略
选择淘汰最近最少使用的缓存淘汰策略可以保证缓存中都是热点数据,但这个策略只会在内存吃紧的情况下起效果,一般要保证缓存的数据都是热点数据就是在redis内存不够用的情况下。建议及时做缓存数据清理,依靠缓存淘汰策略的时候性能也会有所下降。
C、缓存访问次数,定时清除访问次数少的记录
比如用Sorted Set缓存key的读次数,周期性的去删除访问次数小于多少的key。适用于hash等集合类型,计录field的读次数,缺点是每次请求都有统计次数的性能开销。
如何更新缓存数据
A、在数据库修改记录时使用MQ队列通知更新
适用于那种比较少改动的缓存记录,比如用户信息;适用于要求数据修改及时更新缓存的业务场景,如一些配置的修改要求及时生效。但不适用于要求非常实时的场景,比如商品库存。
B、在修改数据库记录时直接更新缓存
这种方法与前一种方法都可利用AOP方式去更新,区别在于,前者解决多个服务之间的耦合问题,用于跨服务数据更新。小公司为考虑成本问题不会为每个服务使用独立的Redis集群,后者只能用于单个服务内的数据更新。即便是多个微服务使用同一个Redis集群,也不要通过共用key的方式共享缓存,否则耦合性太大,容易出问题。
C、定时任务批量更新
配合ttl使用,ttl的时间设置比定时任务周期长一点,避免数据过期了新的任务还没执行完成。适用于实时性要求不是很高,且短时间内大量数据更新的业务场景。比如数据库有10w数据,每15分钟都会有百分七八十的数据变更,且变更时间只在一分钟内。
如果是集合类型、Hash类型,一般会配合Rename使用,只有所有数据写入到redis成功,才原子性替换旧数据。且数据量大的情况下使用pipeline批量写入,避免使用hmset这类批量操作。使用hash这类集合类型时,一定要考虑到脏数据的问题。
如何处理请求倾斜问题
Cluster分槽会导致缓存数据倾斜,从而导致请求倾斜。假设一个三个小主从的Cluster集群,平均分配槽位,大量的key落到第二个节点上,导致请求都偏向第二个节点。导致这个问题的主要原因是,大量key为hash、set、sorted sort类型,且每个集合数据量都比较大。其次是HashTag的不合理使用。
解决方案,一是将大hash分段存储,二是减少HashTag的使用,三是重新分配槽位,将第二个节点的槽位根据实际情况分配一些给其它两个节点。
实际业务场景下,如何选择缓存数据结构
拿我最熟悉的广告行业,举几个简单例子。
a、判断一个广告单是否过期
使用hash、bitmap都可实现。bitmap适用于判断true or false的业务需求。bitmap的读写速度都优于hash,且内存占用少。但出于其它需求,我选择hash。bitmap用于其它业务需求,如快速判断offer每日展示数是否达到上限。
b、统计每个渠道的拉取广告次数
简单的key-value以及hash都支持incr自增,且操作原子性。为减少缓存中key的数据,我选择hash,同时也因为hash支持hgetall,用于实时统计以及方便问题排查。
c、根据标签限CAP
Capacity,即容量,如根据国家、城市、渠道、广告主等标签限制广告的展示次数,一个广告可能同时会匹配到多个标签,当达到最小Capacity时,即判定为true。通过Sorted Set存储一个广告匹配的所有标签,根据当前展示次数通过zcount获取匹配的标签总数,判断zcount结果是否大于零即可。
d、过滤每日重复ip
如用于过滤短时间内重复点击广告的用户,只是举个例子。这时就可以利用HyperLogLog存储IP,HyperLogLog会过滤重复数据,准确率有误差,但对业务影响甚微。
仅为个人观点,假设你是面试者,欢迎留言写下你的答案!

原文地址:https://mp.weixin.qq.com/s/-aOHMe3uOqiJt2Km4fkwGg

缓存雪崩、穿透如何解决,如何确保Redis只缓存热点数据?的更多相关文章

  1. 面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题

    今天来分享一下Redis几道常见的面试题: 如何解决缓存雪崩? 如何解决缓存穿透? 如何保证缓存与数据库双写时一致的问题? 一.缓存雪崩 1.1什么是缓存雪崩? 回顾一下我们为什么要用缓存(Redis ...

  2. (转)面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题

    背景:redis问题在面试过程中经常被问到,对于常见问题一定不能放过. 面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题 一.缓存雪崩 1.1什么是缓存雪崩? 如果缓存数据设置的过 ...

  3. 什么是redis的缓存雪崩, 穿透, 击穿?

    目前的互联网系统没有几个不使用缓存的, 但是只要使用缓存的话就会面临这几个问题, 如使用redis缓存技术, 可能会遇到缓存的雪崩, 穿透, 以及击穿. 首先来看一个简单的正常缓存流程: 如用户访问J ...

  4. PHP之缓存雪崩,及解决方法(转)

    一.什么是缓存雪崩缓存雪崩就是指缓存由于某些原因(比如 宕机.cache服务挂了或者不响应)整体crash掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难. 下面的就是一个 ...

  5. memcached缓存雪崩现象及解决办法

    1)什么是缓存雪崩?场景:一个访问很大的文章(论坛之类)的网站,使用memcached缓存用户查询过的文章.设置的缓存过期时间为6小时,所以没过6小时,缓存就会失效并重建一遍 问题:过六小时时,一部分 ...

  6. 如何确保redis中都是热数据

    相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略. redis 提供 6种数据淘汰策略: voltile-lru:从已设置过期时间的数据集(server.db[i].ex ...

  7. Redis分布式缓存剖析及大厂面试精髓v6.2.6

    概述 官方说明 Redis官网 https://redis.io/ 最新版本6.2.6 Redis中文官网 http://www.redis.cn/ 不过中文官网的同步更新维护相对要滞后不少时间,但对 ...

  8. 从Redis分布式缓存实战入手到底层原理分析、面面俱到覆盖大厂面试考点

    概述 官方说明 Redis官网 https://redis.io/ 最新版本6.2.6 Redis中文官网 http://www.redis.cn/ 不过中文官网的同步更新维护相对要滞后不少时间,但对 ...

  9. redis缓存雪崩,缓存穿透,缓存击穿的解决方法

    一.缓存雪崩 缓存雪崩表示在某一时间段,缓存集中失效,导致请求全部走数据库,有可能搞垮数据库,使整个服务瘫痪. 使缓存集中失效的原因: 1.redis服务器挂掉了. 2.对缓存数据设置了相同的过期时间 ...

随机推荐

  1. SPC软控件提供商NWA的产品在各行业的应用(石油天然气行业)

    Northwest Analytical (NWA)是全球领先的“工业4.0”制造分析SPC软件控件提供商.产品(包含: NWA Quality Analyst , NWA Focus EMI 和 N ...

  2. maven 学习---Maven添加远程仓库

    默认情况下,Maven从Maven中央仓库下载所有依赖关系.但是,有些库丢失在中央存储库,只有在Java.net或JBoss的储存库远程仓库中能找到. 1. Java.net资源库 添加Java.ne ...

  3. odoo10学习笔记十一:视图综述

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189322.html 一:视图标签等公共结构 name (必选) 用于通过名字查找标签 model: 与v ...

  4. linux7系统进入单用户模式

    1.重启系统,在出现选择内核界面的时候按“e”键 2.移动光标到红色找到LANG=zh_CN.UTF-8 增加“init=/sysroot/bin/sh” 修改后如下图 3.使用"ctrl+ ...

  5. requests---requests简介

    在做接口测试的时候都会用到很多工具,如postman.jmeter.soupUI等工具,除了这些工具外,我们也可以用python的第3方库requests来做接口测试. request简介 reque ...

  6. Ubuntu下部署Shipyard管理docker

    使用k8s对于我这种新人来说,难度有点大.遂尝试使用Shipyard这个docker web ui工具来进行管理,以方便入门. 首先,我们还是需要在我们的主机上安装docker. 然后官方提供了自动安 ...

  7. pytest文档30-功能用例与自动化用例完美对接(allure)

    前言 做自动化做久了,经常会思考一个问题,到底别人是怎么做的自动化,跟自己的有啥不一样,看过不少书和资料,都是停留在demo的层面. 真正把自动化做的好的大牛又不屑于分享自己的劳动成果,所以大部分情况 ...

  8. Js中的对象、构造函数、原型、原型链及继承

    1.对象 在传统的面向过程的程序设计中,会造成函数或变量的冗余.而JS中对象的目的是将所有的具有相同属性或行为的代码整合到一起,形成一个集合,这样就会方便我们管理,例如: var person1={  ...

  9. 201871010117-石欣钰 《面向对象程序设计(Java)》第十周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  10. 使用angularJS接收json数据并进行数据的显示

    1.引入JS <script type="text/javascript" src="../plugins/angularjs/angular.min.js&quo ...