码迷,mamicode.com
首页 > 其他好文 > 详细

一 缓存概述

时间:2020-02-15 15:17:18      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:网络流量   产生   扩展性   缓存   写入   频率   计算机的硬件组成   执行   访问   

软件:指令和数据的集合

最简单的应用:输入数据,计算机计算,输出结果

缓存就是针对这里的数据写入计算机做的一个优化

计算机的硬件组成可以抽象为由总线、io设备、主存、cpu等组成。其中数据是存放在主存中的,cpu负责指令的执行,cpu执行指令计算非常快,大部分一个简单的执行执行只需要一个时钟周期,而一次主内存数据读取则需要几十到几百个时钟周期,那么cpu从主内存读取数据机会有很大的延迟。这是就产生了高速缓存的概念。(一个时钟周期指的是纳秒,1nm=1/10亿秒)

同样的道理,随着业务访问量的增加,很快人们就发现了,从硬盘上读取数据成了提高响应速度的瓶颈,所以,缓存的概念就诞生了。

起初人们将访问频率比较高的数据放到内存中,以提升访问效率,后来发现这样做,如果业务系统重新启动,应用缓存也就随之要重新加载,这样使得业务系统的启动很慢,而且随着缓存数据的增加,就会受到进程分配到内存大小的限制。例如,我们如果以对象的形式存放在jvm堆上时,随者缓存对象的增多,jvm申请的内存是有固定大小的,很可能会发生OOM异常。

考虑到这些问题,又衍生出了同机不同进程的缓存服务和不同机的缓存服务。

一、综上可以对缓存服务分类如下:

  1、按宿主机分可以分为:本地缓存、进程间缓存、远程缓存

  2、按存储介质分可以分为:

    1)、内存型缓存:数据不会落地,只是存储在服务器进程内存中,如果程序重启或crash,缓存的数据会丢失。memcache就是内存型缓存。

    2)、持久化缓存:数据不仅存放在内存中支持高速读取,同时还支持持久化操作,所以数据不会丢失,常用的缓存组件redis就是持久化型缓存组件。

  3、其实实际应用的时候,我们可能更侧重与以下分类:本地缓存、分布式缓存、多级缓存

二、读写模式:

  • Cache Aside(旁路缓存):数据一致性非常高,数据以DB为准,写入数据时先写入DB,然后以DB驱动缓存,更新数据的时候也是先更新DB数据,再由DB驱动缓存更新,读数据的时候先读取缓存数据,如果没有命中再去DB中读取,DB读取计算后回种到缓存中后返回收据。这种方式数据完全以DB为主,业务系统要同时操作缓存和DB,同时也要防止缓存回种异常时的后续处理,不能影响整个业务流程,而且还会数据写入时由于要同时写入缓存,更新时要同时更新缓存,第一次数据读取时要回种缓存,所以这些场景下会比较慢。解决办法是使用额外组件做DB数据同步到缓存中的操作,或者使用异步操作。我曾经写过一个项目,就是把用户的登录权限和菜单信息缓存到redis中,使用的就是旁路缓存,涉及到权限,所以要求数据的一致性比较高,而且没必要单独搭建一个存储服务。用户角色变更,角色权限变更后都先更新DB后,再封装成访问需要的对象序列化后更新到缓存中,同时返回结果。

  • Read/Write Through(读写穿透):这种类型的缓存是将业务和数据读写操作抽离,将数据操作抽离出一个存储服务来,业务系统需要操作数据的时候直接发送请求调用存储服务,具体的缓存处理和DB写入都是由存储服务统一处理。这种类型的特点就是:

    •   (1)缓存和DB的数据同步对业务系统是无侵入的,完全交给存储服务器来完成。但这里要注意的是,虽然是以缓存为先,但是缓存和DB操作也是同步的。

    •      (2)以缓存为主,缓存处理不了才去操作DB,所以性能会更高。但是,要单独维护一个存储服务,如果是同机依然会有资源强占的风险,但若单独部署,还要考虑网络带宽的影响。

  • Write Behind Caching(异步缓存写入):异步缓存,和读写Through一样的是,都是存在存储服务来处理缓存和DB数据。但是不同的是正如名字一样,缓存和DB操作是异步的,业务系统过来请求后都先在缓存中处理,然后直接返回响应,之后再异步跟进DB操作,这样的性能自然是会提高,但是DB和缓存的数据一致性很低,很多时候缓存更新了,但是DB还是老数据,而且极端情况下还会存在数据丢失的情况,例如存储服务宕机或系统crash。

说了这么多,其实缓存的原理无非就是避免在高并发下数据的读取成为系统提高性能的瓶颈。而为了更好的应用缓存,我们一定要更好的理解缓存使用的原理,以及缓存使用的优势和代价。

三、缓存的原理:

缓存构建的基本思想是利用时间局限性原理,通过空间换时间来达到加速数据获取的目的,同时由于缓存空间的成本较高,在实际设计架构中还要考虑访问延迟和成本的权衡问题。这里面有 3 个关键点。

  • 一是数据一次获取可能后续还会多次获取。

  • 二是以空间换时间,原始数据获取太慢,我们在内存开辟一块高速的独立空间,提供高效访问,来达到数据获取加速的目的。

  • 三是成本换性能,相同存储大小的存储介质,内存成本肯定是大于硬盘成本的,这时候就要权衡实际成本和系统性能之间的trade off了。

四、缓存的优势:

  1)、正如缓存诞生的原因,因为缓存是存储在内存中的数据,自然比业务系统直接读取数据库操作数据的性能要高,就如操作系统中的高速缓存的作用一样,,使用缓存可以充分利用cpu资源。

  2)、由于使用缓存中存储的数据一般都是做过初步计算的,所以直接从缓存中读取数据,可以减少计算代价,从而降低业务系统负荷

  3)、缓存中存储的数据一般都是部分访问高频数据,且是存储初步计算过的数据,所以缓存中获得的数据要不DB中的原始数据少得多,这样可以减少网络流量,降低网络拥堵。

  4)、使用缓存,在流量高峰可以通过扩容增加请求性能,流量低谷可以通过下线节点节约成本,特别是现在云服务时代,使得应用的可扩展性增强

五、缓存的代价:

  首先,根据缓存的原理我们可以知道,使用缓存是一个tradeoff的过程,也就是说,使用缓存需要拿空间换时间,拿成本换性能,所以,使用缓存很肯定要增加额外的运维成本和部署成本,所以在架构设计的时候要做好trade off。

  其次,使用缓存肯定会增加系统的复杂性,在处理数据的时候,除了要处理db数据,同时也要考虑到缓存的同步。

  最后,而对于缓存服务本身,除了考虑到数据与db中源数据同步的问题外,同时还要考虑缓存内部多个数据副本,多份数据的一致性问题,而且缓存体系本身也会存在可用性问题和分区的问题。这就需要我们加强对缓存原理、缓存组件以及优秀缓存体系实践的理解,从系统架构之初就对缓存进行良好设计,降低缓存引入的副作用,让缓存体系成为服务系统高效稳定运行的强力基石。

 

总的来讲:服务系统的全量原始数据存储在 DB 中(如 MySQL、HBase 等),所有数据的读写都可以通过 DB 操作来获取。但 DB 读写性能低、延迟高,如 MySQL 单实例的读写 QPS 通常只有千级别(3000~6000),读写平均耗时 10~100ms 级别,如果一个用户请求需要查 20 个不同的数据来聚合,仅仅 DB 请求就需要数百毫秒甚至数秒。而 cache 的读写性能正好可以弥补 DB 的不足,比如 Memcached 的读写 QPS 可以达到 10~100万 级别,读写平均耗时在 1ms 以下,结合并发访问技术,单个请求即便查上百条数据,也可以轻松应对。

 

但 cache 容量小,只能存储部分访问频繁的热数据,同时,同一份数据可能同时存在 cache 和 DB,如果处理不当,就会出现数据不一致的问题。所以服务系统在处理业务请求时,需要对 cache 的读写方式进行适当设计,既要保证数据高效返回,又要尽量避免数据不一致等各种问题。

  

 

一 缓存概述

标签:网络流量   产生   扩展性   缓存   写入   频率   计算机的硬件组成   执行   访问   

原文地址:https://www.cnblogs.com/tianhaichao/p/12304875.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!