首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何用好缓存?全面梳理(第一篇)

我们做为研发同学,经常会接到各种需求或项目,除了保证业务功能实现外,还会关注一个重要的指标,就是系统性能。如果一个系统发布上线后,扛不住一定的流量,很难得到客户的满意。

如何提升系统性能,有几种方式,做个简单回顾:

  • 复杂的事情简单化,将一个大的业务域拆分成若干子域,并借助DDD的思想指导落地一系列的微服务,系统间通过RPC完成调用。微服务无状态化,理论支持无限级扩容。
  • 从RT入手,RT=work time+wait time。借助MQ框架,将非核心流程异步化,缩短RT,进而提升系统的并发数。
  • 数据层面,按业务域对数据库垂直拆分,读写分离、分库分表。
  • 还有一种就是我们今天要讲的缓存

性能不够,缓存来凑。对于一个典型的互联网应用来讲,使用缓存可以解决绝大部分的性能问题,如果需要优化软件性能,那么可以优先考虑哪里可以使用缓存改善性能。“周期短、见效快”

计算机最核心两部分:计算(飞机)、存储(蜗牛)。木桶原理,整体性能由短板决定。针对速度相差较大的两种硬件,引入组件,协调两者数据传输速度的差异,称之为缓存!!! 如:CPU(1级、2级、3级)

复制两层含义:一种数据的直接拷贝镜像,数据异构;另一种原始数据二次加工,合、拆、转换。通过空间换时间,提升性能。

为什么使用缓存?性能角度,TPS:mysql(2K),redis(10W+)

微博Feed流、微信朋友圈,数据有热点属性,读占80%的流量。搜索不太适合,每个人的搜索词不同,效果不明显。

计算 y = F(x) 非常复杂,中间涉及很多步骤,发生了一系列的存储访问请求。如:一个直播需要在首页展示当前有多少用户同时在线,如果使用 MySQL 来存储当前用户状态,则每次获取这个总数都要“count(*)”大量数据,这样的操作无论怎么优化 MySQL,性能都不会太高。如果要实时展示用户同时在线数,则 MySQL 性能无法支撑。实时的可以借助Spark 、Flink。

命中率。系统 QPS 是 10000/s,每次调用会访问 10 次缓存或数据库,命中率减少 1%,数据库每秒就会增加 10000 * 10 * 1% = 1000 次请求。

注意:缓存并非银弹,需要接受一定时间区间内的数据不一致(最终一致性)

一般来说,我们都会在数据首次被访问的时候,顺便把这条数据放到缓存中。随着访问的数据越来越多,总有把缓存占满的时刻,这个时候就需要把缓存中的一些数据删除掉,以便存放新的数据,这个过程称为缓存置换。

  • LRU,最近最少使用原则,如果数据最近被访问过,那么将来被访问的几率也更高。可能“挖坟”现象。爬虫,冷数据,而程序会把这些数据加入到缓存中去,而导致缓存中那些真实的热点数据被挤出去。
  • LFU,最近最不常用原则,关键是看一段时间内被使用的频率,淘汰一定时期内被访问次数最少的。有的文档可能有很高的使用频率,但之后不会用到。LFU无法剔除这类数据,导致“缓存污染”。
  • SIZE,替换占用空间最大的对象,28原则效果。而不是淘汰小对象,导致“缓存污染”
  • LRU-Threshold,不缓存超过某一size的对象,其他与LRU相同。
  • FIFO,先进先出,当空间满了,队列头部的对象会被踢出,新对象加到队尾。

缓存还是挺费钱的。像阿里云 8节点16G集群版,1年要近2W块钱。缓存还无法做到像磁盘那样廉价,考虑ROI 性价比,数据淘汰策略显得很重要。

缓存无处不在,我们来看下常见的几种缓存

  • 浏览器缓存。这个前端接触比较多一些。浏览器都是基于http协议传输数据的。有5类状态码,其中有一个304状态码。Last-Modified 、Etag。减少网络传输数据,省带宽。
  • 静态页面缓存。静态缓存在 Web 1.0 时期是非常出名,它一般通过生成 Velocity 模板或者静态 HTML 文件,放置在nginx或squid等web服务器,这样用户在访问的时候会优先访问 Web 服务器上的静态页面,在一些门户网站,使用的较多。现在更多是动静结合的方式,将页面中低频变化的元素剥离出来,提前渲染静态页面,比如商详,动态数据通过ajax实时从后端计算获取,从而减轻像tomcat、weblogic等后台应用服务器的压力。
  • APP缓存。刷抖音,流畅。其实播放器中有缓存组件,在播第一个视频时,后台静默线程已经将第二、三个视频提前缓存在本地。秒开。网络差的环境特别明显。
  • 应用级缓存。本地缓存(Guava、Caffieine、Ehcache、ConcurrentHashMap)、分布式缓存( Memcache、Redis)

本地缓存直接访问进程所属内存,不需要跨网络调度,避免网络交互带来的性能损耗,速度快

缓存内容不会改变。因为对多实例服务器来讲,当数据源更新后,每个单机很难感知,维护成本高。发布订阅模式

时效性要求低。能接受一定的延迟,设置较短过期时间,被动失效保持数据的新鲜度

注意事项:

  • 控制数据条数,避免内存占用过多导致OOM,应用瘫痪。
  • 数据时效性,写入后多久有效
  • 实现简单,但潜在的坑比较多,选择成熟的开源框架,如 Guava Cache、Caffeine、Ehcache

全文共三篇,未完待续。。。

举报
领券