缓存设计

天大地大妈咪最大 提交于 2020-01-16 04:21:34

1.前言&基本介绍

    在原始的系统架构中,我们都由程序直接连接DB,随着业务的进一步开展,DB的压力越来越大,为了缓解DB的这一压力,我们引入了缓存,在程序连接DB中加入缓存层,

从而减轻数据库压力,而且缓存一般存在于内存中,相比于存在硬盘中的DB在读取速度上绝对是比DB高几个等级。下面我们来简单聊聊关于缓存几个东西

  

2.缓存的优缺点

    缓存的优点就是“快”,一个快字基本能概括了。如上文说的加速读写,分流对数据库的压力,归根结底就是对快字的应用及其本身,缺点主要是如下三点:

      1.数据不一致性:DB的数据与缓存中的数据不一致

      2.开发成本:需要同时处理缓存层跟DB层的逻辑,增加了开发成本

      3.维护成本:例如需要对缓存层进行一个监控,增加了运维的成本

 

3.缓存更新策略

     在上面中我们说到数据不一致性,一般来说缓存也是需要有生命周期的,需要被更新或者删除,这样才能保持缓存的可控性,在缓存更新中有如下三点:

      1.LR(F)U/FIFO算法删除:简单来说就是按照队列的形式对不常用的缓存进行删除,链表的形式来实现,具体可点这里http://blog.csdn.net/maddemon/article/details/6650703
 
      2.超时删除:在设置缓存的时候可以设置过期时间,在时间到期之后自动删除。在使用这个的时候,最好还是确保缓存数据跟数据库数据不一致的时候业务能容忍,还是存在一致性的问题
 
      3.主动更新:应用于对数据一致性要求高的,但最好还是需要保证更新的准确性。假如对实时性要求不高的,还是根据超时删除吧
 

4.缓存粒度

    假设一张用户表有20个字段,那是否需要将全部字段都放到缓存中?这就涉及到一个粒度的问题!数据字段放少了,就会出现了不通用的问题;数据字段放多了,空间占用也多,序列化跟反序

列化消耗的性能更多了。在粒度这个问题上还是需要根据通用性,代码维护,性能跟空间占用这几点上进行考虑, 简单来说就是靠经验了

 

5.缓存穿透

      缓存穿透指的是查询一个不存在的数据,DB跟缓存都不会命中的数据。这样的话每次查询都会到DB层中查询,DB层负载加大还有可能造成死机,这样缓存就失去了保护DB层的意义。出现这种情况有两种:1.攻击,爬虫的大量请求;2.业务自身有问题。现在基本流行的解决方案有以下两种:

       5.1 缓存空对象,当DB层也查不到数据的时候,缓存一个null值进缓存,这样下一次的话就直接从缓存中读取,保护了后端。不过这种带来的后果是缓存了更多的键,需要更多的空间,而且不可控性增加

 
      5.2布隆过滤器拦截,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。这样在查询缓存之前先去过滤器中查询缓存是否有存在该key。不过这个适合于数据量固定,实时性低的应用中,因为要维护这一个过滤器。
 

6.雪崩优化

    指的是原先的缓存层承载了大量的请求,有效的保护了DB层,但是假如缓存层炸了,那所有的请求都直接穿透到DB层,会容易造成DB层也炸了。就这个问题一直没有一个很完美的解决方案,可以从下列两个方面进行思考:

      6.1.保证缓存层的高可用(HA),例如redis的Sentinel跟Cluster都实现了高可用(在windows10下跑这个sentinel,偶尔会出现节点挂了但是sentinel没反应过来的情况,还是linux稳定一点)
 
      6.2.提前演练,这个类似与实验设计,模拟某一层挂了的处理情况
 

7.总结

  最后用Xmind总结一下:

  

 

 

出处:http://www.cnblogs.com/powerdk/p/7116830.html

1.前言&基本介绍

    在原始的系统架构中,我们都由程序直接连接DB,随着业务的进一步开展,DB的压力越来越大,为了缓解DB的这一压力,我们引入了缓存,在程序连接DB中加入缓存层,

从而减轻数据库压力,而且缓存一般存在于内存中,相比于存在硬盘中的DB在读取速度上绝对是比DB高几个等级。下面我们来简单聊聊关于缓存几个东西

  

2.缓存的优缺点

    缓存的优点就是“快”,一个快字基本能概括了。如上文说的加速读写,分流对数据库的压力,归根结底就是对快字的应用及其本身,缺点主要是如下三点:

      1.数据不一致性:DB的数据与缓存中的数据不一致

      2.开发成本:需要同时处理缓存层跟DB层的逻辑,增加了开发成本

      3.维护成本:例如需要对缓存层进行一个监控,增加了运维的成本

 

3.缓存更新策略

     在上面中我们说到数据不一致性,一般来说缓存也是需要有生命周期的,需要被更新或者删除,这样才能保持缓存的可控性,在缓存更新中有如下三点:

      1.LR(F)U/FIFO算法删除:简单来说就是按照队列的形式对不常用的缓存进行删除,链表的形式来实现,具体可点这里http://blog.csdn.net/maddemon/article/details/6650703
 
      2.超时删除:在设置缓存的时候可以设置过期时间,在时间到期之后自动删除。在使用这个的时候,最好还是确保缓存数据跟数据库数据不一致的时候业务能容忍,还是存在一致性的问题
 
      3.主动更新:应用于对数据一致性要求高的,但最好还是需要保证更新的准确性。假如对实时性要求不高的,还是根据超时删除吧
 

4.缓存粒度

    假设一张用户表有20个字段,那是否需要将全部字段都放到缓存中?这就涉及到一个粒度的问题!数据字段放少了,就会出现了不通用的问题;数据字段放多了,空间占用也多,序列化跟反序

列化消耗的性能更多了。在粒度这个问题上还是需要根据通用性,代码维护,性能跟空间占用这几点上进行考虑, 简单来说就是靠经验了

 

5.缓存穿透

      缓存穿透指的是查询一个不存在的数据,DB跟缓存都不会命中的数据。这样的话每次查询都会到DB层中查询,DB层负载加大还有可能造成死机,这样缓存就失去了保护DB层的意义。出现这种情况有两种:1.攻击,爬虫的大量请求;2.业务自身有问题。现在基本流行的解决方案有以下两种:

       5.1 缓存空对象,当DB层也查不到数据的时候,缓存一个null值进缓存,这样下一次的话就直接从缓存中读取,保护了后端。不过这种带来的后果是缓存了更多的键,需要更多的空间,而且不可控性增加

 
      5.2布隆过滤器拦截,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。这样在查询缓存之前先去过滤器中查询缓存是否有存在该key。不过这个适合于数据量固定,实时性低的应用中,因为要维护这一个过滤器。
 

6.雪崩优化

    指的是原先的缓存层承载了大量的请求,有效的保护了DB层,但是假如缓存层炸了,那所有的请求都直接穿透到DB层,会容易造成DB层也炸了。就这个问题一直没有一个很完美的解决方案,可以从下列两个方面进行思考:

      6.1.保证缓存层的高可用(HA),例如redis的Sentinel跟Cluster都实现了高可用(在windows10下跑这个sentinel,偶尔会出现节点挂了但是sentinel没反应过来的情况,还是linux稳定一点)
 
      6.2.提前演练,这个类似与实验设计,模拟某一层挂了的处理情况
 

7.总结

  最后用Xmind总结一下:

  

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!