使用微软分布式缓存服务Velocity Part 3

概述

Velocity是微软推出的分布式缓存解决方案,为开发可扩展性,可用的,高性能的应用程提供支持,可以缓存各种类型的数据,如CLR对象、XML、二进制数据等,并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中,本文将介绍Velocity中的悲观锁定,缓存项版本、日志记录、客户端缓存以及路由表等知识。

悲观锁定

在Velocity提供了一套悲观锁定模型,即在某个缓存项数据处理过程中,数据将处于锁定状态,来自于其它客户端应用程序将无法对该缓存项进行处理。提供悲观锁定的方法主要三个,如下代码所示:

GetAndLock():获取缓存项并对数据加锁;

PutAndUnlock():更新加锁的数据并释放锁;

Unlock():释放锁定。

先来看GetAndLock()方法,在获取缓存项时并加锁,此时如果其它客户端试图获取该数据并加锁(即调用GetAndLock方法)将会失败,而不会阻塞;但客户端如果只想获取数据(即调用Get方法),则会返回相应数据,可以用图1形象的来表示:

Velocity_003

图 1

可以看到,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表示:

Velocity_004

图 2

客户端缓存

在Velocity中还支持客户端缓存,如果启用了客户端缓存后,在从缓存集群中取回数据时,将会放在客户端缓存中,这样下次取数据时将会直接从客户端缓存中取出,能够极大的提高效率,有点像是缓存的缓存。当集群中的数据发生变化时,Velocity将会使用事件通知机制通知客户端缓存刷新数据,如图3所示:

Velocity_005

图 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所示:

Velocity_007

图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所示:

Velocity_006

图 5

总结

本文介绍了Velocity中的悲观锁定,缓存项版本、日志记录、客户端缓存以及路由表等知识,希望对大家有用。至此,关于微软的分布式缓存服务Velocity就用短短的三篇文章介绍到这里,期待在.NET Framework 4.0中Velocity能够为我们带来更多的惊喜。

相关文章:

1. 使用微软分布式缓存服务Velocity Part 1

2. 使用微软分布式缓存服务Velocity Part 2

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2008-12-07 22:42 TerryLee 阅读(7170) 评论(29)  编辑 收藏 网摘 所属分类: [01]  .NET大本营

  回复  引用  查看    
#1楼2008-12-07 22:50 | Jeffrey Zhao      
和Memcached已经不可同日而语了。
对了,李兄都是哪里找来的Velocity资料的呀?

  回复  引用  查看    
#2楼[楼主]2008-12-07 22:54 | TerryLee      
@Jeffrey Zhao
呵呵,Memcached我还不怎么了解

资料比较少,主要是官方提供的文档还有在PDC上关于Velocity的两节课视频:)

  回复  引用  查看    
#3楼2008-12-07 23:10 | Astar      
学习
  回复  引用  查看    
#4楼2008-12-07 23:52 | 牛牛x      
打算试试手!
  回复  引用  查看    
#5楼2008-12-08 08:30 | xjb      
--引用--------------------------------------------------
TerryLee: @Jeffrey Zhao
呵呵,Memcached我还不怎么了解

资料比较少,主要是官方提供的文档还有在PDC上关于Velocity的两节课视频:)
--------------------------------------------------------
高手呀,资料少还讲这么详细

  回复  引用  查看    
#6楼2008-12-08 09:19 | Artech      
@TerryLee
通过老李的介绍,对Velocity加深了了解。等正式发布后,我打算把它引入到我们自己的框架中:)

  回复  引用  查看    
#7楼2008-12-08 09:46 | 朝晖的.net      

关注,不错的东西啊。

支持楼主。

  回复  引用  查看    
#8楼2008-12-08 10:12 | Jeffrey Zhao      
--引用--------------------------------------------------
Artech: @TerryLee
通过老李的介绍,对Velocity加深了了解。等正式发布后,我打算把它引入到我们自己的框架中:)
--------------------------------------------------------
这是啥框架?

  回复  引用  查看    
#9楼[楼主]2008-12-08 10:22 | TerryLee      
@Astar
:)

  回复  引用  查看    
#10楼[楼主]2008-12-08 10:23 | TerryLee      
@牛牛x
不过现在Velocity在配置上还有一些问题,估计到.NET Framework 4.0中就比较稳定了:)

  回复  引用  查看    
#11楼[楼主]2008-12-08 10:23 | TerryLee      
@xjb
呵呵,谢谢:)

  回复  引用  查看    
#12楼[楼主]2008-12-08 10:23 | TerryLee      
--引用--------------------------------------------------
Artech: @TerryLee
通过老李的介绍,对Velocity加深了了解。等正式发布后,我打算把它引入到我们自己的框架中:)
--------------------------------------------------------
嗯,正式发布估计到.NET Framework 4.0中了:)

  回复  引用  查看    
#13楼[楼主]2008-12-08 10:24 | TerryLee      
@朝晖的.net
的确是个好东西,值的关注,谢谢支持:)

  回复  引用  查看    
#14楼[楼主]2008-12-08 10:24 | TerryLee      
--引用--------------------------------------------------
Jeffrey Zhao: --引用--------------------------------------------------
Artech: @TerryLee
通过老李的介绍,对Velocity加深了了解。等正式发布后,我打算把它引入到我们自己的框架中:)
--------------------------------------------------------
这是啥框架?
--------------------------------------------------------
估计是Artech公司内部自己开发的框架吧:)

  回复  引用  查看    
#15楼2008-12-08 10:41 | Artech      
--引用--------------------------------------------------
TerryLee: --引用--------------------------------------------------
Jeffrey Zhao: --引用--------------------------------------------------
Artech: @TerryLee
通过老李的介绍,对Velocity加深了了解。等正式发布后,我打算把它引入到我们自己的框架中:)
--------------------------------------------------------
这是啥框架?
--------------------------------------------------------
估计是Artech公司内部自己开发的框架吧:)
--------------------------------------------------------
是的!

  回复  引用  查看    
#16楼2008-12-08 11:44 | 代震军      
现在有没有什么大型布署的示例呀:)
  回复  引用  查看    
#17楼2008-12-09 01:07 | 蛙蛙池塘      
不是一个PHP的模板吗?
  回复  引用  查看    
#18楼[楼主]2008-12-15 10:09 | TerryLee      
@代震军
现在还在CTP 2,在配置上还有很多的问题,所以……

  回复  引用  查看    
#19楼[楼主]2008-12-15 10:09 | TerryLee      
@蛙蛙池塘
PHP的模板?啥意思?

  回复  引用  查看    
#20楼2008-12-15 10:12 | 蛙蛙池塘      
  回复  引用    
#21楼2008-12-17 11:26 | leijuan903[未注册用户]
@Jeffrey Zhao

学习了

  回复  引用  查看    
#22楼[楼主]2008-12-17 11:31 | TerryLee      
@蛙蛙池塘
错了,名字相同,但不是同一个东西:)

  回复  引用    
#23楼2008-12-18 17:54 | 过过客[未注册用户]
--引用--------------------------------------------------
Jeffrey Zhao: 和Memcached已经不可同日而语了。
对了,李兄都是哪里找来的Velocity资料的呀?
--------------------------------------------------------


现在用memcached的人很多,还希望谁来写写这两者的一个PK :)

  回复  引用  查看    
#24楼[楼主]2008-12-19 01:30 | TerryLee      
@过过客
我大概看了一下,觉的最终版Velocity肯定比memcached要强大:)

  回复  引用  查看    
#25楼2009-03-14 18:41 | www.guyazi.com      
不错,三篇文章都看完了。功能真的很强大。
本来我近期打算自己写一个基于WCF的简单分布式缓存程序,看了这个文章后我就不打算写了,还是可以使用现成的,网上应该已经存在很多分布式缓存的开源项目了。估计我不会等到微软推出VS2010时候才使用分布式缓存的。微软其实早该做了。

  回复  引用  查看    
#26楼2009-03-27 12:32 | 宏宇      
我现在就遇到了这个问题,试试这个解决方案
  回复  引用  查看    
#27楼2009-04-01 03:36 | EricWen      
学习,就要用了。逼得
  回复  引用  查看    
#28楼2009-05-10 20:16 | 李永京      
分布式架构其中一个好东西,现在才发现~~不过老李太强了,写了这么多了~值得学习
  回复  引用  查看    
#29楼[楼主]2009-05-15 09:37 | TerryLee      
@李永京
谢谢小李同学支持 :)

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1349769




相关文章:

相关链接: