什么技能产品经理不会提,但技术人必须懂?

缓存是搭建高性能高并发系统的必备手段之一,一般用来解决性能瓶颈,是程序员的必备知识点,也是面试必备考点。前端

尽管,产品经理大几率不会关注系统性能,但程序员在实现需求的时候必须思考系统承载的并发量和用户量。缓存主要用来解决性能瓶颈的问题,一旦错误使用反而会令系统崩溃。今天,咱们就经过4W的方式系统化地总结缓存相关的理论知识。
随着互联网业务的快速迭代以及用户量激增,应用架构须要不断调整甚至重构以适应这种业务的快速发展。当数据量迅速增加,业务逻辑越复杂,服务链路不断增长等等一系列问题,会致使RT过长,服务性能须要逐渐提高以知足更优的用户体验。在优化系统架构时一般的所用的两种方式scale up以及scale out,scale out就是一般所说的水平扩展,将应用服务设计成无状态性,能够方便水平扩展经过增长硬件的方式分解访问压力。而scale up则是将单个服务链路性能提高,以提高QPS以及系统的吞吐量。在追求更优的性能时,大多数业务场景是读多写少的状况,通常会经过引入缓存的方式解决。nginx

  1. What——什么是缓存?
    关于缓存的定义,在wiki中为:
    a collection of data duplicating original values stored elsewhere on a computer, usually for easier access.
    简单理解就是保存在计算机设备中的一个数据副本,以便于后续可以进行快速访问。
    从定义上能够看出所谓缓存必定是针对已有数据的一个副本存在,也能够看出缓存的使用是为了解决快速访问数据(读数据)的场景。在现有的互联网应用中,缓存的使用是一种可以提高服务快速响应的关键技术,也是产品经理无暇顾及的非功能需求,须要在设计技术方案时对业务场景,具备必定的前瞻性评估后,决定在技术架构中是否须要引入缓存解决这种这种非功能需求。
    缓存在计算机领域中实际案例存在不少,好比CPU的缓存是为了解决CPU的运算速度和内存的读取数据不平衡的问题,CPU的运算速度远快与内存的读写速度,为了下降CPU等待数据读写的时间,在CPU中引入L1/L2/L3多级缓存。
    再好比Linux中的文件缓存,实际上咱们在编程时,会谈论到数据的内存地址,可是咱们接触的都是虚拟地址而不是真实的物理地址,计算机中的内存管理单元(MMU)和页表会将虚拟地址转换成物理地址。在计算机硬件领域中就已有不少关于缓存的应用案例,实际上在软件架构中关于缓存的设计会借鉴于不少传统且成熟的计算机硬件缓存设计的思想。
  2. Why——为何须要使用缓存?
    软件服务可以获得用户的信赖,并将产品的价值带给用户,可以解决目标用户的痛点问题这是决定用户会不会一开始决定使用,也就是《增加***》中提到了产品可以带来给用户“啊哈时刻”,而决定用户会不会高频使用以及持续使用,用户体验则是被认为是软件产品提高用户黏性的关键影响因素。
    2.1 什么是用户体验
    用户体验被专业定义和推广须要推广到20世纪90年代,由Donald Norman布道推广。用户体验在人机交互领域上受到了重视,并一度和传统的三大可用性指标(即效率、效益以及基本满意度)不相上下。
    ISO 9241-210标准将用户体验官方定义为:人们对正在使用或者期待使用的产品、系统或者服务的认知印象和回应。能够看出用户体验是用户的对软件产品的主观感觉,具体包含了用户在使用以前、使用中以及使用后的情感、喜爱、认知印象、心理反应以及情绪表达等等多种主观感觉,每一个用户对产品的主观感觉的视角不一样,关注点不一样,也就致使软件产品让大多数用户都可以得到很好的用户体验自己就是一件颇有挑战性的事情。
    在业界大多数,将用户体验分为三类:使用者状态、软件产品的系统性能以及环境,使用者状态以及环境(使用者环境以及产品在同类产品中的产品大环境)这两个因素须要交互设计和用研等多个专业领域同窗去攻克,软件开发者则须要解决系统性能的问题。对用户而言,最基本的需求就是在使用软件服务时,软件产品提供服务内容的及时性,也就是一般所说的在使用过程当中持续的Loading(转菊花)必定会致使用户体验不好,内容的及时性也是系统性能的最低要求。
    而系统性能的问题,是产品经理无暇顾及的点,也是非功能性需求,须要开发者去花心思去思考的地方。评估系统性能的指标有不少,在以提高用户体验为前提的状况下,咱们须要着重关注的性能指标有哪些呢?
    2.2 常见的性能指标
    在设计软件架构时须要关注的几个常见指标:响应时间、延迟时间、吞吐量、并发用户数和资源利用率。
    1)系统响应时间 :响应时间是指系统对用户请求作出响应的时间,不一样的功能的链路长短不一样,而且同一功能在不一样数据量等这些状况都会致使响应时间的不一样。所以,在衡量系统响应时间时,一般会关注软件产品全部功能的平均响应时间以及最大响应时间。
    2)延迟时间 :在讨论系统响应时间时,更细粒度的划分能够划分为:
    客户端在接受数据进行渲染的内容“呈现时间”;
    服务端在接受用户请求发送至服务端以及服务端将数据返回到客户端这两个过程当中涉及到的:网络传输时间以及应用延迟时间。应用延迟时间便是服务端在执行整个服务链路时所花费的时间,也是性能优化首要下降的就是这个时间。
    3)吞吐量 :吞吐量指的是单位时间内可以处理请求的数量,对于无并发的应用来讲,吞吐量和请求响应时间成反比,服务延迟更长则系统吞吐量更低。
    4)并发用户数 :并发用户数指的是系统可以同时承载正常使用系统功能的用户数,相较于吞吐量,这个指标更为笼统可是对于非软件领域的人来讲更容易理解。
    5)资源利用率 :资源利用率反映的是在一段时间内资源被占用的状况。
    2.3 缓存带来的优点
    在追求更优的优化体验时,客观的来讲须要不断提高以上这些性能指标,不断逼近系统体验的最优解。缓存到底具备什么样的优点,值得咱们花费很大的精力去设计一套能很好的适应如今的业务场景的缓存结构呢?
    1)极大的提高软件用户体验
    软件产品主要围绕两个核心问题,一是解决目标用户的痛点问题,二是提高产品黏性。在提供软件服务时,抽象的来看是解决数据在整个链路上的流转问题,如何让数据流转更加高效、更加顺畅是在实现时着重关注的地方,事实上,不管是浏览器、负载均衡、应用服务器仍是数据库等等各个环节都会应用到缓存,当数据离用户“更近”,好比数据副本在客户端上,也就意味着请求可以很快的进行响应,相应的给用户进行数据呈现的耗时就更短。现现在用户爸爸们“日理万机”,若是一个软件产品不能在很短期就获取用户的注意力,很大可能性就意味着失败。所以,使用缓存可以让用户从主观上获取更优的用户体验。
    2)提高吞吐量
    试想,若是在服务链路上,请求可以在缓存中获取服务数据的话,也就意味着不少数据并不须要从源应用服务器进行获取,下降了源服务器网络传输的频率,在必定IDC带宽下,系统可以下降网络传输时间以及应用延迟时间,从而支撑更多的系统访问以提高系统总体吞吐量以及并发用户数,硬件的使用效率也会明显提高。
    从实际场景下,在系统性能优化时大几率会优先选择使用缓存进行系统优化,也是一种被证实有效的手段,缓存也被认为是一种“空间换时间”的艺术。
  3. Where——缓存存在链路中的哪些地方?
    3.1 缓存分类
    从一个请求到最终获取响应,会通过不少环节,缓存能够几乎存在整个链路的每一个节点。缓存按照不一样的维度能够有以下分类:
    1)缓存所处链路节点的位置:
    客户端缓存
    网络缓存
    服务端缓存
    2)缓存架构部署方式:
    单机缓存
    缓存集群
    分布式缓存
    3)缓存的内存区域
    本地缓存/进程内缓存
    进程间缓存
    远程缓存
    按照缓存在服务链路上的位置来划分,能够系统性的梳理下缓存的不一样应用。
    3.2 客户端缓存
    客户端缓存是离用户“最近”的一种存储介质,常常和网络测和服务端缓存一块儿配合使用,常见的客户端缓存有以下几种:
    1)页面缓存:页面缓存是指将静态页面获取页面中的部分元素缓存到本地,以便下次请求不须要重复资源文件,h5很好的支持的离线缓存的功能,具体实现可经过页面指定manifest文件,当浏览器访问一个带有manifest属性的文件时,会先从应用缓存中获取加载页面的资源文件,并经过检查机制处理缓存更新的问题。
    2)浏览器缓存:浏览器缓存一般会专门开辟内存空间以存储资源副本,当用户后退或者返回上一步操做时能够经过浏览器缓存快速的获取数据,在HTTP 1.1中经过引入e-tag标签并结合expire、cache-control两个特性可以很好的支持浏览器缓存,关于浏览器缓存更为细节的知识能够查看该文章。
    3)APP缓存:APP能够将内容缓存到内存或者本地数据库中,例如在一些开源的图片库中都具有缓存的技术特性,当图片等资源文件从远程服务器获取后会进行缓存,以便下一次再也不进行重复请求,并能够减小用户的流量费用。
    客户端缓存是前端性能优化的一个重要方向,毕竟客户端是距离“用户”最近的地方,是一个能够充分挖掘优化潜力的地方。
    3.3 网络缓存
    网络缓存位于客户端以及服务端中间,经过经过代理的方式解决数据请求的响应,下降数据请求的回源率。一般具备以下几种形式的网路缓存:
    1)web代理缓存:常见的代理形式分为分为:正向代理、反向代理以及透明代理。web代理缓存一般是指正向代理,会将资源文件和热点数据放在代理服务器上,当新的请求到来时,若是在代理服务器上能获取数据,则不须要重复请求到应用服务器上;
    2)边缘缓存:和正向代理同样,反向代理一样能够用于缓存,例如nginx就提供了缓存的功能。进一步,若是这些反向代理服务器可以作到和用户请求来自同一个网络,那么获取资源的速度进一步提高,这类的反向代理服务器能够称之为边缘缓存。常见的边缘缓存就是CDN(Content Delivery Network),能够将图片等静态资源文件放到CDN上。
    3.4 服务端缓存
    服务端缓存是后端开发中进行性能优化的发力点,常见的后端性能优化也是经过引入缓存来进行解决,常见的有数据库的查询缓存、缓存框架以及引入应用级缓存。
    3.4.1 数据库查询缓存
    例如,MySQL的缓存机制是经过将SELECT语句以及相应的ResultSet进行缓存,当后续接受到SELECT请求后,若是MySQL已经开启了Query Cache功能,会将SELECT语句以字符串的方式进行hash,而后去从缓存中进行查询,若是查询出数据,则直接进行返回,省去了后续的优化器以及存储引擎IO的操做,可以极大的提高响应时效。如何优化Query Cache须要从以下几个指标上进行考虑:
    query_cache_size:设置可以缓存ResultSet的内存区域大小
    query_cache_type:表示使用缓存的场景。0表示任何场景下都不使用Query Cache,1表示显式指定不使用Query Cache的查询均可以使用,2(DEMAND)表示只有明确指示使用Query Cache才会生效;
    Qcache hits:表示多少次查询命中Query Cache
    Qcache inserts:表示多少次没有命中Query Cache而插入数据
    Qcahce lowmem prunes:表示多少条Query引入空间不足而被清除
    Qcache free memory:表示剩余内存大小
    Qcache free blocks:该值很大表示内存碎片不少,须要及时清理
    在进行Qcache优化时,能够对以上指标综合进行分析,好比了解Qcache的缓存命中率 = Qcache hits/ Qcache hits + Qcache inserts,来判断当前Qcache的效率。也能够结合Qcahce lowmem prunes、Qcache free memory以及Qcache free blocks来判断当前Qcache的内存使用效率。
    另外,若是使用Innodb存储引擎的话,也须要着重关注innodb_buffer_pool_size参数,该参数决定了innodb的索引以及数据是否有足够大的空间放入到缓存中。table_cache决定了可以缓存表的最大数量,也是须要关注的一个参数。
    3.4.2 缓存框架
    在功能开发时,会经常使用提供缓存特性的缓存框架或者实现缓存功能的类库来高效的完成开发,常见的缓存框架有Ehcache、Guava等,这些缓存框架配置简单,可以简单灵活的使用。这些开源的缓存框架不只支持单机的本地缓存还能配置集群的方式达到灵活伸缩。
    3.4.3 应用级缓存
    当缓存框架不能知足需求的时候,就须要引入应用级缓存,好比Redis、MongoDB等NoSQL数据库,应用级缓存具有高可用性以及伸缩性的分布式架构可以支撑业务需求,固然,作好一款应用级缓存产品其中的挑战也是巨大。
  4. When——何时须要使用缓存?缓存不是架构设计的必选项,也不是业务开发中的必要功能点,只有在业务出现性能瓶颈,进行优化性能的时候才须要考虑使用缓存来提高系统性能。也不是全部的业务场景都适合使用缓存,读多写少且数据时效要求越低的场景越适合使用缓存,缓存并非全部性能问题的灵丹妙药,若是滥用缓存反而会成为毒药,而且会引入维护缓存的操做成本,使得系统复杂度更高不利于维护。另外把缓存当作存储来使用是一件极其致命的作法,这种错误的认识,将缓存引入系统的那一刻起就意味着已经让系统走上了危险的局面,对缓存的使用边界要有深入的理解,才能尽量保证作出引入缓存才是一个正确的决定。在进行缓存结构设计的时候,须要考虑的点有不少:1)业务流量量级以及应用规模:对于低并发低流量的应用而言,引入缓存并不会带来性能的显著提高,反而会带来应用的复杂度以及极高的运维成本。也不是任何数据都须要使用缓存,好比图片视频等文件使用分布式文件系统更合适而不是缓存。所以,在引入缓存前,须要对当前业务的流量进行评估,在高并发大流量的业务场景中引入缓存相对而言收益会更高;2)缓存应用的选择:缓存应用有不少如Redis、Memcached以及tair等等,针对每一种分布式缓存应用的优缺点以及适用范围、内存效率、运维成本甚至团队开发人员的知识结构都须要了解,才能作好技术选型;3)缓存影响因素的正确评估:在引入缓存前,须要着重评估value大小、缓存内存空间、峰值QPS、过时时间、缓存命中率、读写更新策略、key值分布路由策略、过时策略以及数据一致性方案等等多个因素,要作到心中有数;4)缓存高可用架构:分布式缓存要高可用,这也是分布式系统追求的三高指标中的一个,缓存的集群设计,主从同步方案的设计等等,只有缓存足够可靠,才能服务于业务系统,为业务带来价值;5)完善的监控平台:当缓存投入生产环境后,须要有一套监控系统可以显式的观测缓存系统的运行状况,才能更早的发现问题,同时对于预估不足的非预期热点数据,也须要热点发现系统去解决非预期的热点数据缓存问题。6)缓存最近原则:将缓存数据放在离用户最近的地方,无疑会极大的提高响应的速度,这也是多级缓存设计的核心思想。5.如何正确使用缓存?影响缓存总体的性能会有不少大大小小的影响因素,好比语言自己的特性的影响,例如Java须要考虑GC的影响。还须要尽量的提高缓存命中率等等多个方面,核心的几个影响因素有哪些?如何正确使用?
相关文章
相关标签/搜索