基于.net的通用内存缓存模型组件
2017-11-08 08:46
211 查看
谈到缓存,我们自然而然就会想到缓存的好处,比如:
降低高并发数据读取的系统压力:静态数据访问、动态数据访问
存储预处理数据,提升系统响应速度和TPS
降低高并发数据写入的系统压力
提升系统可用性,后台宕机后,系统还存在可用的机会
缓存技术一直是优化程序性能的一个重要手段,在互联网技术体系中,也不例外。但是在分布式架构下,大家开始更多的使用分布式缓存,比如Redis、MemcacheD等等,对进程内的内存缓存使用的越来越少。其主要原因无外乎几点:
一是,数据不能做到强一致性,程序内存数据缓存同步的周期相对分布缓存更慢一些。
二是,需要对缓存的各种同步策略进行封装,并控制同步时机。进程内缓存的使用比分布式缓存的使用具有更高的技术门槛。没有分布缓存使用简单。
虽然分布式缓存具有非常多很好的特性,但是当完全抛弃了程序内存缓存后,分布式缓存将会被滥用,应用程序甚至过度的依赖分布式缓存。笔者认为,任何一种技术的滥用,都将可能导致系统架构在健壮性上存在缺陷。分布式缓存虽然很好用,性能也不错,但是与进程内存缓存比起来,性能还是差了好多个数量级。要想把系统的性能做到极致,仅仅依赖Redis等分布式缓存还不不够的,还需要充分利用进程内存缓存。
缓存技术,从出现到现在,总结来说,已有四个阶段的发展:本地缓存、分布式缓存、弹性缓存平台,弹性应用平台。本地缓存的特点是数据存储在应用代码所在内存空间,可提供快速的数据访问,纳秒级性能。缺点也很明显,数据无法分布式共享,无容错处理。分布式缓存的特点是数据在固定数目的集群节点间分布存储,缓存容量可扩展(静态扩展),但是扩展过程中需大量配置,无容错机制。弹性缓存平台的特性是数据在集群节点间分布存储,基于冗余机制实现高可用性。其优点是可动态扩展,具有容错能力,但是复制备份会对系统性能造成一定影响。弹性应用平台的特点是弹性缓存与代码执行的组合体,将业务逻辑代码转移到数据所在节点执行,极大地降低数据传输开销,提升系统性能。纵观整个缓存技术的发展,经历了从分散到集中,又到集中并分散的一个过程。弹性应用平台作为最终的缓存解决方案,已经不仅仅停留在缓存技术本身,而是更多的考虑了如何更好的与业务代码无缝集成,并提供进程内存级别的性能。
基于此,我们规划设计了一个通用的内存缓存组件。通过此组件,可以实现各种内存数据的缓存,以及缓存数据同步等,并提供了分布式缓存数据同步到进程内存的方案。此组件与传统的缓存组件有很大的不同,它是对进程内存缓存的使用和同步做了抽象和总结,直接提供了一套模型。上文也提到,使用进程内存缓存最大的挑战在与数据同步,那么,我们先看一下影响进程内存缓存同步的一些因素。通过下图,我们看到在同步策略、同步时机、同步模式上都有很多选择。进程内存缓存的使用,其实就是下面三个维度组合处理的一个结果。
在实际的业务中,同步策略更多的会基于时间、数据版本或者时间来做,然后选择合适的同步时机和模式来执行数据同步。所以,在组件的封装上,我们支持了三种应用模型:
对缓存数据标记有效期,过期自动清理
缓存数据时,同时缓存数据版本,定时校验或实时校验数据版本,发现版本不一致时清理或重新同步缓存数据
缓存数据并订阅数据变化通知,当收到变化通知后,更新缓存数据
模型一:对缓存数据标记有效期,过期自动清理
此模型主要适用于, 比如:字符串资源信息查询、App充电地图数据、App最新动态、高频率日志记录、配置中心数据的缓存等等。
数据实时性要求很低,访问频率很高,变化频率较小的数据查询
访问频率很高,查询参数基本一致的数据查询
访问频率很高,允许丢失的辅助信息写入
代码示例:
//nuget:Teld.Core
//引用:Teld.Core.Cache.ServiceEx.dll
//创建一个带过期时间的本地内存容器
using(var container = LocalCacheService.CreateExpirationContainer("TTP-Cache-CFG"))
{
//向容器中增加项目,3秒钟的有效期
container.Add("Name", "张三", new TimeSpan(0, 0, 3));
//想容器中增加项目,永久有效
container.Add("Address", "鑫盛大厦1号楼12层北特来电");
}
模型二:缓存数据时,同时缓存数据版本,定时校验或实时校验数据版本,发现版本不一致时清理或重新同步缓存数据
此模型主要适用于, 比如:帮助查询等。
数据实时性要求不高,访问频率很高的数据查询
访问频率很高,查询参数基本一致的数据查询
代码示例1: 定时同步,每分钟执行一次版本同步
static voidMain(string[] args)
{
//创建缓存数据同步代理
CacheValidateEventHandler<UserInfo> handler = new CacheValidateEventHandler<UserInfo>(SyncUserData);
//创建一个带版本校验的本地内存缓存容器,每隔60s,自动进行一次数据全量同步
using(varcontainer = LocalCacheService.CreateVersionContainer<UserInfo>("TTP-Cache-User", handler, SyncTime.Timing, SyncModel.All, 60))
{
container.SyncFailed += Container_SyncFailed; //数据同步失败,事件通知
container.SyncData(); //立即执行一次数据同步
var user = container.Get("Name"); //从缓存中获取数据
Console.WriteLine(JsonConvert.SerializeObject(user));
}
Console.ReadLine();
}
//数据同步,返回全量或者增量数据,并返回数据的最新版本
static Dictionary<string, UserInfo> SyncUserData(CacheValidateEventArgs e,out string newVersion)
{
//通过e.Version获取上次同步的数据数据
Dictionary<string, UserInfo> result = new Dictionary<string, Cache.UserInfo>();
Random r = new Random(DateTime.Now.Second);
result.Add("Name", new Cache.UserInfo() { Name = "Name", Age =r.Next(1,20) , IsMale = true , LastModifyTime = DateTime.Now});
newVersion = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
return result;
}
代码示例2: 调用缓存Get方法时,自动同步缓存
static void Main (string[] args)
{ //创建缓存数据同步代理
CacheValidateEventHandler<UserInfo> handler = new CacheValidateEventHandler<UserInfo>(SyncUserData);
//创建一个带版本校验的本地内存缓存容器
varcontainer = LocalCacheService.CreateVersionContainer<UserInfo>("TTP-Cache-User", handler, SyncTime.GetCheck, SyncModel.All);
container.SyncFailed += Container_SyncFailed; //数据同步失败,事件通知
var user = container.Get("Name"); //从缓存数据中获取数据
Console.WriteLine(JsonConvert.SerializeObject(user));
Console.ReadLine();
}
模型三:缓存数据并订阅数据变化通知,当收到变化通知后,更新缓存数据
此模型主要适用于, 比如:电站状态缓存等。
数据实时性要求比较高,访问频率很高的数据查询
代码示例1: 带事件更新通知的缓存
public void GetString_Invoke()
{
//创建一个带MQ变化通知的本地内存缓存容器
using (var container = LocalCacheService.CreateEventContainer<string>("TTP-Cache-EventCacheUnitTest",
(CacheValidateEventArgs e, out string newVersion) =>
{
newVersion = Guid.NewGuid().ToString();
return BuildStringData();
}, SyncModel.All, 1))
{
container.SyncData(); //为容器初始化数据
var data = container.Get("lastModifytime"); //获取数据项
Assert.IsNotNull(data);
var data1 = container.Get("lastModifytime");
Assert.AreEqual(data, data1);
//发送数据项的更新通知事件
LocalCacheService.SendDataChangedEvent(container.Name, "lastModifytime");
Thread.Sleep(5000);
var data2 = container.Get("lastModifytime");
Assert.AreNotEqual(data2, data);
}
}
代码示例2:数据删除的事件通知
[align=left]public void GetString_Delete()[/align]
{
//创建一个带MQ变化通知的本地内存缓存容器
[align=left] using (var container = LocalCacheService.CreateEventContainer<string>("TTP-Cache-EventCacheUnitTest",[/align]
[align=left] (CacheValidateEventArgs e, out string newVersion) =>[/align]
[align=left] {[/align]
[align=left] newVersion = Guid.NewGuid().ToString();[/align]
[align=left] return BuildStringData();[/align]
[align=left] }, SyncModel.All, 1))[/align]
[align=left] {[/align]
[align=left] container.SyncData(); //为容器初始化数据[/align]
[align=left] var data = container.Get("lastModifytime"); //获取数据项[/align]
[align=left] Assert.IsNotNull(data);[/align]
[align=left] var data1 = container.Get("lastModifytime");[/align]
[align=left] Assert.AreEqual(data, data1);[/align]
[align=left] LocalCacheService.SendDataChangedEvent(container.Name, "lastModifytime", EventType.Delete); //发送数据项的删除通知事件[/align]
[align=left] Thread.Sleep(5000);[/align]
[align=left] var data2 = container.Get("lastModifytime");[/align]
[align=left] Assert.IsNull(data2);[/align]
[align=left] }[/align]
[align=left] }[/align]
以上是此缓存组件应用的三种模型。三种模型,可通过 LocalCacheService 创建。其代码如下:
public class LocalCacheService
[align=left] {[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建过期自动清理的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="limitSize">限制使用的内存大小(M)</param>[/align]
[align=left] public static IExpirationCacheContainer CreateExpirationContainer(string key,long? limitSize =null)[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] return new InMemoryExpirationContainer(key, limitSize);[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建基于版本比较的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <typeparam name="T"></typeparam>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="handler">基于版本比较的数据处理器</param>[/align]
[align=left] /// <param name="syncTime">同步时机</param>[/align]
[align=left] /// <param name="model">同步模式</param>[/align]
[align=left] /// <param name="syncTimeMin">同步时机为Timing时,同步时间间隔</param>[/align]
[align=left] /// <returns></returns>[/align]
[align=left] public static IVersionCacheContainer<T> CreateVersionContainer<T>(string key, CacheValidateEventHandler<T> handler, SyncTime syncTime = SyncTime.Invoke,SyncModel model = SyncModel.All,int syncTimeSec=180) where T : class[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] if (handler == null)[/align]
[align=left] {[/align]
[align=left] throw new ArgumentNullException(nameof(handler));[/align]
[align=left] }[/align]
[align=left] if (syncTimeSec == 0)[/align]
[align=left] syncTimeSec = 180;[/align]
[align=left] return new InMemoryVersionCacheContainer<T>(key, handler, syncTime, model, TimeSpan.FromSeconds(syncTimeSec));[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建基于事件通知的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <typeparam name="T"></typeparam>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="handler">基于版本比较的数据处理器</param>[/align]
[align=left] /// <param name="model">同步模式</param>[/align]
[align=left] /// <param name="syncTimeMin">同步时机为Timing时,同步时间间隔</param>[/align]
[align=left] /// <returns></returns>[/align]
[align=left] public static IVersionCacheContainer<T> CreateEventContainer<T>(string key,CacheValidateEventHandler<T> handler, SyncModel model = SyncModel.All, int syncTimeSec = 180) where T : class[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] if (handler == null)[/align]
[align=left] {[/align]
[align=left] throw new ArgumentNullException(nameof(handler));[/align]
[align=left] }[/align]
[align=left] if (syncTimeSec == 0)[/align]
[align=left] syncTimeSec = 180;[/align]
[align=left] return new InMemoryEventCacheContainer<T>(key,model,handler, TimeSpan.FromSeconds(syncTimeSec));[/align]
[align=left] } [/align]
[align=left] }[/align]
同步模式和同步时机的定义如下:
/// <summary>
/// 同步模式
/// </summary>
public enum SyncModel : int
{
All, //全量同步,清楚历史缓存信息,重新插入
Increase, //增量同步,同步变化部分,不对历史缓存数据清理
Clear //仅清理历史数据
}
/// <summary>
/// 同步时机
/// </summary>
public enum SyncTime : int
{
Invoke, //调用方执行SyncData方法主动同步
Timing, //定时同步
GetCheck //Get方法是自动同步
}
以上是我们在进程内存组件的一些实践心得,更多技术细节,欢迎同学们来电沟通。微信号:vveiliang
降低高并发数据读取的系统压力:静态数据访问、动态数据访问
存储预处理数据,提升系统响应速度和TPS
降低高并发数据写入的系统压力
提升系统可用性,后台宕机后,系统还存在可用的机会
缓存技术一直是优化程序性能的一个重要手段,在互联网技术体系中,也不例外。但是在分布式架构下,大家开始更多的使用分布式缓存,比如Redis、MemcacheD等等,对进程内的内存缓存使用的越来越少。其主要原因无外乎几点:
一是,数据不能做到强一致性,程序内存数据缓存同步的周期相对分布缓存更慢一些。
二是,需要对缓存的各种同步策略进行封装,并控制同步时机。进程内缓存的使用比分布式缓存的使用具有更高的技术门槛。没有分布缓存使用简单。
虽然分布式缓存具有非常多很好的特性,但是当完全抛弃了程序内存缓存后,分布式缓存将会被滥用,应用程序甚至过度的依赖分布式缓存。笔者认为,任何一种技术的滥用,都将可能导致系统架构在健壮性上存在缺陷。分布式缓存虽然很好用,性能也不错,但是与进程内存缓存比起来,性能还是差了好多个数量级。要想把系统的性能做到极致,仅仅依赖Redis等分布式缓存还不不够的,还需要充分利用进程内存缓存。
缓存技术,从出现到现在,总结来说,已有四个阶段的发展:本地缓存、分布式缓存、弹性缓存平台,弹性应用平台。本地缓存的特点是数据存储在应用代码所在内存空间,可提供快速的数据访问,纳秒级性能。缺点也很明显,数据无法分布式共享,无容错处理。分布式缓存的特点是数据在固定数目的集群节点间分布存储,缓存容量可扩展(静态扩展),但是扩展过程中需大量配置,无容错机制。弹性缓存平台的特性是数据在集群节点间分布存储,基于冗余机制实现高可用性。其优点是可动态扩展,具有容错能力,但是复制备份会对系统性能造成一定影响。弹性应用平台的特点是弹性缓存与代码执行的组合体,将业务逻辑代码转移到数据所在节点执行,极大地降低数据传输开销,提升系统性能。纵观整个缓存技术的发展,经历了从分散到集中,又到集中并分散的一个过程。弹性应用平台作为最终的缓存解决方案,已经不仅仅停留在缓存技术本身,而是更多的考虑了如何更好的与业务代码无缝集成,并提供进程内存级别的性能。
基于此,我们规划设计了一个通用的内存缓存组件。通过此组件,可以实现各种内存数据的缓存,以及缓存数据同步等,并提供了分布式缓存数据同步到进程内存的方案。此组件与传统的缓存组件有很大的不同,它是对进程内存缓存的使用和同步做了抽象和总结,直接提供了一套模型。上文也提到,使用进程内存缓存最大的挑战在与数据同步,那么,我们先看一下影响进程内存缓存同步的一些因素。通过下图,我们看到在同步策略、同步时机、同步模式上都有很多选择。进程内存缓存的使用,其实就是下面三个维度组合处理的一个结果。
在实际的业务中,同步策略更多的会基于时间、数据版本或者时间来做,然后选择合适的同步时机和模式来执行数据同步。所以,在组件的封装上,我们支持了三种应用模型:
对缓存数据标记有效期,过期自动清理
缓存数据时,同时缓存数据版本,定时校验或实时校验数据版本,发现版本不一致时清理或重新同步缓存数据
缓存数据并订阅数据变化通知,当收到变化通知后,更新缓存数据
模型一:对缓存数据标记有效期,过期自动清理
此模型主要适用于, 比如:字符串资源信息查询、App充电地图数据、App最新动态、高频率日志记录、配置中心数据的缓存等等。
数据实时性要求很低,访问频率很高,变化频率较小的数据查询
访问频率很高,查询参数基本一致的数据查询
访问频率很高,允许丢失的辅助信息写入
代码示例:
//nuget:Teld.Core
//引用:Teld.Core.Cache.ServiceEx.dll
//创建一个带过期时间的本地内存容器
using(var container = LocalCacheService.CreateExpirationContainer("TTP-Cache-CFG"))
{
//向容器中增加项目,3秒钟的有效期
container.Add("Name", "张三", new TimeSpan(0, 0, 3));
//想容器中增加项目,永久有效
container.Add("Address", "鑫盛大厦1号楼12层北特来电");
}
模型二:缓存数据时,同时缓存数据版本,定时校验或实时校验数据版本,发现版本不一致时清理或重新同步缓存数据
此模型主要适用于, 比如:帮助查询等。
数据实时性要求不高,访问频率很高的数据查询
访问频率很高,查询参数基本一致的数据查询
代码示例1: 定时同步,每分钟执行一次版本同步
static voidMain(string[] args)
{
//创建缓存数据同步代理
CacheValidateEventHandler<UserInfo> handler = new CacheValidateEventHandler<UserInfo>(SyncUserData);
//创建一个带版本校验的本地内存缓存容器,每隔60s,自动进行一次数据全量同步
using(varcontainer = LocalCacheService.CreateVersionContainer<UserInfo>("TTP-Cache-User", handler, SyncTime.Timing, SyncModel.All, 60))
{
container.SyncFailed += Container_SyncFailed; //数据同步失败,事件通知
container.SyncData(); //立即执行一次数据同步
var user = container.Get("Name"); //从缓存中获取数据
Console.WriteLine(JsonConvert.SerializeObject(user));
}
Console.ReadLine();
}
//数据同步,返回全量或者增量数据,并返回数据的最新版本
static Dictionary<string, UserInfo> SyncUserData(CacheValidateEventArgs e,out string newVersion)
{
//通过e.Version获取上次同步的数据数据
Dictionary<string, UserInfo> result = new Dictionary<string, Cache.UserInfo>();
Random r = new Random(DateTime.Now.Second);
result.Add("Name", new Cache.UserInfo() { Name = "Name", Age =r.Next(1,20) , IsMale = true , LastModifyTime = DateTime.Now});
newVersion = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
return result;
}
代码示例2: 调用缓存Get方法时,自动同步缓存
static void Main (string[] args)
{ //创建缓存数据同步代理
CacheValidateEventHandler<UserInfo> handler = new CacheValidateEventHandler<UserInfo>(SyncUserData);
//创建一个带版本校验的本地内存缓存容器
varcontainer = LocalCacheService.CreateVersionContainer<UserInfo>("TTP-Cache-User", handler, SyncTime.GetCheck, SyncModel.All);
container.SyncFailed += Container_SyncFailed; //数据同步失败,事件通知
var user = container.Get("Name"); //从缓存数据中获取数据
Console.WriteLine(JsonConvert.SerializeObject(user));
Console.ReadLine();
}
模型三:缓存数据并订阅数据变化通知,当收到变化通知后,更新缓存数据
此模型主要适用于, 比如:电站状态缓存等。
数据实时性要求比较高,访问频率很高的数据查询
代码示例1: 带事件更新通知的缓存
public void GetString_Invoke()
{
//创建一个带MQ变化通知的本地内存缓存容器
using (var container = LocalCacheService.CreateEventContainer<string>("TTP-Cache-EventCacheUnitTest",
(CacheValidateEventArgs e, out string newVersion) =>
{
newVersion = Guid.NewGuid().ToString();
return BuildStringData();
}, SyncModel.All, 1))
{
container.SyncData(); //为容器初始化数据
var data = container.Get("lastModifytime"); //获取数据项
Assert.IsNotNull(data);
var data1 = container.Get("lastModifytime");
Assert.AreEqual(data, data1);
//发送数据项的更新通知事件
LocalCacheService.SendDataChangedEvent(container.Name, "lastModifytime");
Thread.Sleep(5000);
var data2 = container.Get("lastModifytime");
Assert.AreNotEqual(data2, data);
}
}
代码示例2:数据删除的事件通知
[align=left]public void GetString_Delete()[/align]
{
//创建一个带MQ变化通知的本地内存缓存容器
[align=left] using (var container = LocalCacheService.CreateEventContainer<string>("TTP-Cache-EventCacheUnitTest",[/align]
[align=left] (CacheValidateEventArgs e, out string newVersion) =>[/align]
[align=left] {[/align]
[align=left] newVersion = Guid.NewGuid().ToString();[/align]
[align=left] return BuildStringData();[/align]
[align=left] }, SyncModel.All, 1))[/align]
[align=left] {[/align]
[align=left] container.SyncData(); //为容器初始化数据[/align]
[align=left] var data = container.Get("lastModifytime"); //获取数据项[/align]
[align=left] Assert.IsNotNull(data);[/align]
[align=left] var data1 = container.Get("lastModifytime");[/align]
[align=left] Assert.AreEqual(data, data1);[/align]
[align=left] LocalCacheService.SendDataChangedEvent(container.Name, "lastModifytime", EventType.Delete); //发送数据项的删除通知事件[/align]
[align=left] Thread.Sleep(5000);[/align]
[align=left] var data2 = container.Get("lastModifytime");[/align]
[align=left] Assert.IsNull(data2);[/align]
[align=left] }[/align]
[align=left] }[/align]
以上是此缓存组件应用的三种模型。三种模型,可通过 LocalCacheService 创建。其代码如下:
public class LocalCacheService
[align=left] {[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建过期自动清理的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="limitSize">限制使用的内存大小(M)</param>[/align]
[align=left] public static IExpirationCacheContainer CreateExpirationContainer(string key,long? limitSize =null)[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] return new InMemoryExpirationContainer(key, limitSize);[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建基于版本比较的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <typeparam name="T"></typeparam>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="handler">基于版本比较的数据处理器</param>[/align]
[align=left] /// <param name="syncTime">同步时机</param>[/align]
[align=left] /// <param name="model">同步模式</param>[/align]
[align=left] /// <param name="syncTimeMin">同步时机为Timing时,同步时间间隔</param>[/align]
[align=left] /// <returns></returns>[/align]
[align=left] public static IVersionCacheContainer<T> CreateVersionContainer<T>(string key, CacheValidateEventHandler<T> handler, SyncTime syncTime = SyncTime.Invoke,SyncModel model = SyncModel.All,int syncTimeSec=180) where T : class[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] if (handler == null)[/align]
[align=left] {[/align]
[align=left] throw new ArgumentNullException(nameof(handler));[/align]
[align=left] }[/align]
[align=left] if (syncTimeSec == 0)[/align]
[align=left] syncTimeSec = 180;[/align]
[align=left] return new InMemoryVersionCacheContainer<T>(key, handler, syncTime, model, TimeSpan.FromSeconds(syncTimeSec));[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 创建基于事件通知的本地内存缓存容器[/align]
[align=left] /// </summary>[/align]
[align=left] /// <typeparam name="T"></typeparam>[/align]
[align=left] /// <param name="key">容器标识,三段式命名,全局唯一:TTP-Resource-DataCache</param>[/align]
[align=left] /// <param name="handler">基于版本比较的数据处理器</param>[/align]
[align=left] /// <param name="model">同步模式</param>[/align]
[align=left] /// <param name="syncTimeMin">同步时机为Timing时,同步时间间隔</param>[/align]
[align=left] /// <returns></returns>[/align]
[align=left] public static IVersionCacheContainer<T> CreateEventContainer<T>(string key,CacheValidateEventHandler<T> handler, SyncModel model = SyncModel.All, int syncTimeSec = 180) where T : class[/align]
[align=left] {[/align]
[align=left] if (string.IsNullOrEmpty(key))[/align]
[align=left] {[/align]
[align=left] throw new ArgumentException("Key值不能为空!", nameof(key));[/align]
[align=left] }[/align]
[align=left] if (handler == null)[/align]
[align=left] {[/align]
[align=left] throw new ArgumentNullException(nameof(handler));[/align]
[align=left] }[/align]
[align=left] if (syncTimeSec == 0)[/align]
[align=left] syncTimeSec = 180;[/align]
[align=left] return new InMemoryEventCacheContainer<T>(key,model,handler, TimeSpan.FromSeconds(syncTimeSec));[/align]
[align=left] } [/align]
[align=left] }[/align]
同步模式和同步时机的定义如下:
/// <summary>
/// 同步模式
/// </summary>
public enum SyncModel : int
{
All, //全量同步,清楚历史缓存信息,重新插入
Increase, //增量同步,同步变化部分,不对历史缓存数据清理
Clear //仅清理历史数据
}
/// <summary>
/// 同步时机
/// </summary>
public enum SyncTime : int
{
Invoke, //调用方执行SyncData方法主动同步
Timing, //定时同步
GetCheck //Get方法是自动同步
}
以上是我们在进程内存组件的一些实践心得,更多技术细节,欢迎同学们来电沟通。微信号:vveiliang
相关文章推荐
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
- Varnish[反向代理,缓存基于内存或文件]
- 基于组件的.NET软件开发(3)
- 基于.net技术的代码高亮显示组件
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 第四节:一些指令总结 定时调度系列之Quartz.Net详解 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
- 基于.net技术的代码高亮显示组件
- 通用权限管理系统组件 (GPM - General Permissions Manager) 中灵活经典的.NET2.0数据库访问组件,附源码
- 通用内存缓存管理器的设计
- 基于STSdb和fastJson的磁盘/内存缓存
- 利用 AOP 实现 .NET 上完整的基于角色的访问控制(RBAC)模型{zhuang}
- 分布式组件--基于内存的网络锁服务器
- 基于组件的.NET软件开发(4)
- 基于RBAC模型的通用企业权限管理系统
- .NET通用数据库访问组件,日志组件,C#相关工具
- 分布式缓存技术redis学习系列(二)——详细讲解redis数据结构(内存模型)以及常用命令
- 基于RBAC模型的通用权限管理系统的设计(数据模型)的扩展
- .NET模型验证组件FluentValidation
- 内存In-memory模型 缓存Cache
- 利用 AOP 实现 .NET 上完整的基于角色的访问控制(RBAC)模型
- 通用基于TCP协议的C/S模型的代码