✅P151_缓存-缓存使用-本地缓存与分布式缓存
大约 3 分钟
缓存使用
为了系统性能的提升, 我们一般都会将部分数据放入缓存中, 加速访问。 而 DB 承担数据落盘工作。
哪些数据适合放入缓存?
- 即时性、 数据一致性要求不高的
- 访问量大且更新频率不高的数据(读多, 写少)
举例: 电商类应用, 商品分类, 商品列表等适合缓存并加一个失效时间(根据数据更新频率来定), 后台如果发布一个商品, 买家需要 5 分钟才能看到新的商品一般还是可以接受的。
本地缓存使用的伪代码:
data = cache.load(id);//从缓存加载数据
If(data == null){
data = db.load(id);//从数据库加载数据
cache.put(id,data);//保存到 cache 中
}
return data;
注意:
在开发中, 凡是放入缓存中的数据我们都应该指定过期时间, 使其可以在系统即使没有主动更新数据也能自动触发数据加载进缓存的流程。 避免业务崩溃导致的数据永久不一致问题。
本地模式
如果我们的应用只是一个单体应用,缓存使得查询数据速度更快。
但在分布式系统下,商品服务可能会部署在十几个服务器上,而每个服务都自带一个自己的本地缓存,那就会出现这样一个问题:
- 第一次请求,负载均衡来到第一个微服务,第一个微服务查数据的时候,缓存中没有,它查了一次数据库,查到以后再放到缓存中,现在缓存中有数据了
- 如果下一次请求,负载均衡到第二个微服务,这个微服务的缓存,相当于还是没有数据,还得再查一遍数据库
- 由于这些缓存都是分开的、各顾各的,没有的话都得自己查一遍。
解决方案:
- 使用集中的缓存中间件,解决了上述问题的同时还解决了缓存不足的问题,可以将缓存中间件集群化
分布式缓存
我们将所有商品服务的缓存数据,放到一个集中的缓存中间件中,
- 假如请求被负载均衡到第1个服务器,如果第1个服务器查询缓存中没有数据,就会查询数据库,1份数据用来显示,1份用来给缓存;
- 假设第二次请求,来到了第2个服务器,由于第1次查询已经给缓存中放过数据了,所以第2个服务器就可以直接从缓存中查出数据,那就不需要再调用复杂的业务逻辑查询了;
- 包括第3个服务器、乃至第N个,都可以直接从缓存中拿到数据;
- 同样的,如果数据发生了修改,假设有一次请求来到了3号服务器,那不但会修改数据库,并且缓存中的数据也将被修改。这样,就是其他的请求来到了别的服务器,因为它们操作的都是一个地方的缓存,所以就不会出现数据不一致的问题;
- 这就是分布式缓存的解决方案,不应该把缓存放在它本地的进程里面,而是要跟其它服务器共享一个集中式的缓存中间件。