没有合适的资源?快使用搜索试试~ 我知道了~
透明客户端缓存的设计与实现
34网址:http://www.elsevier.nl/locate/entcs/volume65.html11页支持透明客户端缓存Christoph Pohl,Alexander Schill德累斯顿工业系统架构研究所,计算机网络摘要本文回顾了现有的缓存概念在代理和存根的组件技术,并列出了他们的优点和缺点。引入了一个新的概念,避免了客户端组件存根的扩散,同时提供了高效的属性缓存,根本不需要对现有代码进行任何更改。通用的面向对象设计工具和代码生成工具被用来支持将这些缓存概念无缝集成到开发周期中。1引言像远程过程调用这样的技术曾经被引入来提供对远程接口的透明编程访问,就像对它们的本地等价物一样。但现实证明,透明分配是一个神话。对于构建可伸缩的应用程序,重要的是要记住远程调用要昂贵得多。这对于今天的通信密集型组件模型(如Enterprise JavaBean)来说更加重要。有不同的策略来解决这个问题的网络流量-c减少。在组件技术的上下文中,很大一部分远程调用用于状态转移,其中组件属性被单独查询接口的重新设计可以帮助减少这些状态传输的粒度这消除了以数据编组为代价的多次往返但是,由于大多数数据的读取频率高于写入频率,因此复制是保持可扩展性的另一种选择缓存是部分复制的一种特殊形式,通常选择它来缩小信息源和接收器之间的差距。它建立在这样的假设之上,即一旦访问数据,在不久的将来将再次查询1 eMail:fpohl,schill g @ rn. 在法国,tu-dr esd en. de2002年由ElsevierScienceB出版。 诉操作访问根据C CB Y-NC-N D许可证进行。35这将缓存与预取(另一种部分复制)区分开来,预取尝试提前加载接下来可能被查询的数据。复制的效率主要取决于读写操作的比例,因为写操作会在同一对象的副本之间引入不一致性进一步的影响因素包括网络延迟、每次写入操作的改变的数据量、用于复制的可用存储器、应用对微小不一致的容忍度等。缓存技术至少可以通过两种不同的方式集成到基于构件的软件中:(1)使用特殊的设计模式,可以通过必要的方法来扩充构件接口。这通常意味着对现有的应用程序进行重大的重新设计,尽管它可能是新兴程序的可行选择。(2)正交设施可以实现的组件的中间件本身。现有的组件大多未受影响。缓存需求是以描述性的方式指定的,可以由中间件评估。无论在特定环境中采取什么方法,对于基于组件的软件,至少存在三个必须由高速缓存子系统处理的问题:(1)组件状态高速缓存包括用于本地高速缓存所查询的组件属性的供应。(2)组件标识对于确定某些查询是否引用相同的共享对象或组件非常重要。(3)多重引用处理避免了相同组件实例的重复缓存条目。组件通常相互关联。这些关系的公开方式通常与其接口上的属性非常相似。这意味着通常有多种方法可以获取对组件实例的引用。但是所有的引用都必须重定向到客户端进程中的同一个缓存副本第3节介绍了解决这些问题的一种可能方法。特别是最后一点往往被简单的分布式缓存解决方案所忽略。只有少数作者意识到这个问题的重要性。2相关工作缓存不是面向对象系统中的新特性。现有的解决方案可以追溯到Orca[1]和Shadows[5],其中包括Arjuna。本文集中讨论在EnterpriseJavaBeans环境中组件接口和代理对象的特殊问题,在这种环境中,用于缓存的端口可从现有容器获得。许多解决方案提供者依赖于特殊的客户端代理对象来进行优化的bean访问。重要的是要记住,“客户端”仅指接口的用户。 在EJB的上下文中,这也可能是一个Web 服务器,通过查询EJB 容器来处理JSP 和Servlet。这两个进程不一定在同一个网络节点上运行。在ASP的局域网中分布它们是相当常见的。考虑36因此,缓存代理的范围比简单的Java小程序和应用程序客户端要广得多。代理是面向对象软件设计中的一种常见模式[16,8,4]。它指的是作为某些(远程)委托的代表安装的对象,这些对象控制这些委托并遵循这些委托的接口。这种方法通常由RPC风格的中间件(如RMI和IIOP)采用,其中代理(也称为远程存根透明地处理参数和返回值的编组以及其他任务。分布式应用程序基于此抽象层来实现其特定功能。正如在第1节中所预期的那样,这给我们留下了两个缓存实现的位置:要么在这个抽象之上作为应用程序接口的扩展,要么在下面作为附加的中间件服务。2.1应用级解决方案基于组件接口抽象层的缓存实现必须引入一个代理层来封装其他客户端应用程序模块的缓存逻辑。这个代理层越接近原始组件的接口,对现有客户端模块的修改就越少。这种方法已经被OORPC[20]和MinORB[12]等所遵循。但是由于需要显式调用或创建代理对象,完全透明是无法实现的(客户端程序员必须知道这些更改)。所描述的缓存层可以简单地尝试保持查询结果的副本,但是通常几个查询被依次触发,例如,因为客户端应用程序需要组件的多于一个属性来完成它们的工作。缓存层可以使用状态对象或相关的设计模式,组件的状态以粗粒度的方式被传送到操纵(客户机)进程,这减少了网络往返的总次数。这种批量状态传输可以在一些修改之后由客户端应用程序触发,或者甚至可以由缓存层本身透明地触发,这将添加简单的预取功能。2.1.1状态对象模式状态对象模式不要与[8]中介绍的行为状态模式混淆。它是代理模式的结构扩展,代理模式的主要部分由一个简单的holder对象组成,用于在抽象客户机/服务器对之间进行捆绑状态传输。这种策略通常节省了大量的网络往返,因为多个属性是一起查询的,而不是单独获取的。同一概念的其他名称是值对象[14]和数据数组。此模式使用固定数据结构以其原始形式进行状态传输,但扩展后,更灵活的版本(如Dynamic Property)使客户端能够查询业务对象属性的可变集,而不是大量的37美德.先知-愿不同的用例在运行时成为可能,而无需更改组件的代码。IBM的Enterprise JavaBeans产品线中集成了一个名为Access Bean的类似解决方案[17]。Access Bean是客户端访问EJB时必须使用的JavaBean风格代理的名称。复制帮助器和行集为一个Access Bean中的单个和多个EJB实例添加了缓存功能。Astral Clones[15]使用不同的方法:Bean类可在容器外部使用。包含组件状态的序列化副本可以通过其他方法传输到客户端。由于这些类已经包含了所有必要的数据操作逻辑,因此客户端可以像使用远程类一样使用它们。不幸的是,所需的预防措施似乎引入了比它们解决的更多的问题,而且,由于改变了持久状态管理,这个概念将不适用于EJB 2.0实体[7]。2.1.2会话Bean包装器会话外观[14]或会话Bean包装实体Bean(如[3]中)是另一种模式,当不可能或不希望(例如出于兼容性原因)直接修改现有组件以支持上述值对象查询的方法时,也可以使用该模式。然后,会话虚包可以为新客户端添加对现有组件的访问,并为这些绑定的对象状态查询添加支持。然后,各个组件属性查询将在运行实体和会话虚包组件的容器的服务器上本地发生。如上所述,客户端代理可以从这个增加的功能中受益,使它们的缓存更加有效2.2基于中间件的概念如前所述,所有上述概念都需要在客户端和服务器端进行大量的重新编码,这违反了透明度,这在当今的许多业务场景中可能是不可行的。本节介绍实现透明缓存的替代方法。2.2.1分布式共享对象在过去的十年中,相当多的科学出版物对分配共享对象进行了详细的阐述,例如,Javanaise[9].由于不受特定中间件或组件平台的约束,这些建议中的大多数都设法为分布式应用程序构建了高效的解决方案。不幸的是,几乎没有任何一个成功地流行或获得更广泛的接受基础,这使得应用程序开发人员避免在这些技术上投入时间和金钱。382.2.2智能代理在Corba世界中,为更高级别的透明性所做的努力已经导致了所谓的智能代理2(Smart Proxies2)的概念,用户定义的远程存根可以用来代替ORB的默认实现。这些智能代理可以包含缓存功能等。然而,这个概念仍然只是作为提供程序专用的c3,不可互操作的扩展而存在。2.2.3存根注释Java的RMI和Java-IDL没有任何关于这个概念的规定。然而,已经提出了如何填补这一空白的建议:智能存根[11]是一个简单的概念验证,其基本思想依赖于重命名系统的默认远程存根,并将其替换为派生的,增强的类,这些类包装了缓存和性能监控的功能。2.2.4Caching Services缓存是一个技术驱动的方面,从来没有直接关系到应用程序的要求。它更像是在应用程序运行时考虑性能问题时出现的。因此,让应用程序员摆脱这种挑战,并提供可以在部署期间配置而无需重新编码的缓存支持,才是公平的。其他作者也有同样的感觉,这导致了像Flex[10]这样的项目,一个基于CORBA的客户端缓存框架,以及Cascade[6],一个用于WAN中对象缓存的CORBA服务。2.3结论现有的解决方案似乎有许多缺点:它们要么迫使程序员适应新的编程模型,要么为客户端和服务器程序提供有些几乎不考虑服务器对象的全局标识,即对同一客户端的单个服务器对象的多个3支持透明客户端缓存的中间件在本节中,我们将概述我们目前在EnterpriseJavaBean上下文中关于透明客户端缓存解决方案的工作3.1对同一远程对象的代理的爆炸性增长是一个经常被忽视的问题:无论(远程)操作将代理作为远程引用返回到何处,2 更详细地解释,例如[18]3 例如Borland/ Inprise/ Visigenic的VisiBroker和Iona的Orbix提供智能代理39图1. 客户端容器在每次调用时在客户端进程中创建。内存消耗随对象引用的数量线性增加。每个客户端都必须检查其接收到的代理是否相等,如果它们引用相同的服务器对象,则丢弃相同的副本。这获得了更重要的修改代理也可能包含缓存的数据。如果不采取预防措施,客户端肯定会淹没在缓存的属性中。这个问题以前已经被其他人意识到,例如[19],但由于缺乏透明度,所提出的解决方案并不令人满意。3.2这个想法我们建议使用“客户端容器”,即每个客户端进程中的静态查找表,每次必须传输新代理时都会查询该表,尽管更精细的缓存服务(如[2])也可以 用 于 后 续 版 本 中 的 实 现 。 该 概 念 基 于 第 2.2.3 节 中 描 述 的 StubAnnotation,因为它比全面代理生成解决方案更容易实现短期换句话说,生成的默认代理由自定义子类扩展,而不是修改业务接口和组件实现。这些经过修改的工具生成的代理为组件的属性提供了适应性的缓存功能,并根据客户端容器检查远程引用返回值(见图1)。如果一个远程引用被证明等于已经存储在客户端容器的存储库中的同一组件的另一个代理,则它将被丢弃,并将返回来自存储库的等效另一方面,如果找不到对等的代理,客户端容器将透明地存储新的远程引用。3.3基于中间件平台的对象平等性如引言所述,必须特别注意对象识别。人们可能会认为存根可以简单地在Hashtable中维护,但是像EJB这样的组件模型额外引入了某些障碍,因为规范[13,7]暗示hashCode()和equals()的结果是未知的。不幸的是,这些方法对于标准Java哈希表中的正确存储至关重要。EJB对象派生自java.rmi.Remote,这使得它们可以跨网络边界访问,但是EJB的概念依赖于对特定业务的后续远程调用的动态重新分配40反对不同的仆人为汇集的目的。因此,hashCode()和equals()的行为与对同一个javax.ejb.EJBObject服务器的预期相同,但这可能被容器的池算法用于不同的实体标识。对于实例标识来说,EntityBean的主键是不实用的,因为它们只在单个部署的上下文中对于某个bean类型是唯一的。解决方法是将代理的hashCode()和equals()实现委托给javax.ejb.Handle,这是一个长期存在的身份对象,可以从每个javax.ejb.EJBObject作为唯一引用获得 句柄也以延迟评估的方式缓存,以避免每次测试相等性时进行额外的远程调用。利用这些先决条件,实现了基于单个静态哈希表的第一个简单的客户端容器原型,但更复杂版本的可能性几乎是无限的。3.4使用要 可 视 化 客 户 端 容 器 的 使 用 , 请 想 象 以 下 示 例 : OrderBean 引 用CustomerBean。 将实现getCustomer()方法,以支持以面向对象的方式进行导航访问,返回对CustomerBean的远程引用。生成器工具将实现这种依赖性,从而将代码插入到生成的代理中,以按照以下方式执行上述查找公共clas s订单存根extendsOrder Stubf pri合物stati ctran si entCSContainercs conta i ner = CSContainer。 g e t C S C o n t a i n e r();privateCustomer customerCache =nul;//(. .. )的方式公共客户getCustomer()抛出j a va . RMI . RemoteExceptionfI f(customerCach e==nu ll)f客户c =超级。 getCustomer(); customerCache = cc c o n t a n e r . getString(c);G返回客户缓存;GGrmic生成的默认存根被重命名为__Order_Stub,替代它的增强实现是从该类派生的。Java中的存根实例化基于命名约定,这使得重命名成为必要。另一方面,除了简单的重命名之外,默认存根不应该被改变,因为它们的结构可能会由于Sun的内部修改而在没有通知的情况下发生变化。此示例还演示了缓存功能的集成。订单的Customer通常在创建时确定,这使得该属性成为一个完美的缓存候选者。如果实体之间存在多值关系,事情就会变得更加复杂。由于动态类加载,代理类可以正确传输,41还 必 须 检 查 实 例 是 否 与 本 地 客 户 端 容 器 重 复 我 们 通 过 为java.util.Collection和java.util.Iterator实现通用包装器来确保这种行为。只要给定部署的所有代理都由生成器工具修改,这个概念就可以很好地工作。如果标准的存根实现混合在一起,它们将污染积极的影响,并重新激活代理的扩散请注意,不需要对现有的客户端或服务器代码进行修改,因为所有更改对组件本身都是完全透明的。缓存的补充集成甚至不需要源。存根可以由rmic或容器的相应工具基于现有的类les重新生成。这些又被存根生成器工具改变。在以后的版本中,这两个步骤将被单个存根生成器工具所取代。3.5部署在EJB部署过程中,容器的部署工具会打包两个存档文件,即所谓的“文件包”(archive),一个用于包含远程存根和接口的Bean客户端,另一个用于服务器,服务器还包含Bean实现本身和所有必要的骨架或绑定类。问题是如何将修改后的代理放入EJB档案中。不幸的是,大多数EJB服务器在Bean部署期间甚至不公开生成的服务器JAR。只要没有容器支持的访问可能性,客户端和服务器JAR就必须被解包、修改和复制回它们特定于容器的位置。一些容器,如JBoss4,利用特殊优化的、不兼容RMI的协议,甚至没有物理代理类。它们是使用Recection-API的调用处理程序动态生成的,而Recection-API又为集成提供了新的访问点。因此,目前,部署过程必须适应各个容器的实现。我们正在尝试更紧密地集成到JBoss等开源容器的部署过程中的可能性。此外,我们希望容器提供商能够意识到透明缓存存根的好处,并开始实现类似于Smart-Proxy的接口或集成类似的缓存解决方案。3.6一致性问题已经概述了对复制的分布式对象所做的更改总是会导致不一致。幸运的是,大多数应用程序可以在短时间内处理这些不一致性。许多出版物[1,10,6]阐述了不同的一致性水平和协议。我们目前只支持脏读,即在不获取服务器锁的情况下进行读访问。正在开发一种使用时间戳的乐观锁定策略。我们的原型通过定期清除缓存来实现可选的缓存失效,但我们正在4 http://www.jboss.org/42图2. UML构造型关于在写访问时异步通知实体的分布式高速缓存的更新传播解决方案。未来的版本将允许对交易需求进行描述性规范。4 UML支持前面已经提到,大多数缓存概念缺乏与可视化设计和构建器工具的集成 。 缓 存 属 性 必 须 以 专 有 格 式 存 储 在 外部 。 然 而 , 统 一 建 模 语 言(UML)提供了为不同的缓存策略标记组件属性的方法。所谓的刻板印象(见图2)是放在设计师的处置。它们隐含着某些特征和角色,可以由代码生成器和其他工具评估,以推断出适用的算法和代码段。组件属性之间的以下区别涵盖了缓存方面的大多数用例:可预取这些属性是接口的客户端最经常需要的,所以它们应该在存根/代理初始化时就已经被传输了group-prefetchable表示一组属性,只要查询其中一个属性,就将全部一起传输;在RST访问时单独缓存的可缓存附加属性;易失性的不可缓存属性,其经常改变或者只能在事务上下文中访问。构造型在UML模型中的存储方式完全取决于设计工具的实现。设计工具可以根据它们的模型存储分为两类:(1)特殊的存储库格式可以用来以一种高效的方式存储UML模型,例如Rational Rose。(2)源代码存储库依赖于将所有模型元素存储在相应的源代码段中,例如,一起后一种方法对于大型项目通常缺乏效率另一种工具通常提供导出器插件,用于从其内部模型存储库生成可编辑的源代码。如果这些导出器被修改为将构造型转换为相同的代码,43这两类工具可以互换使用。5未来前景第一个概念验证测试显示了缓存实体属性访问的巨大潜力:对本地缓存副本的查询只需要几秒钟,而等效的远程调用往返时间要高出一个数量级,需要几毫秒。 特别是通信密集型JSP/Servlet引擎以及GUI前端都从这些性能提升中受益。我们目前的努力集中在更不同的一致性水平和更精细的高速缓存内存管理。新兴的规范建议,如[2] 在此背景下进行评估。我们工作的主要目标是开发一个框架,该框架涵盖了组件的整个生命周期{从设计到运行时}的缓存问题。引用[1] 亨利·E Bal,M.放大图片作者:Andrew S.塔南鲍姆和杰克·詹森加速分布式系统上并行应用程序的复制技术。 Concurrency:Practice and Experience,4(5):337{355,August 1992.[2] 杰瑞·波特维特Java临时缓存API。 甲骨文公司,2001年3月19日。107.第107章一夜情[3] 凯尔·布朗。会话bean包装实体bean。在波特兰模式仓库。2001年2月。[4] Frank Buschmann,Regine Meunier,Hans Rohnert,Peter Sommerlad,and Michael Stal. 面向模式的软件架构:模式系统。Wiley,1996年。[5] Steve J. Caughey , Graham D. Parrington 和 Santosh K. 什 里 瓦 斯 塔 瓦SHADOWS -分布式系统中对象的灵活支持系统。 在第三届面向对象和操作系统国际研讨会(IWOODS'93),第73页,第82页,北卡罗来纳州阿什维尔(美国),1993年。[6] Gregory Chockler,Danny Dolev,Roy Friedman,and Roman Vitenberg.实现分布式CORBA对象的缓存服务。在Middleware'00,第1页{23,2000.[7] 琳达·G 德塞尔湖UmitYa l~cinalp和SanjeevKrishnan。企业JavaBeans规范2.0版。Sun Microsystems,2001年8月14日。最终释放。[8] E.伽马河赫尔姆河Johnson,and J. Vlissides. 设计模式-可重用面向对象软件的元素。艾迪森·韦斯利1995年44[9] Daniel Hagimont和D. Louvegnies。Javanaise:Internet协作应用程序的分布式共享对象。InMiddleware'98,The Lake District,England,1998.[10] Rammohan Kordale , Mustaque Ahamad , and Murthy V. Devarakonda.CORBA兼容系统中的对象缓存。Computing Systems,9(4):377{404,1996.[11] 托尼·洛顿。使用Java进行分布式性能监控的智能方法。JavaWorld,2000.[12] 保罗·马丁,维克多·卡拉汉,艾德里安·克拉克.使用缓存代理的高性能分布式对象用于大规模应用。在分布式对象和应用的国际研讨会上,第110{ 119}页,1999年。[13] 维拉达·马特纳和马克·哈普纳 企业JavaBean规范版本1.1. Sun Microsystems,1999年11月24日。 最终释放。[14] 太阳微系统公司 设计模式目录。 J2EE设计模式 2001.[15] Martijn Res.使用星形克隆减少EJB网络流量。JavaWorld,2001年1月。[16] 马克·夏皮罗。分布式系统中的结构和封装:代理原则。第六届分布式计算机系统国际会议,1986年5月。[17] Rob Stevenson和Leanoard Theivendra。在VisualAge for Java中开发EJB访问Bean。 IBM多伦多实验室,2000年10月[18] Nanbor Wang , Kirthika Parameswaran , Douglas Schmidt , and OssamaOthman.对象请求代理中间件元编程机制的设计与性能。第六届面向对象技术与系统会议(COOTS'01),2001年1月[19] M.杰·威尔逊 使用代理和RMI变得更聪明。JavaWorld,2000年11月[20] Matthew J. Zelesko和David R.切里顿专门针对面向对象的RPC的功能和性能。 第16届IEEE分布式计算系统国际会议。斯坦福大学计算机科学系,IEEE计算机协会出版社,1996年5月
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 5
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 黑板风格计算机毕业答辩PPT模板下载
- CodeSandbox实现ListView快速创建指南
- Node.js脚本实现WXR文件到Postgres数据库帖子导入
- 清新简约创意三角毕业论文答辩PPT模板
- DISCORD-JS-CRUD:提升 Discord 机器人开发体验
- Node.js v4.3.2版本Linux ARM64平台运行时环境发布
- SQLight:C++11编写的轻量级MySQL客户端
- 计算机专业毕业论文答辩PPT模板
- Wireshark网络抓包工具的使用与数据包解析
- Wild Match Map: JavaScript中实现通配符映射与事件绑定
- 毕业答辩利器:蝶恋花毕业设计PPT模板
- Node.js深度解析:高性能Web服务器与实时应用构建
- 掌握深度图技术:游戏开发中的绚丽应用案例
- Dart语言的HTTP扩展包功能详解
- MoonMaker: 投资组合加固神器,助力$GME投资者登月
- 计算机毕业设计答辩PPT模板下载
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功