2023-08-12
原文作者:Ressmix 原文地址:https://www.tpvlog.com/article/207

我的分布式系列文章写到这里,相信各位童鞋已经对分布式理论和进阶中的核心知识点有了一个清晰的认识,至少应该明白所有分布式系统无外乎是围绕 高性能可扩展高可用一致性 这四个方面来设计的。

从本章开始,我将以一个完整的电子商务支付平台为案例,融合整个系列前两部分介绍过到各种分布式理论和框架,手把手带领大家进行分布式系统的架构设计与落地。

实战篇部分的核心要点是缓存架构的设计,由于架构是不断演进的,所以本章我将先从一个小型的电子商务网站为切入点,介绍其架构存在的缺陷,然后逐步引出系统中的一些核心部分,一步一步讲解支撑高并发场景下的缓存技术、解决方案、架构设计。

一、系统背景

1.1 小型电商平台

这个小型的电子商务网站,其实我在分布式进阶篇的Hystrix简介一章中已经介绍过了。我们来回顾一下:

对于电商系统的商品模块来说,如果我们需要展示商品的详情信息,那么一般都会对商品页进行静态化处理。所谓静态化处理,就是预先从数据库中加载商品信息填充html模板,这样每次用户浏览一个页面,不需要进行任何跟数据库的交互逻辑,直接返回一个html页面就可以了,性能非常高,如下图:

202308122224014801.png

对于小型电商网站,常见的页面静态化处理方式,就是采用velocity、freemarker等html模板,配合后台的页面数据管理系统来做。比如,当我们修改了某个HTML模板后,就在后台点击一个按钮,查出对应的所有商品数据,填充到模板中,然后推送到Nginx服务器:

    <html>
        <title></title>
        <body>
            商品名称:#{productName}
            商品价格:#{productPrice}
            商品描述:#{productDesc}
        </body>
    </html>

这里思考一下,对于这些小型电商平台,商品数量不多,一个HTML模板对应的商品最多也就几千个,这种一次性全量渲染的方式还是可以接受的。但是对于大型电商平台,商品数量都是亿级的,每次html页面模板有变更,都有可能将几亿个页面重新静态化一次,显然是不靠谱的。

1.2 大型电商平台

大型电商平台一般都会采用多级缓存架构来提升性能。我们引入分布式缓存和消息中间件,实现HTML页面的实时动态渲染——即页面不是初始时就填充数据渲染好的,而是每次用户请求过来时动态渲染html页面,这样即使html页面模板变更也没什么影响。动态渲染虽然耗费了渲染时间,但也就是几毫秒,整体上是可以接受的。

202308122224023022.png

我来分析下上图的多级缓存架构:

  1. 用户通过APP或前端网站访问商品详情信息页;
  2. Nginx首先尝试从本地缓存获取商品数据,然后动态渲染HTML模板,将渲染后的页面返回给前端;
  3. 如果Nginx本地缓存中没有数据,则尝试从Redis分布式缓存获取,获取到后更新到本地缓存,然后渲染返回;
  4. 如果Redis中也获取不到数据,则从缓存数据生产服务获取;
  5. 缓存数据生产服务先从本地JVM缓存——ehcache获取数据,如果没有,则调用后台服务获取商品相关数据,然后更新本地缓存、更新Redis缓存,最后返回给Nginx;
  6. 后台服务的各类商品相关数据发生变动时,后台服务会发送变更通知消息到MQ,缓存数据生产服务订阅MQ,接受到通知后会调用后台服务的数据接口,获取相应的数据并更新本地缓存和Redis缓存。

上述这种架构其实就是很多大型电商平台经常使用的三级缓存架构,我们来看下各级缓存的意义:

  • Nginx本地缓存:主要用于抗热点数据的高并发访问;
  • Redis分布式缓存:主要用于抗高并发的离散访问,因为Nginx本地缓存是有限的,而Redis Cluster可以进行水平扩展,所以可以支撑海量数据,并提供高可用服务;
  • JVM本地缓存:主要用于Redis发生大规模灾难时的场景,此时Nginx的大量请求直接涌入数据生产服务,那么最后的JVM本地缓存还可以再抗一下,避免请求直接打到数据库。

二、总结

本章,我主要对后续章节将要进行实战的系统作了一个概述,主要讲解了多级缓存架构。上述多级缓存架构,最核心的其实就是Redis分布式缓存,后续章节,我将带领大家搭建分布式Redis集群,然后引出各种高并发场景下的缓存面临的难题,最后在缓存架构中不断的引入解决这些难题的方案和技术,解决高并发的问题。

阅读全文