Redis之缓存设计
一 缓存的收益和成本
1.1 优点
加速读写;降低后端负载
1.2成本
# 数据不一致性:缓存层和存储层的数据存在着差异
# 代码维护成本:同时维护缓存层和存储层的逻辑
缓存的使用场景:
# 开销大的复杂计算:比如MySQL一些复杂的操作或者计算,如果不加缓存,MySQL在并发量大的时候,可能扛不住
# 加速请求响应
二 缓存的更新策略
2.1 LRU/LFU/FIFO 算法剔除
一般算法剔除是指缓存数目超过了指定 的预设值,如何对现有缓存的数据进行剔除。比如最近很少的缓存项,比如最近频繁使用的缓存想,或者先进的先踢出来
2.2 超时剔除
一般是给缓存数据设置过期时间,让其在过期后自动删除。
2.3 主动更新
一般是指对数据一致性要求较高,需要在真实数据更新后,立即更新缓存数据,当然维护成本比较高。
2.4 最佳实践
# 低一致性业务建议配置最大内存和淘汰策略
# 高一致性业务建议结合使用超时剔除和主动更新
三 穿透优化
缓存穿透:是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常我们不会将存储层查不到的数据写入缓存。
缓存穿透将导致不存在的数据每一次请求都会到存储层去查询,失去了缓存保护后端存储的意义,有可能导致后端存储负载加大,甚至宕机。
造成缓存穿透的原因,一般都是:
# 开发的代码写的有问题或者数据有问题
# 一些恶意的攻击或者爬虫等造成的空命中
如何解决呢?
方案一:缓存空对象
当缓存和存储层都没有查到的话,就将该数据缓存起来,之后再访问这个数据的时候,就直接从缓存中获取。
但是这样,明显有问题:就是空值做了缓存,那就意味着缓存层很可能缓存更多的key都是对应着空值,那么也就需要更多的内存空间。
方案二:布隆过滤器拦截
在访问缓存层和存储层之前,用布隆过滤器对key进行过滤,做第一层拦截。
四 无底洞
为什么在有的场景,水平添加节点性能不但没有好转反而下降了。这种现象称为缓存的无底洞现象。即更多的节点不代表跟高的性能,投入越多,不一定产出越高。
为什么?
一般来说我们加节点,使得集群的性能应该更好,但是为什么性能反而下降了呢?key-value数据库,一般采用哈希函数将key映射到各个节点,造成key的分布和业务无关,但是由于数据量和访问量的持续增长,造成需要添加大量节点做水平扩容,导致key-value分布到更多的节点上,对于Redis批量操作需要从不同节点获取,相比于单机批量操作只涉及一次网络操作,分布式批量操作会涉及到多次网络时间。
无底洞问题分析:
# 客户端一次批量操作会涉及多次网络操作,就意味着批量操作会随着节点的增多耗时会不断扩大
# 网络连接数变多,对接点的性能也有一定影响
4.1 串行命令
由于key均与分布在集群中各个节点上,因此无法使用mget命令一次性获取,所以通常来讲要获取N个key的值,就是逐次执行N个get命令,这种操作虽然简单,但是时间复杂度增高。他的操作时间=n次网络时间+n次命令时间
public List<String> serialMGet(List<String> keys) {
JedisCluster cluster = getCluster();
List<String> values = new ArrayList<>();
String value = null;
for (String key : keys) {
value = cluster.get(key);
values.add(value);
}
return values;
}
private static JedisCluster getCluster(){
Map<String,Integer> nodes = new HashMap<>();
nodes.put("192.168.3.200",7001);
nodes.put("192.168.3.201",7001);
nodes.put("192.168.3.202", 7001);
return JedisUtils.getJedisCluster(nodes);
}
4.2 串行IO
我们知道,Smart客户端会保存slot和节点的对应关系,有了这两个数据就可以将属于同一个节点的key进行归档,得到每一个节点的key子列表,之后对每一个节点执行mget或者pipeline操作。操作时间 = node次网络时间 + N次命令时间,比第一种方式呢好很多,但是如果节点数太多,还是有一定的问题。
五 雪崩
指的是缓存层由于某些原因挂了,或者不能提供服务,从而导致流量疯狂的涌入了后端存储层,存储层调用暴涨,造成存储层可能会级联宕机。
预防和解决雪崩效应的方案:
# 保证缓存层服务高可用性
# 依赖隔离组件,为后端限流或者降级
无论是缓存还是存储层都有出错的概率,可以将他们都视作资源。作为并发量较大的系统,假如有一个资源不可用,可能会造成线程全部阻塞,从而系统不可用。
降级机制在高并发系统中非常普遍:比如推荐服务,如果个性化推荐不可用,可以降级补充热点数据。在实际项目中,我们对重要的资源比如Redis,MySQL,HBase或者其他外部接口都进行隔离,每一种资源都单独运行在自己的线程池中,对其他服务没有影响。
六 热点key重建优化
缓存+过期策略一般情况下,可以加速读写,又保证了数据定期更新,可以满足大部分需求,但是如果有2个问题同时出现,可能造成较大的危害:
# 当前的key是一个热点key,并发量非常大
# 重建缓存不可能在短时间内完成,可能是一个复杂的SQL或者多次IO等等。
在缓存失效的瞬间,大量线程来重建缓存,造成后端负载加大,甚至崩溃。
方案一:互斥锁
只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据
方案二:永不过期
不设过期时间
Redis之缓存设计相关推荐
- Redis一通百通~P8架构师带你玩转Redis高性能缓存设计实战
前言 高并发十分考验架构师功底,它也是分布式架构设计中必须考虑的因素之一.要知道,光靠服务器堆是没有出路的. 想看看大牛是怎么面对高并发的?想知道BATJ大厂是怎么设计高可用架构的?这里有可参考的实践 ...
- Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理
基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客 QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...
- redis缓存设计要点随谈
在高并发系统中,缓存是必不可少的一部分.没有缓存对系统的加速和阻挡大量的请求直接落到系统的数据库,系统是很难撑住高并发的冲击.所以缓存设计是系统很关键的一环. 1.缓存更新 缓存的数据一般都是有有效期 ...
- 同程旅行王晓波:同程凤凰缓存系统在基于 Redis 方面的设计与实践(上篇)
王晓波 同程旅行机票事业群 CTO 读完需要 12 分钟 速读仅需 4 分钟 本章和大家分享一下同程凤凰缓存系统在基于 Redis 方面的设计与实践.在本章中除了会列举我们工作过程中遇到各种问题和误区 ...
- python文本框与数据库的关联_Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理...
基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客 QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3. ...
- Redis缓存设计(key、value设计)与性能优化(缓存击穿、缓存穿透、缓存雪崩)
一.多级缓存架构 二.缓存设计 1.缓存穿透 缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中, 通常出于容错的考虑, 如果从存储层查不到数据则不写入缓存层. 缓存穿透将导致不存在的数 ...
- Redis缓存设计原理及实战
缓存是什么? 一个系统中的不同层之间的访问速度不一样,所以我们才需要缓存,这样就可以把一些需要频繁访问的数据放在缓存中,以加快它们的访问速度. 为了让你能更好地理解,我以计算机系统为例,来解释一下.下 ...
- 深入理解分布式缓存设计
欢迎关注方志朋的博客,回复"666"获面试宝典 前言 在高并发的分布式的系统中,缓存是必不可少的一部分.没有缓存对系统的加速和阻挡大量的请求直接落到系统的底层,系统是很难撑住高并发 ...
- 从bitmap到布隆过滤器,再到高并发缓存设计策略
点击关注公众号,Java干货及时送达 作者:that_is_cool blog.csdn.net/that_is_cool/article/details/91346356 前言:怎么能把风马牛不相及 ...
最新文章
- ES6 模块化的基本语法——默认导出 与 默认导入、按需导出 与 按需导入、直接导入并执行模块代码
- 前端月趋势榜:6 月新增的、最热门的 20 个前端开源项目 - 2106
- 程序员看过来:阿里毕玄提升代码能力的4段经历
- 业务处理速度变慢?且看IT如何成为救世主
- 修改linux的最大文件句柄数限制
- Find the Difference(leetcode389)
- 自监督学习在CV领域研究进展总结
- 【软考】2020年全国计算机技术与软件专业技术资格考试,软件设计师,考纲
- IDEA14创建Maven管理的Java Web项目
- HOOK(钩子,挂钩)
- python对平面设计有用吗_平面设计有前途吗?
- 转调小程序(练口琴时用的)
- vm虚拟机配置动态ip和静态ip的方法
- SVN如何建立版本库
- 什么是注意力机制及其应用(self attention)?
- 逻辑推理题:海盗分金币
- 炉石传说酒馆战棋一键拔线(windows)
- 性能测试到底该怎么做?
- Django(10)-模板层的变量和标签
- C++内存问题(很多公司面试的题目,值得一看,看懂了别忘了告诉我)
热门文章
- java 多线程取一条记录_java多线程从队列中取出数据执行
- pytorch得到中间层输出
- matlab 全部的随机数函数
- jsp转换java_JSP编码转换
- php升级语言,PHP是最好的语言,PHP 8.0带来了重大更新
- 网上购物软件的测试计划,网上购物平台购物测试计划书
- python中的异或操作_Python中的异或和位操作的反转
- fluent并行 linux_windows 系统下启动linux主机群的fluent并行操作.docx
- php中的变量函数,PHP中的一些路径变量或函数
- linux配置php mysql_Linux下LAMP(Apache+PHP+MySql)环境配置