伊春住房和城乡建设网站,郴州吧百度贴吧,wordpress 目录样式,商业网站建设者Redis 做缓存虽减轻了 DBMS 的压力#xff0c;减小了 RT#xff0c;但在高并发情况下也是可能会出现各 种问题的。
1 缓存穿透 当用户访问的数据既不在缓存也不在数据库中时#xff0c;就会导致每个用户查询都会“穿透” 缓存“直抵”数据库。这种情况就称为缓存穿透。一个…Redis 做缓存虽减轻了 DBMS 的压力减小了 RT但在高并发情况下也是可能会出现各 种问题的。
1 缓存穿透 当用户访问的数据既不在缓存也不在数据库中时就会导致每个用户查询都会“穿透” 缓存“直抵”数据库。这种情况就称为缓存穿透。一个两个请求无所谓当高并发的访问请求到达时缓存穿透不 仅增加了响应时间而且还会引发对 DBMS 的高并发查询这种高并发查询很可能会导致DBMS 的崩溃。 缓存穿透产生的主要原因有两个一是在数据库中没有相应的查询结果二是查询结果为空时不对查询结果进行缓存。所以针对以上两点解决方案也有两个 对非法请求进行限制 。 对结果为空的查询给出默认值 。 可以使用布隆过滤器解决缓存穿透的问题
把已存在数据的key存在布隆过滤器中相当于redis前面挡着一个布隆过滤器。当有新的请求时先到布隆过滤器中查询是否存在:如果布隆过滤器中不存在该条数据则直接返回;如果布隆过滤器中已存在才去查询缓存redis如果redis里没查询到则再查询Mysq|数据库
2 缓存击穿
对于某一个缓存在高并发情况下若其访问量特别巨大当该缓存的有效时限到达时即刚好达到设置的时间此数据在缓存消失了key到期了此时大量用户来访问它 可能会出现大量的访问都要重建该缓存即这些访问请求发现缓存中没有该数据则立即到DBMS 中进行查询那么这就有可能会引发对 DBMS 的高并发查询从而接导致 DBMS 的崩 溃。这种情况称为缓存击穿而该缓存数据称为热点数据。 对于缓存击穿的解决方案较典型的是使用“双重检测锁”机制。 类似于高并发下安全的单例 3 缓存雪崩
对于缓存中的数据很多都是有过期时间的。
若大量缓存的过期时间在同一很短的时间 段内几乎同时到达那么在高并发访问场景下就可能会引发对 DBMS 的高并发查询而这将 可能直接导致 DBMS 的崩溃。这种情况称为缓存雪崩。对于缓存雪崩没有很直接的解决方案最好的解决方案就是预防即提前规划好缓存的 过期时间。要么就是让缓存永久有效当 DB 中数据发生变化时清除相应的缓存。如果 DBMS采用的是分布式部署则将热点数据均匀分布在不同数据库节点中将可能到来的访问负载均衡开来。
解决办法
事前尽量保证整个 Redis 集群的高可用性发现机器宕机尽快补上选择合适的内存淘汰策略。 事中本地ehcache缓存 hystrix限流降级避免MySQL崩掉 通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存其他线程等待。 事后利用 Redis 持久化机制保存的数据尽快恢复缓存
4 数据库缓存双写不一致
以上三种情况都是针对高并发读场景中可能会出现的问题而数据库缓存双写不一致问 题则是在高并发写场景下可能会出现的问题。 对于数据库缓存双写不一致问题以下两种场景下均有可能会发生
1 “修改 DB 更新缓存”场景
对于具有缓存 warmup 功能的系统DBMS 中常用数据的变更都会引发缓存中相关数 据的更新。在高并发写请求场景下若多个请求要对 DBMS 中同一个数据进行修改修改后 还需要更新缓存中相关数据那么就有可能会出现缓存与数据库中数据不一致的情况。 第一种没有问题。
第二种a修改DB中的数据后stock7刚想从本地缓存写入redis缓存此时出问题了有可能是时间片到了也有可能redis出现问题这是b过来了也修改了数据stock2然后更新缓存也是2然后出现问题的a请求又好了更新redis stock为7。覆盖了2
解决方案
最经典的缓存数据库读写的模式就是 预留缓存模式Cache Aside Pattern。
读的时候先读缓存缓存没有的话就读数据库然后取出数据后放入缓存同时返回响应。更新的时候先删除缓存然后再更新数据库这样读的时候就会发现缓存中没有数据而直接去数据库中拿数据了。
题外话 本地缓存和Redis缓存是两种不同的缓存方式。 本地缓存是指将数据缓存在本地内存中通常使用内存缓存库如Memcached、Ehcache等来实现。本地缓存的优点是访问速度快缓存的数据可以快速地被读取同时数据在本地内存中可以减轻数据库的压力。然而本地缓存的缺点是容易受到服务器重启、应用重启等因素的影响同时可用空间有限。 Redis缓存是一种基于内存的也可以持久化到磁盘键值对存储系统具有高性能、高可用性和可扩展性等优点。Redis可以作为分布式缓存来使用可以减轻数据库的压力并提高应用程序的响应速度。Redis还提供了多种数据结构如字符串、哈希、列表、集合和有序集合等还可以设置过期时间可以满足复杂的应用场景。 相比之下本地缓存通常只适用于单机环境适用于只有一个应用程序使用的数据而Redis适用于分布式、多应用程序场景下的数据缓存。虽然Redis的性能和可用性优于本地缓存但是使用Redis也需要考虑到数据一致性、网络延迟等问题。因此具体的缓存方案应该根据应用场景来选择。 2 “修改 DB 删除缓存”场景
在很多系统中是没有缓存 warmup 功能的为了保持缓存与数据库数据的一致性一般 都是在对数据库执行了写操作后就会删除相应缓存。
在高并发读写请求场景下若这些请求对 DBMS 中同一个数据的操作既包含写也包含读 且修改后还要删除缓存中相关数据那么就有可能会出现缓存与数据库中数据不一致的情况。
问题
b先查询 redis中无数据 到DB查为10然后写入本地缓存此时出现问题中断了。然后a过来修改DB中的数据并将redis中相关数据删除。然后b恢复执行将本地缓存的10写入redis。
3 解决方案延迟双删
延迟双删方案是专门针对于“修改 DB 删除缓存”场景的解决方案。但该方案并不能彻 底解决数据不一致的状况其只可能降低发生数据不一致的概率。
延迟双删方案是指在写操作完毕后会立即执行一次缓存的删除操作然后再停上一段 时间一般为几秒后再进行一次删除。而两次删除中间的间隔时长要大于一次缓存写操作的时长。