接上一篇 学习中,顺便翻译,有不正确的地方欢迎指正,转载请注明出处http://cnblogs.com/xuf22
二、缓存概念
2. 缓存客户端与本地缓存
使用Velocity缓存,应用程序中需要用到DataCache对象存储缓存对象。这个对象就是缓存客户端,它为应用程序提供了一个缓存群集服务的name cache的引用。该对象由DataCacheFacory对象的GetCache方法创建。
出于性能考虑,建议在应用程序中尽量少创建DataCacheFactory对象,在应用程序中创建一个全局变量,以便缓存客户端可以在任何地方都给使用--用单件模式吧
缓存客户端分为两种:路由客户端和普通客户端。两种缓存客户端都可以将缓存存储在本地,这种被存储在本地的缓存称为:本地缓存。缓存客户端的存储选项可以通过应用程序配置文件指定。
2.1 安全考虑
缓存客户端应该用在运行数据中心的服务器上的应用程序中,在企业防火墙内。缓存服务和缓存主机之前的通信是不加密的,很容易受到“嗅探”和“Replay”攻击。
强烈建议使用加密的XML配置文件来指定缓存客户端。
2.2 客户端类型
下图中有两个使用了缓存的应用程序:路由(routing)和普通的(simple)
路由客户端(Routing Client)
Routing Client的性能要高于Simple Client,因为它在缓存的引导主机(Lead hots)上保存了一张路由表。该路由表用记录缓存群集中的所有缓存主机上的对象的地址并做唯一标示。Routing Client使用路由表可以直接找到对象的物理地址。
普通客户端(Simple Client)
只要有可能,尽量使用Routing Client,但在情况下,如网络拓扑中,可能有些客户端只能访问缓存服务群集的中的部分主机,这时就要用到Simple Cleint来做为分布式缓存的数据源。
为了在有限的网络通信情况下工作,Simple Client被设计为只访问缓存群集中的一台主机。它没有路由选择功能,不能跟踪对象的地,要获取缓存中的一个对象通常需要遍历所有主机。
本地缓存Local Cache
缓存主机存储的是序列化后的对象,客户端要使用该对象,必需先反序列化,为了提高取出对象的效率,可以启用本地缓存。路由客户端和普通客户端都可以使用本地缓存。
当启用本地缓存后,对象将以复本的文本保本地计算机的内在中,客户端应用程序在从缓存主机取出对象时,先检查本地缓存是否已存在该对象。如果本地缓存已存在该对象,将直接从本地取出。
本地缓存有两种过期策略:超时过期和通知过期。
线程并发(Object Consistency)
本地缓存对象和缓存客户端对象在同一个进程空间中,只为DataCache是引用方式获取这些对象,在多线程应用程序中可能会存在线程同步问题。
为了避免潜在的多线程中的问题,多线程应用程序在使用缓存对象时应先生成一个对象的复本,或对取其它方式来避免线程并发问题。另一种方法是为每一个线程创建一个DataCache对象。
3 并发概念
Velocity允许任何有网络权限和相关配置的缓存客户端公开的访问缓存数据,这样就面临着安全和并发的挑战。
为了减少安全问题,所有的缓存客户端、缓存服务和主数据源服务器都应该在同一个域下,并在防火墙内,这是极度推荐的方法。
为了解决并发问题,Velocity提供了开放式并发和保守式并发。
3.1 开放式并发模式(Optimistic Concurrency Model)
在开放式并发下,对象不会在更新时被锁定,访问缓存时先读取缓存对象,更新时再对缓存版本进行检查,如果本地缓存对象已过期,则缓存更新失败。
例如:两个缓存客户端(cacheClientA and cacheClientB)在两个独立的应用程序中都要更新同一个名为RadioInventory的缓存。
Time Zero(T0):两个对象同时取出同一个对象
两个缓存客户端实各例化一个DataCacheItem类,并取出缓存同一个对象,两个DataCacheItem实例要准备要更新对象。
T0:取出对象
Time One(T1): cacheClientA
更新对象成功
cacheClientA将对象
RadioInventory更新,
RadioInventory的版本号添加,这时
cacheClientB中的
RadioInventory对象已过期。
//at time T1, cacheClientA updates the FM radio inventory int newRadioInventoryA = 155; cacheClientA.Put("RadioInventory", newRadioInventoryA, radioInventoryA.Version,"electronics");
Time Two: The Second Update Fails
cacheClientB尝试修改
RadioInventory为一个新值,为了阻止将
cacheClientA的更新覆盖,
cacheClientB的更新将会失败。
//later, at time T2, cacheClientB tries to //update the FM radio inventory, triggers exception ERRCA001 int newRadioInventoryB = 130; cacheClientB.Put("RadioInventory", newRadioInventoryB, radioInventoryB.Version,"electronics");
保守式并发
当客户端取出对象时明确指出该对象已被取出,正在更新,所有对缓存对象的请求都被驳回,直到销被释放。当缓存对象被锁定时,读取操作会返回一个句柄。