前言:为什么应用服务器和数据库分离之后,还需要继续优化
我们上一篇文章学习到了单机架构逐渐演化到分布式架构的过程,最开始,应用程序和数据库都运行在同一台服务器上,随着访问量增加,我们可以将应用服务器和数据库服务器分开部署,减少它们之间的资源竞争,如果应用服务器的处理能力不够,还可以增加应用服务器,并通过负载均衡将请求分配给不同的服务器
但是,这样就意味着系统不会再出现性能问题了吗?答案是否定的
例如,一个电商网站有很多用户同时访问商品详情页。即使我们已经部署了多台应用服务器,这些服务器最终仍然可能需要访问同一个 MySQL 数据库,当大量请求集中访问数据库时,数据库依然可能成为整个系统的性能瓶颈。
那么,我们还能怎么优化?
接下来要理解两个重要的思路:
-
数据库读写分离:让不同的数据库实例分担读写压力。
-
引入缓存:让一部分请求不必每次都访问数据库。
这两个方案都可以改善系统的性能,但它们解决问题的方式并不相同,接下来我们的这篇文章就主要围绕这两个优化以及下面这张图来展开

一,数据库读写分离
为什么
在研究数据库读写分离之前,我们先要了解什么是读与写
读:用户查询商品详情,查看订单
写:用户修改个人信息,创建订单
通常访问量比较小的时候,一台MySQL数据库通常就能承担这些工作,但是当大量用户查询商品,数据库就需要处理大量读请求,并且事实也是如此,我们读的操作往往请求量是更大一些的,为了应对这个,我们就可以考虑读写分离了
怎么做
简单来说就是将数据库的读操作和写操作分配给不同的数据库实例处理,一般情况就分为多个从库和一个主库
主库:主要负责写操作,例如新增,修改和删除数据
从库:通常用于处理读操作,例如查询商品信息
数据复制:主库的数据变更会复制到从库,减少数据不同步的情况

存在的问题
这里分离之后存在的一个需要特别注意的问题:主库和从库的数据可能会不实时统一
就比如:当用户修改了自己的昵称之后,整个过程就是应用程序将新的昵称写入主库,主库成功完成更新,用户立即重新查询自己的昵称,而查询的请求被路由到了从库,但是此时的从库的数据还没有更新,这就是常说的复制延迟导致的数据读取不一致
因此我们在应对这种实时性要求很高的场景的时候,系统就需要将这次的查询路由到主库先或者采用其他的一致性的处理策略
二,Redis缓存
理解了读写分离之后,我们还需要考虑一个问题,就是加入我们网站有一个非常热门的产品,大量用户每天查询多次商品信息,但是与此同时,我们用户的信息以及商品的信息是不会频繁改变的,那每一次查看商品的时候都需要重新查询MySQL吗,这个时候我们就可以引入我们的主角Redis了
什么是缓存
缓存可以理解为是将经常使用的数据保存起来,在后续需要的时候优先在这个位置读取,从而减少重复的计算以及访问后端资源
为什么不直接使用MySQL
首先需要明确一点就是MySQL也是可以利用内存的,也就是说不能简单的理解为MySQL只能从硬盘读取数据,使用Redis是因为两个数据库的设计和应用场景不同
MySQL:适合关系型数据管理,复杂SQL查询
Redis:擅长以内存中的数据结构处理大量简单的频繁的数据访问操作
所以我们一般是MySQL以及Redis共同合作
怎么做
我们以用户查询为例子来理解Redis缓存是如何工作的

1. 第一次查询:缓存未命中
我们用户查询商品信息,spring boot接受请求之后查询Redis缓存,发现缓存里没有数据,我们就通过MySQL来查询数据并且将数据写到Redis缓存中
2. 第二次查询:缓存命中
如果商品信息已经在Redis中存储过了,那么我们就可以直接从Redis中获取商品详情
实时更新的问题
就是当我们MySQL中保存的商品信息已经更新了,但是我们的Redis的信息还是老的,这个时候我们该如何进行处理
1. 一种常见的处理方式:更新数据库后删除缓存
-
先更新 MySQL 中的业务数据。
-
更新成功后,删除 Redis 中对应的缓存。
-
下一次用户查询时,如果缓存不存在,就重新查询数据库。
-
获取最新数据后,再将结果写入 Redis。
为什么这里选择删除缓存,而不是一定要把新数据直接写入缓存?
这样可以减少缓存长期保存旧值的风险,也可以避免部分复杂的缓存的更新问题,不过在更加复杂的情况之下,我们还需要考虑一些其他的问题以及方案

三、总结
本文从数据库读写分离出发,进一步理解了 Redis 缓存的作用。
我们需要记住几个核心结论:
-
应用服务器与数据库分离之后,数据库仍然可能成为性能瓶颈。
-
数据库读写分离通过将读写请求分配给不同的数据库实例,分担数据库负载。
-
Redis 缓存通过保存热点数据,减少重复访问 MySQL 的次数。
-
缓存命中时可以直接从 Redis 获取数据;缓存未命中时,应用程序需要从数据库获取数据。
-
使用缓存后,需要考虑过期时间、数据一致性以及缓存失效带来的问题。
-
数据库读写分离与 Redis 缓存可以配合使用,并不是相互替代的技术。