0.学习准备:
参考资料
参考视频:慕课网教程《Redis从入门到高可用》
参考教程:http://www.redis.net.cn/tutorial/3501.html
Redis命令参考手册:http://redisdoc.com/
w3cschoolRedis教程:https://www.w3cschool.cn/redis/nma27f21.html
参考博客:
https://blog.csdn.net/sunhuiliang85/article/details/74800001?utm_source=gold_browser_extension记录一些动力节点的视频未涉及到的知识点。
- 缓存的使用与设计:
- 缓存的受益与成本
- 缓存更新策略
- 缓存的粒度控制
- 使用过程中出现的一些问题及优化:
- 缓存穿透优化
- 无底洞问题优化
- 缓存雪崩优化(视频错乱,买书再补充)
- 热点key重建优化
- CacheCloud云平台
- Redis规模化运维
- 快速构建
- 机器部署
- 应用接入
- 用户功能
- 运维功能
1.缓存的受益与成本
主要介绍三个方面:
- 收益
- 成本
- 使用场景
1)收益:
- 加速读写:
通过缓存加速读写速度:CPU L1/L2/L3Cache、Linux Page Cache加速硬盘读写、浏览器缓存、Ehcache缓存数据库结果。 - 降低后端负载:
后端服务器通过前端降低负载:业务端使用Redis降低后端MySQL负载等
2)成本:
- 数据不一致:
缓存层和数据层有时间窗口的不一致,和缓存的更新策略有关。 - 代码维护成本会变高:
多了一层缓存逻辑。 - 运维成本:Redis Cluster需要额外的维护
经济成本,人力成本
3)使用场景:
- 降低后端负载:
对高消耗的SQL:join结果集,分组统计结果缓存。 - 加速请求响应:
利用Redis/Memcache加速I/O响应时间。 - 将大量的写合并为批量写:
如计数器累加再批量写入DB。
2.缓存的更新策略与粒度控制
有时候缓存的数据和数据库的数据不一致(如上面的计数器),而缓存需要进行定时的刷新来保证空间的可用性(删除某些key)。
1)缓存更新策略:
- LRU/LFU/FIFO算法剔除:如maxmemory-policy
不需要关系实现细节,Redis会自动帮助我们删除。 - 超时剔除:设置key的expire(过期时间)。
比如某些不重要的信息。 - 主动更新:开发控制声明周期
数据库更新某些重要信息之后主动更新缓存的信息。 - 三种缓存策略之间的比较:
2)关于更新策略的建议:
- 低一致性要求时:缓存中的数据的一致性要求不是那么高
最大内存淘汰策略:maxmemory-policy
但是一般应用都不会对一致性要求过低。 - 高一致性要求:(建议使用这一种)
超时剔除和主动更新为主,最大内存和淘汰策略兜底。
3)缓存粒度简介:
- Redis缓存的使用原理图:
- 模拟基本流程:
- 1.从MySQL中获取用户信息:
select * from user where id={id}
- 2.设置用户缓存:
set user:id 'select * from user where id={id}'
- 1.从MySQL中获取用户信息:
- 缓存的粒度:
如上,缓存的到底是select *
还是仅仅是需要的一些属性。 - 粒度控制从三个角度去考虑:
- 通用性:全量属性会更好
- 占用空间:部分属性更好
- 代码维护上:表面上看全量属性会更好
- 从大部分应用来看:
选择部分属性可能会更好,很多时候不用去考虑扩展性,而是缓存的优化。 - 选择粒度需要综合去考虑。
3.缓存穿透问题与优化
1)缓存穿透问题介绍、原因与发现:
- 缓存穿透:
大量请求不命中,数据直接从存储层读取,使缓存失去了保护存储层的意义。
简单示意图: - 产生的原因:
- 业务代码自身的问题
- 恶意攻击或者爬虫等(一个不存在的URL)
- 如何发现:
- 业务响应时间:监控系统()
- 业务本身的一些问题:产品的代码出现一些问题
- 相关指标:
总调用数,存储层调用数,缓存层命中数,存储命中数等。
2)缓存穿透的优化:
- 解决方法一:缓存空对象
如果对象不存在,或者出于某些原因不可用,那么就把空对象作为结果保存到缓存中 - 解决方案一会出现的两个问题及解决:
- 需要更多的键来保存空对象:
解决:一般会设置key的过期时间 - 缓存和存储层数据短暂的不一致:数据层(接口)短暂不停供服务
解决:订阅数据层或接口的消息,使其恢复服务时更新缓存
- 需要更多的键来保存空对象:
- 解决方法二:布隆过滤器拦截
在缓存之前再做一层布隆过滤器拦截,如果被过滤掉了则说明请求失败。
优点是可以使用一个很小的内存来是实现数据的过滤。 - 布隆过滤器方式的注意事项:
对于数据比较固定的情况会比较好。
数据经常改变时可能不是一个很好的选择。
4.缓存无底洞问题的优化
1)无底洞问题介绍:
- 无底洞问题的发现:
2010年,FaceBook有3000个memcache节点,发现加机器后性能没有提升,反而下降了。机器越多,性能下降越多。 - 产生该问题原因:批量操作的变化
一次mget的操作随着机器的增加,网络时间也会增加。
当然这只对节点非常多的情况下有很大影响。 - 问题的关键点:
更多的机器!=更多的性能
批量接口需求(mget.mset等)
数据增长与水平扩展需求
2)无敌洞问题优化(优化I/O):
- 命令本身的优化:减少使用慢查询及hgetall bigkey等这种命令
- 优化网络时间:减少网络通信时间(Redis这种命令执行很快的主要优化这个)
具体一点可以查看前面的集群中的批量操作。
(在Mysql这种命令执行较慢的数据库中一般会去选择优化SQL语句本身) - 降低客户端连接成本:长连接,连接池,NIO(非阻塞IO)等。
5.热点key的重建优化
1)问题简介:
- 问题出现:
在重建时有大量的数据访问缓存,大量的线程都进行查询数据与缓存重建,对数据库数据源有很大的压力,会减缓IO的时间。 - 三个目标:
- 减少重建缓存的次数
- 数据尽可能一致
- 减少潜在的危险
2)两个解决方案:
- 两个解决方案:
- 互斥锁
- 永不过期
- 互斥锁示意图:
在进行查询及重建的过程中其他线程阻塞。 - 互斥锁的简单代码:
- 永远不过期方案:
缓存层面:不会设置key的expire过期时间
功能层面:为每个value添加一个逻辑过期时间,额外创建一个单独的线程来管理逻辑过期时间,如果超过了这个过期时间则进行重建。
(会出现数据不一致的情况,但是不会阻塞线程) - 永远不过期的示意图:
- 两种方案的对比:
6.CacheCloud云平台
CacheCloud目录
- Redis规模化运维
- 快速构建
- 机器部署
- 应用接入
- 用户功能
- 运维功能
规模化运维问题及快速构建
1)规模化运维的问题与CacheCloud简介:
- 大规模Redis运维会遇到的问题:
发布构建繁琐,私搭乱盖
节点,机器等的运维成本
监控报警比较低级 - CacheCloud的功能:
- 一键开启Redis(Standlong、Sentinel、Cluster)
- 机器、应用、实例监控和报警。
- 客户端:使用透明,性能上报。
- 可视化运维:配置、扩容、Failover、机器/应用/实例上下线。
- 已存在Redis直接迁入和数据迁移。
- 地址:https://github.com/sohutv/cachecloud
2)CacheCloud快速构建:
构建比较麻烦,需要Liunx下的MySQL以及Tomcat的支持,而我的Linux下并没有装这些软件,所以先搁在这里。以后买书了再来学习。
最后更新: 2018年04月29日 15:51
原始链接: https://zjxkenshine.github.io/2018/04/29/Redis学习笔记(十):缓存的使用与优化/