大型网站离不开的缓存技术

JAVA herman 1777浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标
网站性能是主观的感受,而感受则是一种与具体参与者相关的微妙的东西,用户的感受和工程师的感受不同,不同的用户感受也不同。

今天为大家分享的是大型网站的缓存使用之道。网站性能优化第一定律:优先考虑使用缓存优化性能

网站性能测试

  • 不同视角下的网站性能 

    • 用户视角 

      • 标准 
        直观感受到的网站响应速度
      • 手段 
        优化HTML式样、利用浏览器端的并发和异步特性、调整浏览器缓存策略、使用CDN服务、反向代理等
    • 开发人员视角 

      • 标准 
        应用程序本身及其相关子系统的性能
      • 手段 
        使用缓存加速读取,使用集群提高吞吐能力,使用异步消息加快请求响应及实现削峰,使用代码优化等
    • 运维人员视角 

      • 标准 
        基础设施性能和资源利用率
      • 手段 
        优化骨干网、使用高性价比定制服务器、利用虚拟化技术优化资源利用
  • 性能测试指标 

    • 响应时间 
      应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间,反映系统的快慢
    • 并发数 
      系统能够同时处理请求的数目,反映系统的负载特性
    • 吞吐量 
      单位时间内系统处理的请求数量,反映系统的整体处理能力
    • 性能计数器 
      服务器或操作系统的一些数据指标,包括System Load、对象与线程数、内存使用、CPU使用、磁盘与网络I/O等指标,也是系统监控的指标
  • 性能测试方法 

    • 性能测试 
      以系统设计初期规划的性能指标为预期目标,对系统不断施加压力,验证系统在资源可接受范围内,是否达到预期
    • 负载测试 
      对系统不断地增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临界值
    • 压力测试 
      超过安全负载的情况下,对系统继续增加压力,直到系统崩溃或不能再处理任何请求,以此获得系统最大压力承受能力
    • 稳定性测试 
      被测试系统在特定硬件、软件、网络环境条件下,给系统不均匀地加载一定的业务压力,使系统运行一段较长时间,以此检测系统是否稳定
  • 性能测试报告 

    • 主要记录各个并发数下的响应时间、吞吐量、错误率、资源使用情况等数据
    • 主要反映系统性能是否满足设计目标和业务要求、系统最大负载能力、系统最大压力承受能力等重要信息
  • 性能优化策略 

    • 性能分析 

      • 检查请求处理的各个环节的日志,分析哪个环节的响应时间不合理、超过预期
      • 检查监控数据,分析影响性能的主要因素是内存、磁盘、网络、还是CPU,是代码问题该是架构设计不合理,或者系统资源确实不足
    • 性能优化 

      • Web端性能优化
      • 应用服务器性能优化
      • 存储服务器性能优化

Web前端性能优化

  • 浏览器访问优化 

    • 减少http请求 
      合并CSS、JavaScript、图片(使用CSS偏移响应)
    • 使用浏览器缓存 
      缓存静态资源,采用逐量更新,要实现及时更新时采用改变文件名而不是改变内容的方式
    • 启用压缩 
      使用GZip压缩文件,但会对服务器和浏览器产生压力,带宽良好而服务器资源不足的情况下要权衡考虑
    • CSS放在页面最上面、JavaScript放在页面最下面 
      加载渲染展示的顺序问题
    • 减少Cookie传输 
      cookie每次请求和响应都会被携带,因此使用要慎重,可使用localStorage和sessionStorge代替。静态资源可使用独立域名防止携带同一Cookie
  • CDN加速 
    缓存访问频度高的静态资源到运营商的机房,最短路径响应,加快用户访问速度,减少数据中心负载压力
  • 反向代理 
    缓存访问频度高的静态资源和热门动态资源,变化时使用内部机制通知缓存无效并重新加载 
    还具有保护网站安全和负载均衡的功能

应用服务器性能优化

  • 分布式缓存 

    • 缓存的基本原理 

      • 将数据存储在相对较高访问速度的存储介质中,以供系统处理
      • 数据可以是经过计算处理得到的,因此减少了访问和计算两方面的时间
      • 存放读写比较高、很少变化的数据,且网站数据访问必须遵循二八定律
      • 本质是内存Hash表,时间复杂度为O(1)
    • 合理使用缓存 

      • 频繁修改的数据 
        一般数据读写比在2:1以上才写入缓存,否则缓存无意义
      • 没有热点的访问 
        数据访问不遵循二八定律,缓存无意义
      • 数据不一致和脏读 
        缓存一般具有失效时间,会自动重新加载。更新会有延迟,具体应用需考虑(PS:采用立即更新缓存的方式,会带来系统额外开销和事务一致性的问题)
      • 缓存可用性 
        使用分布式缓存服务器集群,防止缓存雪崩导致数据库宕机,导致整个网站不可用
      • 缓存预热 
        缓存系统启动时便加载热门数据
      • 缓存穿透 
        注意防止持续高并发地请求某个不存在的数据,对数据库造成巨大压力,甚至宕机,可缓存不存在的数据解决此问题
    • 分布式缓存架构 

      • 需要更新同步的(JBoss Cache为代表) 
        通常应用程序和缓存部署到同一台服务器上,应用程序可从本地快速获取缓存数据,但缓存数据数量受限于单一服务器的内存空间,并且应用服务器集群规模大时缓存更新信息同步到集群所有机器的代价太高 
        常见于企业应用系统
      • 不互相通信的(Memcached为代表) 
        应用程序与缓存分离部署,应用程序通过一致性Hash等路由选择缓存服务器远程访问缓存数据,缓存服务器之间不通信,缓存系统采用分布式部署,存储量大,伸缩性良好 
        常见于大型网站
    • Memcached 

      • 简单的通信协议 
        通信协议:TCP(UDP也支持) 
        通信序列化协议:一套基于文本的自定义协议,非常简单,以一个命令关键字开头,后面是一组命令操作数,为NoSQL产品提供了借鉴
      • 丰富的客户端程序 
        通信协议简单,只要支持该通信协议的客户端都可以和Memcached服务器通信,支持几乎所有主流网站编程语言
      • 高性能的网络通信 
        服务端通信模块基于Libevent(一个支持事件触发的网络程序通信库),优势在于稳定的长连接
      • 高效的内存管理 
        将内存空间分为一组slab,每个slab中包含一组固定大小的chunk,拥有相同大小chunk的slab被组织在一起乘坐slab_class。数据存储时存入比本身Size大的最小的chunk中,采用LRU算法释放空间等待下一个合适的数据。 
        需特别注意启动参数配置大小要合理
      • 互不通信的服务器集群架构 
        这是集群内服务器能做到几乎无限制的线性伸缩的原因
  • 异步操作(任何可以晚点做的事情都应该晚点再做) 

    • 使用消息队列服务器,用户请求的数据发送给消息队列后立即返回,再由消息队列的消费者进程(通常单独部署)从消息中获取数据,异步写入数据库。
    • 用户响应延迟得到有效改善
    • 削峰作用
    • 后续异步处理有可能失败,因此要适当修改业务流程进行配合,比如用电子邮件或SMS消息通知是否成功
  • 使用集群 
    多台服务器共同处理访问请求,分摊压力,将服务器并发数目控制在最佳运行区间,获得最佳的访问请求延迟
  • 代码优化

    • 多线程 
      启动线程数 = [任务执行时间/(任务执行时间-IO等待时间)] x CPU内核数

      解决线程安全的手段

      • 将对象设计为无状态对象 
        对象本身不存储状态信息(对象无成员变量,或者成员变量也是无状态对象),例如贫血模型对象,但与面向对象思想相悖
      • 使用局部对象 
        方法内部创建对象,除非程序员刻意传递,一般不会出现对象被多线程并发访问的情形
      • 并发访问资源时使用锁 
        通过锁的方式将多线程并发操作转化为顺序操作,尽可能使用轻量级锁,注意对系统性能造成的影响
    • 资源复用 

      • 尽可能减少开销大的系统资源的创建和销毁 
        数据库连接、网络通信连接、线程、复杂对象等
      • 单例 
        贫血模式下的WEB应用Service到Dao都是无状态对象,无需重复创建
      • 对象池 
        数据库连接频繁创建耗费资源和时间,采用使用归还的连接池形式,线程池的机制也类似
    • 数据结构 
      不同场景中合理使用恰当的数据结构,灵活组合各种数据结构可极大优化程序的性能
    • 垃圾回收 
      理解垃圾回收机制有助于程序优化和参数调优,以及编写内存安全的代码

存储性能优化

  • 机械硬盘 VS 固态硬盘 

    • 机械硬盘 

      • 连续访问和随机访问性能表现差别非常大
      • 震动、噪声、功耗比较大
    • 固态硬盘 

      • 连续访问和随机访问性能差距小,都很快
      • 震动、噪声、功耗比较小
      • 可靠性、稳定性不高
  • B+树 VS LSM树 
    需要保证数据在不断更新、插入和删除后依然有序 

    • B+树 

      • 传统数据库使用(两级索引)
      • 一次更新需五次磁盘访问(三次获取索引及行ID,一次读,一次写),操作都在磁盘上
    • LSM树 

      • NoSQL产品使用
      • 数据写操作(插入、修改、删除)均在内存中进行,读取时先内存,若没有再磁盘。超过内存设定阀值后与次哦按最新排序树进行合并(覆盖或记录不同版本)。因最近访问原则读取快
  • RAID VS HDFS 

    • RAIN(廉价磁盘冗余阵列) 

      • 传统关系数据库和文件系统使用
      • RAID0(很快 低可靠 100%利用) 
        数据分为N份,并发写入N块磁盘
      • RAID1(很慢 高可靠 50%利用) 
        一份数据写入两块磁盘
      • RAID10(中等 高可靠 50%利用) 
        RAID0与RAID1的结合
      • RAID3(少用) 
        数据分为N-1份,并发写入N-1块磁盘,第N块磁盘记录校验数据 
        频繁写入的场景会导致第N块磁盘易坏
      • RAID5(较快 较高可靠 (N-1)/N利用,常用) 
        数据分为N-1份,并发写入N-1块磁盘,校验数据螺旋写入所有磁盘
      • RAID6(较快 较(RAID5)高可靠 (N-2)/N利用) 
        数据分为N-2份,并发写入N-2块磁盘,校验数据螺旋写入所有磁盘
    • HDFS(在集群规模上实现了类似RAID的功能) 

      • 分布式文件系统中使用
      • 文件分割为Block块,每个Block存三份,实现了数据复制恢复功能
      • 负载均衡提供读写操作
      • 配合MapReduce等并行框架可进行大数据处理

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号1:xmtxtt(5000人已满),微信号2:codedq(5000人已满),微信号3:xttblog(超2800)。备注:“xttblog”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 大型网站离不开的缓存技术