WebLogic Server中CMP实体bean的性能调优(二)

发表于:2008-8-21 16:59

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

分享:

  为实体Bean选择最佳缓存大小

  既然您理解了事务间的缓存是如何工作的,下面就让我们讨论一下选择最佳缓存大小方面的重要话题。默认情  况下,每个实体bean都定义有一个大小为1000的缓存。缓存大小由weblogic-ejb-jar.xml部署描述符中的max-beans-  in-cache元素控制。我发现该名称有些令人误解,因为根据并发策略的不同,WebLogic  Server保存无状态的实体bean实例池(采用数据库并发策略和排他性并发策略,且事务间缓存被禁止的情况下)或者(只读、乐观或排他性并发策略,且  事务间缓存启用的情况下)保存具有保留字段值的bean的真正缓存,从而无需从数据库中重新加载bean的状态就可使用。后一种情况更有趣。有人可能会  想,更改缓存大小只影响具有实体bean的操作的性能;缓存越大,在缓存中发现需要的特定实体bean实例的机会就越大。基本上是这样的,但是如我下面会  讲到的那样,另一个重要因素会影响缓存大小的选择。

  多版本化和事务的因素

  确定实体bean缓存大小的推动因素之一(可能不太明显)是当事务使用实体bean时,它们在事务的执行期间被实际加载和“固定”在实体缓存中,即使调用  者不在修改实体bean实例而仅是从中读取值。比如,想象一下,一个会话或MDB bean中的代码在一个实体bean  “Person”上执行一个finder方法,然后在返回的集合上迭代。

  ...

  Collection persons = personLocalHome.findSomething();

  for (Iterator iter = persons.iterator(); iter.hasNext();) {

  PersonLocal person = (PersonLocal)iter.next();

  Long id = person.getId();

  // do something: log, send email, etc

  ...

  }

  ...

  如果findSomething()方法返回比max-beans-in-cache中规定的值更多的对象,您的应用程序将在迭代器得到N+1个对象时  (N为当前实体缓存大小)获得一个令人不愉快的(并且很可能是不想要的)CacheFullException。这可能看上去很重要,因为一般大家都认为  finder不应返回很大的集合。但是不要忘记默认情况下WebLogic实体缓存是多版本的,这意味着如果多个事务请求同一个实体bean实例,那么会  在缓存中创建多个版本(每个事务一个);从唯一对象的角度来看这可能极大地降低了缓存容量。

  由于有多个事务同时运行在一个容器上很正常,所以可以想象如果上面的代码被从一个会话或MDB  bean中调用,其中该bean是利用一个较高的max-beans-in-free-pool参数值(默认1000)部署的,并且同时有50个客户端请  求。这使得每个事务在实体缓存中只有1000/50 = 20个可用的槽,如果一个finder返回的对象超过20个,有的事务就会失败。

  在设计具有大量实体bean的操作时要时刻牢记这一点。开发人员通常使用小型数据库这一事实使情况变得更糟,并且该问题可能并不表现出来,直到代码部署到  生产规模的数据库中时。作为保护措施,我建议在开发过程中不要使用默认的缓存大小,而是将其较低值(10-100),这样缓存相关的问题就能在开发早期发  现并解决。

  如您所见,为实体缓存选择正确的大小非常重要,并且不只是从性能的角度来看。如果缓存过大,您的应用程序将消耗很多不必要的内存,但是如果您走到另一个极  端,配置过小的缓存空间,会有收到CacheFullException的风险。那么该如何为所有的实体bean选择最佳的缓存大小呢?

  如果您没有明确为实体bean指定缓存大小,WebLogic  Server将使用默认大小1000。这对于预先知道实例数不会太多的某些bean来说足够了——比如,如果一个bean表示数据库中的一个查询表,比如  “country”或“state”,其中bean实例的上限是已知的。这种情况下,不指定缓存大小而让服务器使用默认值是完全可接受的,因为如果缓存没  有被充分利用不会对内存造成影响。顺便指出,为不变化或不频繁变化的bean使用只读并发策略是一个不错的注意;这不但消除了不必要的数据库调用,还限制  了与该bean的实体缓存中的实例具有同样PK的实例数(多版本是不是必要的),从而节省了内存,提高了性能。

  对于其中可同时访问的最大实例数未知或不能可靠地估计出来的bean,情况略微复杂些。您需要分析和估计从finder方法返回以及从一个事务内访问的最  大bean数,然后乘以可同时发生的最大事务数(这通常受您应用程序入口点的最大实例数限制——会话bean和/或MDB)。这能粗略地估计出特定实体  bean所需的最小缓存容量。

  应用程序级缓存

  如果您的应用程序使用了很多实体bean,那么分析和配置各个bean的缓存会很麻烦。估计从“master-detail”关系的“detail”端返  回的bean实例数尤为困难——比如,如果您的应用程序在“订单”表上执行一个finder操作,每个订单都有一个“项目”数可变的集合。另一个问题是由  于每个实体bean都有一个单独的缓存,内存没有得到最有效的利用。认识到“每个bean一个缓存”模型的限制,WebLogic  Server(从版本7开始)开始支持实体bean的应用程序级缓存。这使得同一个J2EE应用程序中的多个实体bean共享一个运行时缓存。

  应用程序级缓存提供了下列好处:

  它减少了实体bean缓存的数目,从而减少了配置缓存的工作量。

  它充分利用了内存和堆空间,因为减少了分段。比如,如果某一特定EJB经历了一次突发活动,它可以使用联合缓存中可用的所有内存,而使用该缓存的其他  EJB都被换出。如果两个EJB使用不同的缓存,当一个bean的缓存满时,容器就不能将EJB换出到另一个bean的缓存中,导致了内存浪费。

  它简化了管理;联合缓存使系统管理员只需调整单个缓存,而不是很多个缓存。

  它提供了更好的可伸缩性。

  为了定义应用程序级缓存,首先配置weblogic-application.xml中的entity-cache元素。然后在weblogic-  ejb-jar.xml中引用entity-descriptor元素中entity-cache-ref元素中的应用程序级缓存。您可以定义一个缓存,  然会将其用于应用程序中的所有实体bean,或者为bean组定义不同的缓存。也可以将应用程序级缓存与每个bean一个缓存混合使用,这样您就有很大的  试验空间。我建议首先从被所有实体bean共享的应用程序级缓存开始,除非您有某些特殊需求。

  使用应用程序级缓存是为每个bean指定一个缓存的可行的替代方法。可引用单个缓存的不同实体bean的数目或者已定义缓存的数目没有限制。可根据  bean实例数(与每个bean一个缓存类似的方法)或者最大内存空间来指定缓存大小。从管理角度来看,使用内存的大小很有吸引力,但是要知道  WebLogic  Server不计算缓存中bean消耗的实际内存数(这可能是一项代价很高的操作);它只是根据weblogic-ejb-jar.xml部署描述符中规  定的bean平均大小来分割内存。如果没有指定大小,则假定每个bean平均有100字节。我认为根据bean实例数指定缓存大小会更透明。

43/4<1234>
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号