.net core WebApi使用Redis教程(二)Redis缓存应用基础讲解
小白浏览:8382024-01-09 14:15:44本文累计收益:0我也要赚钱

本文讲解Redis在应用缓存领域的使用方法,实例代码基于 .net core WebApi进行实现。实例代码下载链接:http://www.80cxy.com/Blog/ResourceView?arId=202401110950583321kEqrCT 

一、什么是缓存

缓存是数据交换的缓冲区(称作Cache),是存贮数据的临时地方,一般读写性能较高。缓存有浏览器缓存、应用层缓存、数据库缓存。Redis主要用于应用层缓存。

缓存的作用:

降低后端负载,经常访问的数据将存储在Redis中,不用读取数据库进行获取。

提高读写效率,降低响应时间,Redis数据存储在内存中,数据库数据在磁盘中,内存获取数据响应时间较快。

缓存的成本:

数据一致性成本,Redis数据与数据库数据需保持一致,有些场景可能存在不一致的情况。

代码维护成本,为保持Redis和数据库存储数据的一致性,需要通过额外代码编写实现。

运维成本,为避免缓存雪崩,保证缓存高可用,需要搭建集群模式,需要进行软硬件的定期维护。

二、添加Redis缓存

添加Redis缓存的目的是能更快的获取数据,并降低后端负载,增加Redis缓存后数据获取流程为,先从Redis中获取,如果有则直接返回,如果没有则再从数据库获取,获取到数据返回并将数据写入Redis,流程图如下:

增加Redis缓存后的数据获取具体程序流程如下图所示:

以下代码是获取一个商铺实体信息的实现:

        public async Task<ResponseContent> GetShopById(string id)
        {
            ResponseContent response = new ResponseContent();
            Shop shop = null;
            //1.从Redis缓存查询商品
            string shopStr = cacheService.Get(RedisConstants.CACHE_SHOP_KEY + id);
            //2.判断是否存在
            if (!string.IsNullOrEmpty(shopStr))
            {
                //3.存在直接返回
                shop = JsonConvert.DeserializeObject<Shop>(shopStr);
                return response.Ok(new { shop });
            }
            //4.不存在,根据Id查询数据库
            shop = await redisRepostory.GetShopById(id);
            if (shop == null)
            {
                //5.不存在,返回错误
                return response.Error(ResponseType.ParameterVerificationError);
            }
            //6.存在写入Redis
            cacheService.Add(RedisConstants.CACHE_SHOP_KEY + id, JsonConvert.SerializeObject(shop));
            //7.返回
            return response.Ok(shop);
        }
三、缓存更新策略

Redis缓存更新策略主要包含以下三种:

(一)内存淘汰

不用自己维护,利用Redis内容淘汰机制,当内容不足时自动淘汰部分数据。下次查询时更新缓存。一致性效果差,维护成本几乎为零。

(二)超时剔除

给缓存数据添加TTL时间,到期后自动删除缓存。下次查询时更新缓存。一致性一般,维护成本比较低。

(三)主动更新

自己编写业务逻辑,在修改数据库的同时,更新缓存。一致性非常好,需要自己写代码,编码比较复杂,维护成本较高。

1、缓存更新策略业务场景:

低一致性需求:使用内存淘汰机制。例如商品分类数据。

高一致性需求:主动更新,并以超时剔除昨晚兜底方案。例如店铺详情数据。

2、主动更新策略详解:

(1)由缓存的调用者,在更新数据库的同时更新缓存。实际开发中比较常用。

操作缓存和数据库时有需要注意下面几个问题:
◆一般选择删除缓存,而不是更新缓存,查询时在更新缓存。
◆单体系统,将缓存与数据库操作放在一个事务,保证缓存与数据库操作同时成功。
◆分布式系统,采用TCC等分布式事务方案,保证缓存与数据库操作同时成功。
◆先操作数据库,再删除缓存。

(2)缓存与数据库整合为一个服务,由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。

(3)调用者只操作缓存,由其他线程异步的将缓存数据持久化到数据库,保证最终一致性。

(四)、代码实现

以下将上面获取商铺代码进行升级,实现缓存更新策略,第一段代码是获取商铺信息代码,第二段是修改商铺信息代码,获取商铺代码加入过期时间,修改商铺代码加入删除缓存。

        public async Task<ResponseContent> GetShopById(string id)
        {
            ResponseContent response = new ResponseContent();
            Shop shop = null;
            //1.从Redis缓存查询商品
            string shopStr = cacheService.Get(RedisConstants.CACHE_SHOP_KEY + id);
            //2.判断是否存在
            if (!string.IsNullOrEmpty(shopStr))
            {
                //3.存在直接返回
                shop = JsonConvert.DeserializeObject<Shop>(shopStr);
                return response.Ok(new { shop });
            }
            //4.不存在,根据Id查询数据库
            shop = await redisRepostory.GetShopById(id);
            if (shop == null)
            {
                //5.不存在,返回错误
                return response.Error(ResponseType.ParameterVerificationError);
            }
            //6.存在写入Redis,并设置缓存超时时间
            cacheService.Add(RedisConstants.CACHE_SHOP_KEY + id, JsonConvert.SerializeObject(shop), RedisConstants.CACHE_SHOP_TTL);
            //7.返回
            return response.Ok(shop);
        }
       public async Task<ResponseContent> UpdateShop(string id, string name, string address)
        {
            ResponseContent response = new ResponseContent();
            try {
                //更新数据库
                await redisRepostory.UpdateShop(id, name, address);
                //删除Redis缓存,每次查询商铺信息在重新获取
                cacheService.Remove(RedisConstants.CACHE_SHOP_KEY + id);
                return response.Ok(ResponseType.OperSuccess);
            }
            catch (Exception e) {
                return response.Error(ResponseType.OperError);
            }
        }


初学,如有不对的地方,欢迎评论区指正。

评论列表
发表评论
+ 关注