转载地址:http://www.cnblogs.com/JustRun1983/p/CacheManager.html

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函数中配置好我们的缓存:

 1 using System;
2 using CacheManager.Core;
3 namespace ConsoleApplication
4 {
5 class Program
6 {
7 static void Main(string[] args)
8 {
9 var cache = CacheFactory.Build("getStartedCache", settings =>
10 {
11 settings.WithSystemRuntimeCacheHandle("handleName");
12 });
13 }
14 }
15 }

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

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

 1 static void Main(string[] args)
2 {
3
4 var cache = CacheFactory.Build("getStartedCache", settings =>
5 {
6 settings.WithSystemRuntimeCacheHandle("handleName");
7 });
8
9 cache.Add("keyA", "valueA");
10 cache.Put("keyB", 23);
11 cache.Update("keyB", v => 42);
12 Console.WriteLine("KeyA is " + cache.Get("keyA")); // should be valueA
13 Console.WriteLine("KeyB is " + cache.Get("keyB")); // should be 42
14 cache.Remove("keyA");
15 Console.WriteLine("KeyA removed? " + (cache.Get("keyA") == null).ToString());
16 Console.WriteLine("We are done...");
17 Console.ReadKey();
18 }

三,CacheManager多级缓存配置

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

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

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

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

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

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

 1 var cache = CacheFactory.Build<int>("myCache", settings =>
2 {
3 settings
4 .WithSystemRuntimeCacheHandle("inProcessCache")//内存缓存Handle
5 .And
6 .WithRedisConfiguration("redis", config =>//Redis缓存配置
7 {
8 config.WithAllowAdmin()
9 .WithDatabase(0)
10 .WithEndpoint("localhost", 6379);
11 })
12 .WithMaxRetries(1000)//尝试次数
13 .WithRetryTimeout(100)//尝试超时时间
14 .WithRedisBackplane("redis")//redis使用Backplane
15 .WithRedisCacheHandle("redis", true);//redis缓存handle
16 });

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

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

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

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

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

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

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

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

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

五,ExpirationMode和CacheUpdateMode

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

1 public enum ExpirationMode
2 {
3 None = 0,
4 Sliding = 1,
5 Absolute = 2,
6 }

同时CacheManager还为多级缓存之间设置不同的数据更新策略

1 public enum CacheUpdateMode
2 {
3 None = 0,
4 Full = 1,
5 Up = 2,
6 }

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

具体的配置方式如下:

1 var cache = CacheFactory.Build<int>("myCache", settings =>
2 {
3 settings.WithUpdateMode(CacheUpdateMode.Up)
4 .WithSystemRuntimeCacheHandle("inProcessCache")//内存缓存Handle
5 .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromSeconds(60)))
6 .And
7 .WithRedisConfiguration("redis", config =>//Redis缓存配置
8 {
9 config.WithAllowAdmin()
10 .WithDatabase(0)
11 .WithEndpoint("localhost", 6379);
12 }).
13 .WithExpiration(ExpirationMode.Sliding, TimeSpan. FromHours (24)))
14 .WithMaxRetries(1000)//尝试次数
15 .WithRetryTimeout(100)//尝试超时时间
16         .WithRedisBackplane("redis")//redis使用Backplane
17      .WithRedisCacheHandle("redis", true);//redis缓存handle 
18 });

六,缓存使用分析

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

1 var cache = CacheFactory.Build("cacheName", settings => settings
2 .WithSystemRuntimeCacheHandle("handleName")
3 .EnableStatistics()
4 .EnablePerformanceCounters());

在配置好缓存的Statistic功能后,我们就能够跟踪到缓存的使用情况了, 下面就是分别打印各个缓存handle中的分析数据。

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

七,结尾

缓存是个好东西,用好了能够极大的提高性能。缓存的使用本身是个很大的话题,这边文章只是从缓存管理这个角度介绍了CachManager的使用。

下面是CacheManager相关的资料和链接:

官方主页

http://cachemanager.net/

源代码

https://github.com/MichaCo/CacheManager

官方MVC项目的Sample

https://github.com/MichaCo/CacheManager/tree/master/samples/CacheManager.Samples.Mvc

最近在思考不同情况下缓存使用的区别问题。对于互联网项目来说,数据的一致性要求常常不太高,缓存管理中,关注点可能在缓存的命中率上。对于应用系统,访问请求不大,但是对于数据的一致性要求较高,缓存中的数据更新策略可能更加重要。

怎样才是好的适合应用系统的缓存设计呢? 如果大家有兴趣,欢迎探讨指教。

.Net缓存管理框架CacheManager(转)的更多相关文章

  1. .Net缓存管理框架CacheManager

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

  2. Android 框架修炼-自己封装双缓存管理框架库

    一.概述 Android开发中,网络请求是很重要的一部分,而缓存网络请求来的图片或者响应结果字符串或者结果流,既可以省流量,同时也可以帮助我们 解决无网或弱网情况下加载情况,当然也可以提升程序性能效率 ...

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

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

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

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

  5. 在ASP.NET WebAPI 中使用缓存【Redis】

    初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...

  6. CacheManager

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

  7. 谈缓存和Redis

    自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...

  8. [转]在ASP.NET WebAPI 中使用缓存【Redis】

    初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...

  9. .NET缓存框架CacheManager---1、CacheManager的介绍

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

随机推荐

  1. Python JPype 在 Win7 下安装与使用

    JPype 是 Python调用 Java 代码的模块,需要Java SE Runtime Environment (JRE)的支持. 个人安装环境: Windows 7 64bit + Python ...

  2. Reset Identity Column Value in SQL Server (Identity Reset)

    前言:今天在群里看到有人在问SQL Server自增值重置问题(sqlserver identiy column value reset ) 闲话少说,直接上代码: 正文: --create tabl ...

  3. 脚手架搭建的vue项目里引入jquery和bootstrap

    引入jquery: 1.在cmd输入:npm install jquery,回车,等待.. 2.在webpack.base.conf.js里进行如下操作: 3.在webpack.prod.conf.j ...

  4. strrchr 一个获取扩展名的方便的php函数

    上传文件时,$_FILES里面的name是稳健的名称,要获取扩展名就用 strrchr(str,符号)来截取最后一个.后面的扩展名 然后用 trim 去掉特殊字符. 就可以得到扩展名了

  5. rootkit后门检查工具RKHunter

    ---恢复内容开始--- rkhunter简介: 中文名叫"Rootkit猎手", rkhunter是Linux系统平台下的一款开源入侵检测工具,具有非常全面的扫描范围,除了能够检 ...

  6. SpringMVC学习记录3

    这次的主题 最近一直在学习SpringMVC..(这句话我已经至少写了3,4遍了....).这次的研究主要是RequestMappingHandlerAdapter中的各种ArgumentsResol ...

  7. SQL Server数据库定时自动备份

    SQL Server 数据库定时自动备份[转]   在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求 ...

  8. C#RSA算法实现+如何将公钥为XML格式转为PEM格式,给object-C使用

    .net中,处于安全的考虑,RSACryptoServiceProvider类,解密时只有同时拥有公钥和私钥才可以.原因是公钥是公开的,会被多人持有.这样的数据传输是不安全的.C#RSA私钥加密,公钥 ...

  9. iOS中RSA加密详解

    先贴出代码的地址,做个说明,因为RSA加密在iOS的代码比较少,网上开源的也很少,最多的才8个星星.使用过程中发现有错误.然后我做了修正,和另一个库进行了整合,然后将其支持CocoaPod. http ...

  10. Android Duplicate files copied in APK

    今天调试 Android 应用遇到这么个问题: Duplicate files copied in APK META-INF/DEPENDENCIES File 1: httpmime-4.3.2.j ...