0.学习准备:

  1. 参考资料
    参考视频:慕课网教程《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

  2. 记录一些动力节点的视频未涉及到的知识点。

  3. 缓存的使用与设计:
    • 缓存的受益与成本
    • 缓存更新策略
    • 缓存的粒度控制
  4. 使用过程中出现的一些问题及优化:
    • 缓存穿透优化
    • 无底洞问题优化
    • 缓存雪崩优化(视频错乱,买书再补充)
    • 热点key重建优化
  5. CacheCloud云平台
    • Redis规模化运维
    • 快速构建
    • 机器部署
    • 应用接入
    • 用户功能
    • 运维功能

1.缓存的受益与成本

主要介绍三个方面:

  • 收益
  • 成本
  • 使用场景

1)收益:

  1. 加速读写:
    通过缓存加速读写速度:CPU L1/L2/L3Cache、Linux Page Cache加速硬盘读写、浏览器缓存、Ehcache缓存数据库结果。
  2. 降低后端负载:
    后端服务器通过前端降低负载:业务端使用Redis降低后端MySQL负载等

2)成本:

  1. 数据不一致:
    缓存层和数据层有时间窗口的不一致,和缓存的更新策略有关。
  2. 代码维护成本会变高:
    多了一层缓存逻辑。
  3. 运维成本:Redis Cluster需要额外的维护
    经济成本,人力成本

3)使用场景:

  1. 降低后端负载:
    对高消耗的SQL:join结果集,分组统计结果缓存。
  2. 加速请求响应:
    利用Redis/Memcache加速I/O响应时间。
  3. 将大量的写合并为批量写:
    如计数器累加再批量写入DB。

2.缓存的更新策略与粒度控制

有时候缓存的数据和数据库的数据不一致(如上面的计数器),而缓存需要进行定时的刷新来保证空间的可用性(删除某些key)。

1)缓存更新策略:

  1. LRU/LFU/FIFO算法剔除:如maxmemory-policy
    不需要关系实现细节,Redis会自动帮助我们删除。
  2. 超时剔除:设置key的expire(过期时间)。
    比如某些不重要的信息。
  3. 主动更新:开发控制声明周期
    数据库更新某些重要信息之后主动更新缓存的信息。
  4. 三种缓存策略之间的比较:

2)关于更新策略的建议:

  1. 低一致性要求时:缓存中的数据的一致性要求不是那么高
    最大内存淘汰策略:maxmemory-policy
    但是一般应用都不会对一致性要求过低。
  2. 高一致性要求:(建议使用这一种)
    超时剔除和主动更新为主,最大内存和淘汰策略兜底。

3)缓存粒度简介:

  1. Redis缓存的使用原理图:
  2. 模拟基本流程:
    • 1.从MySQL中获取用户信息:select * from user where id={id}
    • 2.设置用户缓存:set user:id 'select * from user where id={id}'
  3. 缓存的粒度:
    如上,缓存的到底是select *还是仅仅是需要的一些属性。
  4. 粒度控制从三个角度去考虑:
    • 通用性:全量属性会更好
    • 占用空间:部分属性更好
    • 代码维护上:表面上看全量属性会更好
  5. 从大部分应用来看:
    选择部分属性可能会更好,很多时候不用去考虑扩展性,而是缓存的优化。
  6. 选择粒度需要综合去考虑。

3.缓存穿透问题与优化

1)缓存穿透问题介绍、原因与发现:

  1. 缓存穿透:
    大量请求不命中,数据直接从存储层读取,使缓存失去了保护存储层的意义。
    简单示意图:
  2. 产生的原因:
    • 业务代码自身的问题
    • 恶意攻击或者爬虫等(一个不存在的URL)
  3. 如何发现:
    • 业务响应时间:监控系统()
    • 业务本身的一些问题:产品的代码出现一些问题
    • 相关指标:
      总调用数,存储层调用数,缓存层命中数,存储命中数等。

2)缓存穿透的优化:

  1. 解决方法一:缓存空对象
    如果对象不存在,或者出于某些原因不可用,那么就把空对象作为结果保存到缓存中
  2. 解决方案一会出现的两个问题及解决:
    • 需要更多的键来保存空对象:
      解决:一般会设置key的过期时间
    • 缓存和存储层数据短暂的不一致:数据层(接口)短暂不停供服务
      解决:订阅数据层或接口的消息,使其恢复服务时更新缓存
  3. 解决方法二:布隆过滤器拦截
    在缓存之前再做一层布隆过滤器拦截,如果被过滤掉了则说明请求失败。

    优点是可以使用一个很小的内存来是实现数据的过滤。
  4. 布隆过滤器方式的注意事项:
    对于数据比较固定的情况会比较好。
    数据经常改变时可能不是一个很好的选择。

4.缓存无底洞问题的优化

1)无底洞问题介绍:

  1. 无底洞问题的发现:
    2010年,FaceBook有3000个memcache节点,发现加机器后性能没有提升,反而下降了。机器越多,性能下降越多。
  2. 产生该问题原因:批量操作的变化
    一次mget的操作随着机器的增加,网络时间也会增加。

    当然这只对节点非常多的情况下有很大影响。
  3. 问题的关键点:
    更多的机器!=更多的性能
    批量接口需求(mget.mset等)
    数据增长与水平扩展需求

2)无敌洞问题优化(优化I/O):

  1. 命令本身的优化:减少使用慢查询及hgetall bigkey等这种命令
  2. 优化网络时间:减少网络通信时间(Redis这种命令执行很快的主要优化这个)
    具体一点可以查看前面的集群中的批量操作。
    (在Mysql这种命令执行较慢的数据库中一般会去选择优化SQL语句本身)
  3. 降低客户端连接成本:长连接,连接池,NIO(非阻塞IO)等。

5.热点key的重建优化

1)问题简介:

  1. 问题出现:

    在重建时有大量的数据访问缓存,大量的线程都进行查询数据与缓存重建,对数据库数据源有很大的压力,会减缓IO的时间。
  2. 三个目标:
    • 减少重建缓存的次数
    • 数据尽可能一致
    • 减少潜在的危险

2)两个解决方案:

  1. 两个解决方案:
    • 互斥锁
    • 永不过期
  2. 互斥锁示意图:

    在进行查询及重建的过程中其他线程阻塞。
  3. 互斥锁的简单代码:
  4. 永远不过期方案:
    缓存层面:不会设置key的expire过期时间
    功能层面:为每个value添加一个逻辑过期时间,额外创建一个单独的线程来管理逻辑过期时间,如果超过了这个过期时间则进行重建。
    (会出现数据不一致的情况,但是不会阻塞线程)
  5. 永远不过期的示意图:
  6. 两种方案的对比:

6.CacheCloud云平台

CacheCloud目录

  • Redis规模化运维
  • 快速构建
  • 机器部署
  • 应用接入
  • 用户功能
  • 运维功能

规模化运维问题及快速构建

1)规模化运维的问题与CacheCloud简介:

  1. 大规模Redis运维会遇到的问题:
    发布构建繁琐,私搭乱盖
    节点,机器等的运维成本
    监控报警比较低级
  2. CacheCloud的功能:
    • 一键开启Redis(Standlong、Sentinel、Cluster)
    • 机器、应用、实例监控和报警。
    • 客户端:使用透明,性能上报。
    • 可视化运维:配置、扩容、Failover、机器/应用/实例上下线。
    • 已存在Redis直接迁入和数据迁移。
    • 地址:https://github.com/sohutv/cachecloud

2)CacheCloud快速构建:
构建比较麻烦,需要Liunx下的MySQL以及Tomcat的支持,而我的Linux下并没有装这些软件,所以先搁在这里。以后买书了再来学习。


× 请我吃糖~
打赏二维码