概述 缓存
Velocity是微软推出的分布式缓存解决方案,为开发可扩展性,可用的,高性能的应用程提供支持,能够缓存各类类型的数据,如CLR对象、XML、二进制数据等,而且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中,本文将介绍Velocity中的悲观锁定,缓存项版本、日志记录、客户端缓存以及路由表等知识。 服务器
悲观锁定 分布式
在Velocity提供了一套悲观锁定模型,即在某个缓存项数据处理过程当中,数据将处于锁定状态,来自于其它客户端应用程序将没法对该缓存项进行处理。提供悲观锁定的方法主要三个,以下代码所示: 函数
GetAndLock():获取缓存项并对数据加锁; 工具
PutAndUnlock():更新加锁的数据并释放锁; 性能
Unlock():释放锁定。 优化
先来看GetAndLock()方法,在获取缓存项时并加锁,此时若是其它客户端试图获取该数据并加锁(即调用GetAndLock方法)将会失败,而不会阻塞;但客户端若是只想获取数据(即调用Get方法),则会返回相应数据,能够用图1形象的来表示: ui
图 1 spa
能够看到,ClientA获取数据成功并加锁;ClientB再次想获取数据并加锁时,将会失败;ClientC可以获取数据。 日志
使用GetAndLock()方式能够指定锁过时时间,而且会有输出参数LockHandle,该参数将会在PutAndUnlock()方法或Unlock()中来释放锁,以下代码所示:
Cache cache = GetCurrentCache();
LockHandle handle = new LockHandle();
Customer item = (Customer)cache.GetAndLock("C20081117005",
new TimeSpan(0, 30, 0), out handle);
Customer customer = new Customer()
{
ID = "C20081117005",
FirstName = "Terry",
LastName = "Lee",
Age = 25,
Email = "lhj_cauc[#AT#]163.com"
};
cache.PutAndUnlock(customer.ID, customer, handle, null);
日志记录
Velocity中一样提供了日志记录的功能,咱们能够在应用程序配置文件中进行设置,它支持基于控制台、基于文件以及Windows事件跟踪三种方式的记录,在配置文件中首先添加配置区:
<section name="fabric" type="System.Data.Fabric.Common.ConfigFile, FabricCommon"
allowLocation="true" allowDefinition="Everywhere"/>
而后能够进行配置,如设置日志记录级别等:
<fabric>
<section name="logging" path="">
<collection name="sinks" collectionType="list">
<customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Data.Fabric.Common.ConsoleSink,FabricCommon"
sinkParam="" defaultLevel="-1"/>
<customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Data.Fabric.Common.FileEventSink,FabricCommon"
sinkParam="CacheClientLog" defaultLevel="1"/>
<customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Data.Caching.ETWSink, CacheBaseLibrary"
sinkParam="" defaultLevel="-1" />
</collection>
</section>
</fabric>
一样也能够在代码中设置,调用CacheFactory的两个静态方法CreateLogSinks和DisableLogSinks,以下代码所示:
private Cache GetCurrentCache()
{
List<LogSink> sinklist = new List<LogSink>(2);
LogSink fileBasedSink = new LogSink(SinkType.FILE,
TraceLevel.Warning, "DCache/dd-hh-mm");
LogSink consoleBasedSink = new LogSink(SinkType.CONSOLE,
TraceLevel.Warning);
sinklist.Add(fileBasedSink);
sinklist.Add(consoleBasedSink);
// 启用
CacheFactory.CreateLogSinks(sinklist);
// 禁用
CacheFactory.DisableLogSinks();
Cache dCache;
ServerEndPoint[] servers = new ServerEndPoint[1];
servers[0] = new ServerEndPoint("localhost", 22233, "DistributedCacheService");
bool routingClient = true;
bool localCache = false;
var factory = new CacheFactory(servers, routingClient, localCache);
dCache = factory.GetCache("default");
return dCache;
}
缓存项版本
在Velocity中提供了一种基于版本的更新功能,当使用GetCacheItem()方法时将返回一个缓存项,并携带有版本信息,当每次对缓存项作更新时,在内部都会对它的版本增长。以下面的示例,有两个客户应用程序,它们同时获取了同一个缓存项:
ClientA
CacheItem item = cache.GetCacheItem("Customers", "C2008");
ClientB
CacheItem item = cache.GetCacheItem("Customers", "C2008");
而且同时对缓存项作修改:
ClientA
((Customer)item.CacheObject).FirstName = "Huijun";
ClientB
((Customer)item.CacheObject).FirstName = "Terry";
若是ClientA首先提交更改,在提交更改时携带版本信息,因为版本信息与内部的版本一致,因此提交成功:
ClientA
cache.Put("Customers", "C2008", item.CacheObject, item.Version);
此时内部版本将会增长,如今ClientB若是再提交更改,将会失败,由于版本没法匹配,如图2表示:
图 2
客户端缓存
在Velocity中还支持客户端缓存,若是启用了客户端缓存后,在从缓存集群中取回数据时,将会放在客户端缓存中,这样下次取数据时将会直接从客户端缓存中取出,可以极大的提升效率,有点像是缓存的缓存。当集群中的数据发生变化时,Velocity将会使用事件通知机制通知客户端缓存刷新数据,如图3所示:
图 3
要启用客户端缓存,一是使用配置文件,设置IsEnabled属性为True,以下代码所示:
<dcacheClient deployment="routing">
<localCache isEnabled="true" sync="TTLBased" ttlValue="300" />
<hosts>
<host name="localhost" cachePort="22233"
cacheHostName="DistributedCacheService"/>
</hosts>
</dcacheClient>
直接指定启用客户端缓存便可,另外也能够在建立CacheFactory时指定,以下代码所示:
Cache dCache;
ServerEndPoint[] servers = new ServerEndPoint[1];
servers[0] = new ServerEndPoint("localhost", 22233, "DistributedCacheService");
bool routingClient = true;
bool localCache = false;
var factory = new CacheFactory(servers, routingClient, localCache);
dCache = factory.GetCache("default");
return dCache;
路由客户端
Velocity中在缓存客户端,提供了一种路由客户端Routing Client,它可以提供比简单客户端Simple Client更好的性能,在Routing Client中会有一个路由表Routing Table,它用来跟踪缓存对象,它是全局缓存中的分区映射的一个子集,同时分发缓存操做(Put、Get等)到肯定的缓存宿主。路由客户端使用此路由表来优化性能,由于该表能够跟踪缓存对象,因此当有请求到缓存宿主时,能够进行物理上的定位。如图4所示:
图4
是否在应用程序中启用路由客户端,能够由开发者来肯定,如在配置中启用路由客户端,这里能够经过指示deployment来设定是路由客户端(routing)仍是简单客户端(simple):
<dcacheClient deployment="routing">
<localCache isEnabled="true" sync="TTLBased" ttlValue="300" />
<hosts>
<host name="localhost" cachePort="22233"
cacheHostName="DistributedCacheService"/>
</hosts>
</dcacheClient>
另外还能够经过代码来设置,以下面的代码,在建立CacheFactory时指定构造函数参数:
Cache dCache;
ServerEndPoint[] servers = new ServerEndPoint[1];
servers[0] = new ServerEndPoint("localhost", 22233, "DistributedCacheService");
bool routingClient = true;
bool localCache = false;
var factory = new CacheFactory(servers, routingClient, localCache);
dCache = factory.GetCache("default");
return dCache;
Velocity组成
最后咱们再看一幅图,来了解一下Velocity的组成部分,能够看到它能够分为客户端缓存、服务端缓存以及管理工具三部分,如图5所示:
图 5
总结
本文介绍了Velocity中的悲观锁定,缓存项版本、日志记录、客户端缓存以及路由表等知识,但愿对你们有用。至此,关于微软的分布式缓存服务Velocity就用短短的三篇文章介绍到这里,期待在.NET Framework 4.0中Velocity可以为咱们带来更多的惊喜。