Cache缓存在计算机领域是一个被普遍使用的概念。硬件中CPU有一级缓存,二级缓存, 浏览器中有缓存,软件开发中也有分布式缓存memcache, redis。缓存无处不在的原因是它能够极大地提高硬件和软件的运行速度。在项
目开发中,性能慢的地方常常是IO操作频繁的地方,读取数据库是我们常见的消耗性能的地方。这个时候,如果将使用频繁的数据缓存到能够高速读取的介质中,下次访问时,不用再去请求数据库,直接从缓存中获取所需的

数据,就能够大大提高性能。这篇文章主要讨论的是在.Net开发中,如何使用CacheManager框架方便的管理项目中的缓存。

一,CacheManager介绍以及优点
CacheManager是开源的.Net缓存管理框架。它不是具体的缓存实现,而是在缓存之上,方便开发人员配置和管理各种不同的缓存,为上层应用程序提供统一的缓存接口的中间层。

下面是CacheManager的一些优点:

让开发人员的生活更容易处理和配资缓存,即使是非常复杂的缓存方案。
CacheManager能够管理多种缓存,包含 内存, appfabric, redis, couchbase, windows azure cache, memorycache等。
提供了额外的功能,如缓存同步、并发更新、事件、性能计数器等…
二,CacheManager开始之旅
CacheManager上手还是非常简单的。下面使用内存缓存结合CacheManager的一个实例,能够帮助我们快速的熟悉CacheManager如何使用。

首先在Visual Studio中创建一个Console Application.

使用Nuget为项目添加CacheManager包引用。CacheManager包含了很多的Package. 其中CacheManager.Core是必须的,其它的针对不同缓存平台上有不同的对应Package.

这个Demo中,我们使用内存作为缓存,所以只是需要CacheManager.Core和CacheManager.SystemRuntimeCaching

接着在Main函数中配置好我们的缓存:
using System;
using CacheManager.Core;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var cache = CacheFactory.Build("getStartedCache", settings =>
{
settings.WithSystemRuntimeCacheHandle("handleName");
});
}
}
}

上面代码中使用CacheFactory创建了一个名称为getStartedCache的缓存实例,这个缓存实例使用的是SystemRunTime Cache, 内存缓存。一个缓存实例是可以配置多个Handle的,我们可以使用内存来作为存储介质,也可以使用Redis分布式缓存作为存储介质,并且可以同时在一个缓存实例中使用,后面我们再介绍多级缓存的配置和使用。

接下来,我们添加一些测试缓存的代码

static void Main(string[] args)
{

var cache = CacheFactory.Build("getStartedCache", settings =>
{
settings.WithSystemRuntimeCacheHandle("handleName");
});

cache.Add("keyA", "valueA");
cache.Put("keyB", 23);
cache.Update("keyB", v => 42);
Console.WriteLine("KeyA is " + cache.Get("keyA")); // should be valueA
Console.WriteLine("KeyB is " + cache.Get("keyB")); // should be 42
cache.Remove("keyA");
Console.WriteLine("KeyA removed? " + (cache.Get("keyA") == null).ToString());
Console.WriteLine("We are done...");
Console.ReadKey();
}

三,CacheManager多级缓存配置

实际开发中,我们常常会需要使用多级缓存。

一种常见的情况是,你有一个分布式式缓存服务器,例如redis,独立的缓存服务器能够让我们的多个系统应用程序都能够共享这些缓存的数据,因为这些缓存项的创建是昂贵的。

和访问数据库相比,分布式缓存速度较快,但是和内存相比,还是不够快。因为分布式缓存使用还需要序列化和网络传输的时间消耗。

这个时候里,做个分级缓存是个好的解决方案,将内存缓存结合分布式缓存使用,使用频率高的数据直接从内存中读取,这将大大提高应用程序的整体性能。

使用内存缓存的读取速度能够达到分布式缓存的100倍,甚至更高。

使用CacheManager, 配置多级缓存是一件非常容易的事情

var cache = CacheFactory.Build<int>("myCache", settings =>
{
settings
.WithSystemRuntimeCacheHandle("inProcessCache")//内存缓存Handle
.And
.WithRedisConfiguration("redis", config =>//Redis缓存配置
{
config.WithAllowAdmin()
.WithDatabase(0)
.WithEndpoint("localhost", 6379);
})
.WithMaxRetries(1000)//尝试次数
.WithRetryTimeout(100)//尝试超时时间
.WithRedisBackPlate("redis")//redis使用Back Plate
.WithRedisCacheHandle("redis", true);//redis缓存handle
});

上面代码中,内存缓存和Redis缓存配置部分很容易看明白。但是BackPlate是什么作用? 接下来,我们看看CacheManager中的BackPlate挡板机制。

四, BackPlate解决分布式缓存中的同步问题

对于大型的软件系统,常常都是分为很多独立的子项目,各个子项目为了节约成本或者是方便数据共享,常常会共用同一个分布缓存服务器。这样在使用多级缓存的时候,就有可能出现数据不一致的情况。

假设在系统A中的更新了缓存中的一个数据项,这个时候CacheManager会在A设置的所有的缓存handle中更新改数据,这里也包括了分布式缓存上的数据。但是在系统B中的内存缓存中,还是会存在着旧的未更新的数据。当系统B从缓存中取这条记录的时候,就会出现内存缓存和分布式缓存中的数据不一致的情况。

为了防止这一点,缓存管理器有一个功能叫做cachebackplate将尝试同步多个系统中的缓存。

上面设置的多级缓存中,我们就将redis作为BackPlate的源. 也就是说所有的数据都需要以redis中缓存的数据为蓝本。

在设置redis作为BackPlate之后,同样发生上面的数据不一致的情况的时候,只要redis中的数据被修改了,就会触发CacheManager更新所有系统中的内存缓存中的数据,和redis中的数据保持一致。

同步的工作是如何完成的?

每次一条缓存记录被删除或更新的时候,Cache Manager会发送一个消息,让BackPlate存储这次的数据变化信息。所有其它的系统将异步接收这些消息,并将相应地作出更新和删除操作,保证数据的一致性。

五,ExpirationMode和CacheUpdateMode

涉及到缓存,就必然有缓存过期的问题。CacheManager中提供了一些简单的缓存过期方式设置。

public enum ExpirationMode
{
None = 0,
Sliding = 1,
Absolute = 2,
}

同时CacheManager还为多级缓存之间设置不同的数据更新策略
public enum CacheUpdateMode
{
None = 0,
Full = 1,
Up = 2,
}

使用Sliding和Up, 我们我可以为多级缓存设置不同的缓存过期时间,这样使用频率高的数据就能够保存在访问速度更快的内存中,访问频率次高的放到分布式缓存中。当CacheManager在内存中找不到缓存数据的时候,就会尝

试在分布式缓存中找。找到后,根据Up设置,会再将该缓存数据保存到内存缓存中。

具体的配置方式如下:

var cache = CacheFactory.Build<int>("myCache", settings =>
{
settings.WithUpdateMode(CacheUpdateMode.)))
.And
.WithRedisConfiguration("redis", config =>//Redis缓存配置
{
config.WithAllowAdmin()
.WithDatabase(0)
.WithEndpoint("localhost", 6379);
}).
.WithExpiration(ExpirationMode.Sliding, TimeSpan. FromHours (24)))
.WithMaxRetries(1000)//尝试次数
.WithRetryTimeout(100)//尝试超时时间
.WithRedisBackPlate("redis")//redis使用Back Plate
.WithRedisCacheHandle("redis", true);//redis缓存handle

});

六,缓存使用分析
在缓存使用中,对于缓存hit和miss数据态比较关系,这些数据能够帮助我们分析和调整缓存的设置,帮助缓存使用地更加合理。

1 var cache = CacheFactory.Build("cacheName", settings => settings
2 .WithSystemRuntimeCacheHandle("handleName")
3 .EnableStatistics()
4 .EnablePerformanceCounters());
在配置好缓存的Statistic功能后,我们就能够跟踪到缓存的使用情况了, 下面就是分别打印各个缓存handle中的分析数据。

foreach (var handle in cache.CacheHandles)
{
var stats = handle.Stats;
Console.WriteLine(string.Format(
"Items: {0}, Hits: {1}, Miss: {2}, Remove: {3}, ClearRegion: {4}, Clear: {5}, Adds: {6}, Puts: {7}, Gets: {8}",
stats.GetStatistic(CacheStatsCounterType.Items),
stats.GetStatistic(CacheStatsCounterType.Hits),
stats.GetStatistic(CacheStatsCounterType.Misses),
stats.GetStatistic(CacheStatsCounterType.RemoveCalls),
stats.GetStatistic(CacheStatsCounterType.ClearRegionCalls),
stats.GetStatistic(CacheStatsCounterType.ClearCalls),
stats.GetStatistic(CacheStatsCounterType.AddCalls),
stats.GetStatistic(CacheStatsCounterType.PutCalls),
stats.GetStatistic(CacheStatsCounterType.GetCalls)
));
}

CacheManager.NET的更多相关文章

  1. CacheManager:–个通用缓存接口抽象类库

    CacheManager是–个缓存通用接口抽象类库,它支持各种高速缓存提供者,例如Memcache,Redis,并且有许多先进的功能特性.具体可以访问官方网站  http://cachemanager ...

  2. .NET缓存框架CacheManager在混合式开发框架中的应用(1)-CacheManager的介绍和使用

    在我们开发的很多分布式项目里面(如基于WCF服务.Web API服务方式),由于数据提供涉及到数据库的相关操作,如果客户端的并发数量超过一定的数量,那么数据库的请求处理则以爆发式增长,如果数据库服务器 ...

  3. .Net缓存管理框架CacheManager(转)

    转载地址:http://www.cnblogs.com/JustRun1983/p/CacheManager.html Cache缓存在计算机领域是一个被普遍使用的概念.硬件中CPU有一级缓存,二级缓 ...

  4. .Net缓存管理框架CacheManager

    using System; using CacheManager.Core; namespace ConsoleApplication { class Program { static void Ma ...

  5. 使用cachemanager做缓存(Session的缓存)

    1.我在这里直接用 cachemanager.redis 往redis里面存储缓存数据2.步骤 1)下载CacheManager.Redis(包含了CacheManager.Core) 下载Stack ...

  6. 解决spring+shiro cacheManager 登录报错

    一.项目启动,登录报错 org.springframework.beans.factory.BeanCreationException: Error creating bean with name ' ...

  7. EhCache WebCache 与 SpringMVC集成时 CacheManager冲突的问题

    转自:点击打开链接 http://www.cnblogs.com/daxin/p/3560989.html EhCache WebCache 与 SpringMVC集成时 CacheManager冲突 ...

  8. hibernate3与ehcache-2.8.3配合使用,在多个SessionFactory实例的情况下出现“Another unnamed CacheManager already exists in the same VM”问题

    不想看分析过程的,直接拉到最下面看第4部分 1. 问题背景 由于某些原因,项目中使用了hibernate3与ehcache-2.8.3在配合使用,又由于某些原因,需要使用多个SessionFactor ...

  9. EHCache 实现通用类 CacheManager

    package com.zhubaje.api.workflow.ehcache; import java.io.Serializable; import java.util.ArrayList; i ...

  10. CacheManager

    .Net缓存管理框架CacheManager Cache缓存在计算机领域是一个被普遍使用的概念.硬件中CPU有一级缓存,二级缓存, 浏览器中有缓存,软件开发中也有分布式缓存memcache, redi ...

随机推荐

  1. 洛谷P1164 小A点菜 DP入门

    原题传输门>>https://www.luogu.org/problem/show?pid=1164<< 前几天开始联系DP的,一路水题做到这,发现这题套不了模板了QAQ 在大 ...

  2. Spring Cloud各组件超时总结

    Ribbon的超时 全局设置: ribbon: ReadTimeout: 60000 ConnectTimeout: 60000 1 2 3 局部设置: service-id: ribbon: Rea ...

  3. Android requestCode的限制

    一. why ? 由于才疏学浅,在开发中requestCode的让我很困惑.困惑是因为什么呢,是因为弄混了.要想弄明白,不困惑,来想一想用到requestCode的地方: ① startActivit ...

  4. 力扣(LeetCode)202. 快乐数

    编写一个算法来判断一个数是不是"快乐数". 一个"快乐数"定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 ...

  5. python特殊成员函数

    1.__init__():构造函数 2.__del__():析构函数 3.print(__doc__):打印描述信息 4.print(Dog.__module__):类来自的模块 5.print(d1 ...

  6. python3+虹软2.0 离线人脸识别 demo

    python3+虹软2.0的所有功能整合测试完成,并对虹软所有功能进行了封装,现提供demo主要功能,1.人脸识别2.人脸特征提取3.特征比对4.特征数据存储与比对其他特征没有添加 虹软SDK下载戳这 ...

  7. 学习笔记21—PS换图片背景

    将照片红底的换成白底的. 操作步骤: 1 先上效果,照片来自网络反正不认识,法律问题找度娘 2 下面开始操作,打开图片进入通道面板,选择照片底色的那个通道,复制并调整色阶,确保黑白分明 3 回到图层面 ...

  8. Qt5标准文件对话框类

    getOpenFileName()函数返回用户选择的文件名,其函数形式如下: QString QFileDialog::getOpenFileName(QWidget *parent = Q_NULL ...

  9. 当启动tomcat时出现tomcat setting should be set in tomcat preference page

    转自:https://blog.csdn.net/withyou_wy/article/details/53081800 出现此状况证明你的tomcat在配置的时候没有配置成功,通过以下两个步骤即可以 ...

  10. JAVA基础知识总结:十六

    一.File类 主要用于文件操作 对存储在磁盘上的文件和目录的抽取和封装 二.IO流 1.概念 File类只能创建或者修改文件或者文件夹的层级结构,如果要访问文件中的内容的话,就需要用到IO流(Inp ...