专栏首页微观技术如何用好缓存?全面梳理(第一篇)

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

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

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

  • 复杂的事情简单化,将一个大的业务域拆分成若干子域,并借助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

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

本文分享自微信公众号 - 微观技术(weiguanjishu),作者:TomGE

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

    讲了这么多,那我们在使用缓存有没有要注意的问题,有没有什么潜在的坑。我们来看几个问题案例。

    用户7676729
  • 使用缓存必须注意的事项

    关系型数据库在TPS上的瓶颈往往会比其他瓶颈更容易暴露出来,尤其对于大型web系统,由于每天大量的并发访问,对数据库的读写性能要求非常高;而传统的关系型数据库的...

    用户7676729
  • 如何用好缓存?全面梳理(第二篇)

    既然本地缓存有这么多的不足,那能不能把缓存独立出来呢?统一化管理。分布式缓存借助分布式的理念,采用集群化部署,突破单机的容量限制,理论上支持无限扩容。如果数据更...

    用户7676729
  • 高并发场景缓存真的可靠吗?

    有一定开发经验的研发人员都知道,缓存是高并发场景解决方案中的大杀器,应用中引入了缓存可以将大部分查询流量引入到缓存上,从而降低DB的qps来保护有限的底...

    Typhoon
  • 分布式系统关注点(18)——「缓存穿透」和「缓存雪崩」到底啥区别?

    有句话说得好,欲要使其毁灭,先要使其疯狂。当你沉浸在缓存所带来的系统tps飙升的喜悦中时,使你系统毁灭的种子也已经埋在其中。

    Zachary_ZF
  • Redis缓存穿透、缓存雪崩和缓存击穿理解

    缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询...

    爱撸猫的杰
  • 系统架构设计:进程缓存和缓存服务,如何抉择?

    我们所说的缓存分为进程内部缓存(系统内部缓存)和 缓存服务(如redis/memcache)。计算机服务从原来的单体结构,到多实例,到现在流行的微服务,缓存服务...

    java乐园
  • 8张图带你分析Redis与MySQL数据一致性问题

    对于Web来说,并发量和访问量增加一定程度上推动项目技术和架构的更迭和进步。可能会有以下的一些状况:

    bigsai
  • 面试前必须要知道的Redis面试题

    在前面学习我们都知道Redis不可能把所有的数据都缓存起来(内存昂贵且有限),所以Redis需要对数据设置过期时间,并采用的是惰性删除+定期删除两种策略对过期键...

    Java团长
  • 对Hibernate二级缓存理解

    缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

    葆宁

扫码关注云+社区

领取腾讯云代金券