一 缓存的收益和成本

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之缓存设计相关推荐

  1. Redis一通百通~P8架构师带你玩转Redis高性能缓存设计实战

    前言 高并发十分考验架构师功底,它也是分布式架构设计中必须考虑的因素之一.要知道,光靠服务器堆是没有出路的. 想看看大牛是怎么面对高并发的?想知道BATJ大厂是怎么设计高可用架构的?这里有可参考的实践 ...

  2. Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理

    基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客  QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...

  3. redis缓存设计要点随谈

    在高并发系统中,缓存是必不可少的一部分.没有缓存对系统的加速和阻挡大量的请求直接落到系统的数据库,系统是很难撑住高并发的冲击.所以缓存设计是系统很关键的一环. 1.缓存更新 缓存的数据一般都是有有效期 ...

  4. 同程旅行王晓波:同程凤凰缓存系统在基于 Redis 方面的设计与实践(上篇)

    王晓波 同程旅行机票事业群 CTO 读完需要 12 分钟 速读仅需 4 分钟 本章和大家分享一下同程凤凰缓存系统在基于 Redis 方面的设计与实践.在本章中除了会列举我们工作过程中遇到各种问题和误区 ...

  5. python文本框与数据库的关联_Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理...

    基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客 QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3. ...

  6. Redis缓存设计(key、value设计)与性能优化(缓存击穿、缓存穿透、缓存雪崩)

    一.多级缓存架构 二.缓存设计 1.缓存穿透 缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中, 通常出于容错的考虑, 如果从存储层查不到数据则不写入缓存层. 缓存穿透将导致不存在的数 ...

  7. Redis缓存设计原理及实战

    缓存是什么? 一个系统中的不同层之间的访问速度不一样,所以我们才需要缓存,这样就可以把一些需要频繁访问的数据放在缓存中,以加快它们的访问速度. 为了让你能更好地理解,我以计算机系统为例,来解释一下.下 ...

  8. 深入理解分布式缓存设计

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 在高并发的分布式的系统中,缓存是必不可少的一部分.没有缓存对系统的加速和阻挡大量的请求直接落到系统的底层,系统是很难撑住高并发 ...

  9. 从bitmap到布隆过滤器,再到高并发缓存设计策略

    点击关注公众号,Java干货及时送达 作者:that_is_cool blog.csdn.net/that_is_cool/article/details/91346356 前言:怎么能把风马牛不相及 ...

最新文章

  1. ES6 模块化的基本语法——默认导出 与 默认导入、按需导出 与 按需导入、直接导入并执行模块代码
  2. 前端月趋势榜:6 月新增的、最热门的 20 个前端开源项目 - 2106
  3. 程序员看过来:阿里毕玄提升代码能力的4段经历
  4. 业务处理速度变慢?且看IT如何成为救世主
  5. 修改linux的最大文件句柄数限制
  6. Find the Difference(leetcode389)
  7. 自监督学习在CV领域研究进展总结
  8. 【软考】2020年全国计算机技术与软件专业技术资格考试,软件设计师,考纲
  9. IDEA14创建Maven管理的Java Web项目
  10. HOOK(钩子,挂钩)
  11. python对平面设计有用吗_平面设计有前途吗?
  12. 转调小程序(练口琴时用的)
  13. vm虚拟机配置动态ip和静态ip的方法
  14. SVN如何建立版本库
  15. 什么是注意力机制及其应用(self attention)?
  16. 逻辑推理题:海盗分金币
  17. 炉石传说酒馆战棋一键拔线(windows)
  18. 性能测试到底该怎么做?
  19. Django(10)-模板层的变量和标签
  20. C++内存问题(很多公司面试的题目,值得一看,看懂了别忘了告诉我)

热门文章

  1. java 多线程取一条记录_java多线程从队列中取出数据执行
  2. pytorch得到中间层输出
  3. matlab 全部的随机数函数
  4. jsp转换java_JSP编码转换
  5. php升级语言,PHP是最好的语言,PHP 8.0带来了重大更新
  6. 网上购物软件的测试计划,网上购物平台购物测试计划书
  7. python中的异或操作_Python中的异或和位操作的反转
  8. fluent并行 linux_windows 系统下启动linux主机群的fluent并行操作.docx
  9. php中的变量函数,PHP中的一些路径变量或函数
  10. linux配置php mysql_Linux下LAMP(Apache+PHP+MySql)环境配置