缓存与ABP Redis Cache (3)

我们 不应该直接存储实体到缓存中 因为缓存的时候需要序列化缓存对象而实体可能不能被序列化(尤其是实体的导航属性)。这就是为什么我们定义了一个简单的像DTO的类来存储数据到缓存中。我们添加了 AutoMapFrom 特性,这是因为我们想使用 AutoMapper 来自动的转换 Person 实体为 PersonCacheItem 对象。如果我们不使用 AutoMapper,那么我们应该重写 EntityCache 类的 MapToCacheItem 方法手动转换/映射它。

然而这不是必须的,我们可能想定义一个接口为缓存类:
public interface IPersonCache : IEntityCache<PersonCacheItem> { }
最后,我们可以创建缓存类来缓存Person实体:
public class PersonCache : EntityCache<Person, PersonCacheItem>, IPersonCache, ITransientDependency { public PersonCache(ICacheManager cacheManager, IRepository<Person> repository) : base(cacheManager, repository) { } }

这样就OK了,我们的person缓存已经准备好可以使用了。缓存类可以使瞬时(如同这个例子)或者是单例。这不是说缓存数据是瞬态的。在你的应用程序中它一直是全局缓存并且是线程安全的。

现在,无论在什么地方我们需要取得Person的Name,我们可以通过Person的Id从缓存中取得它。如下所示:
public class MyPersonService : ITransientDependency { private readonly IPersonCache _personCache; public MyPersonService(IPersonCache personCache) { _personCache = personCache; } public string GetPersonNameById(int id) { return _personCache[id].Name; //alternative: _personCache.Get(id).Name; } }
我们很容易的注入 IPersonCache 接口,通过该接口取得缓存项和Name属性。

那么EntityCache是怎么工作的?

在首次调用的时候我们通过仓储从数据库中取得实体。那么随后的调用都是从缓存中取得。

如果实体被更新或者删除,它会自动的无效实体。因此,它会在下次调用的时候重新从数据库中检索数据。

使用 IObjectMapper 接口来映射实体到缓存项。IObjectMapper 接口在 AutoMapper 中被实现。所以,如果你使用了自动映射,那么就需要 AutoMapper模块。你可以重写 MapToCacheItem 方法手动映射它到缓存项。

使用缓存类的FullName作为缓存的Name,你可以通过传入的缓存名到基类的构造函数来改变它。

它是线程安全的。
如果你有更复杂的缓存需求,那么你需要扩展 EntityCache 类或者创建你自己的解决方案。

Redis Cache 集成

Redis是什么,Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)与范围查询、bitmaps、hyperloglogs和地理空间(geospatial)索引半径查询。
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
Redis 与其他 key - value 缓存产品有以下三个特点

Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

Redis支持数据的备份,即master-slave模式的数据备份。
Redis 优势

性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

多实用工具 - Redis是一个多实用工具,可用于多种用例,如:缓存,消息队列(Redis本地支持发布/订阅),应用程序中的任何短期数据,例如,web应用程序中的会话,网页命中计数等。

(1)首先,我们前往https://github.com/dmajkic/redis/downloads下载安装包,直接下一步下一步就可以了。
然后打开安装的地址就可以看到如下的文件:

image.png


(2)然后启动Redis服务,我们cmd到安装目录下,然后输入命令redis-server.exe redis.windows.conf
就会看到下面的画面证明我们启动服务成功。

abp默认Cache Mananger是使用in-memory来缓存。所以,这可能会成为一个问题,如果有多个并发的Web服务运行在同一个应用中。在这种情况下,你可能想要一个分布式/中央缓存服务器。那么,你可以使用Redis来作为你的缓存服务。
首先,你需要安装
Abp.RedisCachenuget package 到你的项目中(你可以安装它到你的Web项目)。这里我遇到一个错误。

#95602f20f3e7b97bfd984ee1dc126b9c#


开始的时候我搞了半天不知道为什么会出现这个莫名其妙的错误,后来才发现,原来我引入Abp.RedisCache版本和abp版本不一致。才导致的这个错误,比如你abp是3.1.1,那么你的Abp.RedisCache最好也是对应的版本,最好的话把abp和Abp.RedisCache都升级到最新版本,就不会有错误了。
然后我们看看Abp.Runtime.Caching.Redis;依赖项以及之间的关系。

然后在ABPCMSWebModule配置一下。

ABPCMSApplicationModule中引入。

Web.config中配置

image.png


你也可以添加配置到appSettings来设置Redis数据库的Id。如:
<add key="Abp.Redis.Cache.DatabaseId" value="2"/>
在同一个服务器上使用不同的数据库Id是非常有用的这可以创建不同的Key Spaces(隔离缓存)。
UseRedis有一个重载方法,你可以通过这个方法来传入配置参数,这可以覆盖掉配置文件中的配置。关于Redis的其他配置可以查看Redis文档。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydgxy.html