ASP.NET Core缓存如何实现高效查询?

摘要:[TOC] 缓存的基本概念 缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。 缓存原理 将数据写入到读取速度更快的存储设备; 将数据缓存到离应用最近的位置; 将数据缓存到离用户最
目录缓存的基本概念缓存原理缓存设计分布式缓存 Memcache 与 Redis 的比较缓存穿透,缓存击穿,缓存雪崩解决方案数据一致性使用内置 MemoryCache使用分布式缓存 Redis使用 Stackexchange.Redis 自己封装一个 RedisHelper 类参考 缓存的基本概念 缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。 缓存原理 将数据写入到读取速度更快的存储设备; 将数据缓存到离应用最近的位置; 将数据缓存到离用户最近的位置。 缓存设计 缓存内容 热点数据,静态资源 缓存位置 CDN,反向代理,分布式缓存服务器,本机(内存,硬盘) CDN:存放HTML、CSS、JS等静态资源; 反向代理:动静分离,只缓存用户请求的静态资源; 分布式缓存:缓存数据库中的热点数据; 本地缓存:缓存应用字典等常用数据。 过期策略 固定时间,相对时间 同步机制 实时写入,异步刷新 分布式缓存 Memcache 与 Redis 的比较 数据结构:Memcache只支持key value存储方式,Redis支持更多的数据类型,比如Key value、hash、list、set、zset; 多线程:Memcache支持多线程,Redis支持单线程;CPU利用方面Memcache优于Redis; 持久化:Memcache不支持持久化,Redis支持持久化(快照和AOF日志两种持久化方式); 内存利用率:Memcache高,Redis低(采用压缩的情况下比Memcache高)。使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcache。 过期策略:Memcache过期后,不删除缓存,会导致下次取数据数据的问题,Redis有专门线程,清除缓存数据; 缓存穿透,缓存击穿,缓存雪崩解决方案 缓存穿透 缓存穿透是指查询一个一定不存在的数据。由于会频繁的请求数据库,对数据库造成访问压力。 解决方法: 对结果为空的数据也进行缓存,不过设置它的过期时间会很短,最长不超过五分钟。 一定不存在的key,采用布隆过滤器,建立一个大的Bitmap中,查询时通过该bitmap过滤。 布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一> 个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难 如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. > 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈> 希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。 缓存雪崩 缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。 解决方法: 通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。 分散缓存失效时间,比如在设置过期时间的时候增加一个随机数尽可能的保证缓存不会大面积的同时失效。 缓存击穿 缓存击穿是指对于一些设置了过期时间的key,如果这些key可能会在过期后的某个时间点被超高并发地访问。这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。 解决方法: 使用互斥锁来解决问题,通俗的描述就是,一万个用户访问了,但是只有一个用户可以拿到访问数据库的权限,当这个用户拿到这个权限之后重新创建缓存,这个时候剩下的访问者因为没有拿到权限,就原地等待着去访问缓存。 数据一致性 数据不一致的几种情况: 数据库有数据,缓存没有数据; 数据库有数据,缓存也有数据,数据不相等; 数据库没有数据,缓存有数据。 目前比较常用的数据缓存策略的是Cache Aside Pattern,更新缓存是先把数据存到数据库中,成功后,再让缓存失效。 这种策略下不一致产生的原因只有更新数据库成功,但是删除缓存失败。 解决方案: 对删除缓存进行重试. 定期全量更新缓存。 合理设置缓存过期时间。
阅读全文