勇哥注:
先由在线商品销售这种高并发应用的场景聊起什么是缓存?作用是什么?
系列贴子列表:
.NET的缓存(二).net的 MemoryCache
http://www.skcircle.com/?id=2437
.NET的缓存(一)缓存、多级缓存的概念及用途的介绍
http://www.skcircle.com/?id=2436
多级缓存
缓存可以理解为内存数据。主要目的是解决高速对象与低速对象之间的匹配问题。
DB中的数据,会在Nginx, 集群,.Net6集群,Redis集群等多个模块中进行缓存,这就是多级缓存。
在什么地方使用多级缓存?
例如在在线商品销售中的秒杀系统中,就是使用多级缓存的典型场景 。
单体架构
1。查询商品业务场景
在这个场景中,.net6的秒杀服务可以并发处理400条(举例),数据库只能并发处理200条,
两者的并发能力是不一样的。因为数据库用的是磁盘服务,.net6使用的是内存服务。
这样客户端最高就只能提供200的并发请求了,这个就是木桶效应,桶的容量取自最短的那块板。
如果让数据库强制处理400个并发,数据库就会宕机
一级缓存方式
下面加了缓存的解决方案:
我们在.Net6模块增加缓存,这时候客户端的请求,先尝试从缓存里面取,
如果缓存里有要的数据就直接返回,不再通过DB了。
如果缓存里没有要的数据,才从数据库里去取。
因为缓存就是内存,这样客户端的并发能力就能和.net6模块并发能力一样了,都可以处理400个并发。
缓存有一种重要指标:缓存命中率
对于一级缓存来说,假设有两个商品A的查询,那么第一次查询的时候,缓存为空,所以从DB去取,取完后更新到缓存里。
第一次查询商品A的时候,先从缓存里取,结果取到了商品A,然后就不再向DB要,直接返回了。
这个时候两次查询的缓存的命中率就是1/2=50%。
多份缓存方式
如果客户端并发访问提升到800,那么一台.net6服务器就可能会宕机,方法就是提供2台.net6。
这种方式就称为集群,我们提供了.net6服务的集群。
然后的问题是客户端这800个并发,如何负载均衡到两台.net6服务器上,这个是通过Nginx实现。
这一种方式的一个重大问题提可能会极大降低缓存的命中率。
假设还是有两种商品A的查询,第一次查询由Nginx负载均衡到第一台.net6服务器,其缓存没有,于是去DB取,然后更新了缓存。
第二次查询商品A,由Nginx负载均衡到第二台.net6服务器,其缓存没有,于是去DB取,然后更新了缓存。
可见两次查询的命中率为0/2=0%。
怎么提升缓存命中率呢? 答案是使用分布式缓存 。
基于Redis的分布式缓存架构
商品的信息只缓存在Redis,没有缓存在.net6服务器。
查询的时候,任何一个.net6服务器的查询请求,都是先查询redis,如果找不到就去DB要,然后回来更新Redis。
分布式缓存也有自己的问题:
1. 缓存击穿问题
redis中存在缓存过期的问题,此时全部查询都会回到DB查询
2. 缓存崩溃问题
redis宕机了,则全部查询会回到DB查询
以上会导至查询性能急速下降,解决办法是使用多级缓存架构。
多级缓存架构
这种架构中,每台.net服务器都增加了本地缓存。
这样DB中的商品信息,在redis中和.net6服务器中都有了缓存。因此这种方式我们称为多级缓存。
多级缓存架构:
1。 redis缓存叫一级缓存
2。 .net6本地缓存是二级缓存
原则:客户端先查询rddis,然后再查询.net本地缓存,先查询的就是一级缓存。
存在的问题:
对并发数量没有提升。
假设Nginx并发量上限是10W,Redis是5W,.Net6是500个
那么下面的架构中,客户端最多只能并发1000个,这个是受到了两台.net6服务器并发上限的约束。
有一个解决方法是:让Nginx直接去访问Redis,不通过.net6服务器。
这样客户端由并发1000个,扩展到可以支持5W个,可以极大提升查询的并发数量。
集群+Redis+Nginx+Lua架构
Nginx+Lua OpenResty,就是在Nginx中使用Lua脚本直接访问redis。
此架构下,客户端由并发1000个,扩展到可以支持5W个,可以极大提升查询的并发数量。
但是由于nginx支持10W个并发,那么怎么样能让客户端也可以支持10W个并发呢?
答案是在Nginx中增加一个三级缓存。
集群+Redis+Nginx+Lua架构的三级缓存
通过在Nginx中增加三级缓存的方式,我们可以让客户端支持10W个并发访问。
下图架构中:Nginx的缓存是一级,Redis是二级,.net6服务器是三级。
至此,解决清楚了为啥在查询中会应用到多级缓存的根本原因。
一句话:多级缓存就是为了解决高并发访问的问题。
多级缓存在计算机系统中非常常见,例如在操作系统中,处理cpu和磁盘之间的数据通讯就是使用了多级缓存(cpu是高速,磁盘是低速)、内存和cpu之间的通讯也是如此。
因此.net中的缓存机制其实是硬件中的多级缓存概念的一种应用。
一个实际的京东商品查询系统的架构:

