关于缓存的思考

作者:xmuzyu 发表时间:2009年04月24日 14:18  回复
原贴网址: http://www.jdon.com/jivejdon/thread/36063.html

在评价一个系统的时候,性能指标是很重要的,那么在当前J2EE的系统开发当中,如何来提高系统的性能呢?我觉得应该从对象管理入手,从对象的生命周期开始。虽然大家可能会说,Java有垃圾收集器,我们的对象的生命周期不需要我们自己管理,但是如果要是真的过分依赖java语言本身的特性,那么我相信,系统的性能肯定好不到哪去。

下面我主要说一下对于缓存的理解。在说 缓存之前,我不得不说一下面向对象的设计,可能有些人认为,为什么 缓存会与面向对象的设计扯上关系,其实这就是 缓存的关键。首先设想一下,如果开发系统的过程中,都是采用面向过程,面向数据库的思维编程,每一次业务操作,我们都是调用通过数据库操作来完成,这其实就是POEAA中的事务脚本,只适合一些简单的系统的开发,或者一个项目中,比较简单模块的开发,对于复杂的模块,更好的方式就是采用面向对象的方法来进行开发。

好了,说到了面向对象的设计问题,至于这个问题已经有很多书籍以及很多人讨论了很多年了,就我个人来说,我觉得采用DDD建模是目前比较适合的一种方式。DDD中涉及到得每种模式或者说是每一种模型元素对于 对象设计来说都是很重要的,而对象模型的设计又对缓存的设计非常重要,下面我说说我的想法:

首先我说一下关于聚合的问题,为什么说聚合对于 缓存非常重要呢?这其实涉及到了一种控制访问的问题,一个聚合根控制了对整个聚合的访问,要想访问聚合里的对象必须要通过聚合的根。 好了,我们以一个实例来说话,比如jdon中的Forum对象的设计,在jdon中有ForumState对象,Forum对象是聚合的根,是一个实体模型,而ForumState是一个值对象,并且是属于Forum这个聚合根的子对象,我们把ForumState对象从Forum对象分离出来,好处主要有两个,从事务的角度来说,当我们更新ForumState对象的时候,不用锁住Forum对象,从 缓存设计的角度来说,当我们更新ForumState对象的时候不用刷新Forum对象的 缓存,因为Forum不是经常改变的,所以不必要因为经常改变属性的改变而改变。那么具体怎么来设计呢?我们可以这样做,在ForumState对象中设置一个状态位,表示它的状态是否已经改变,当Forum状态发生改变,比如有人创建新的帖子或者回复了帖子后,我们可以设置这个状态位为true,表示状态已经改变,这样当再次从 缓存中取得Forum时,查看状态位,如果发现已经变化了,那么就重新从数据库加载ForumState。当然要想达到这种效果,我们一定要设计好聚合,所有对子对象的访问都要通过聚合的根,比如所有对ForumState对象的访问都要经过Forum对象,并且要保证所有的数据库操作,都首先从统一的缓存入口进行,这样保证了整个系统中用的是同一个 缓存,大家操作的所有对象都是同一个 缓存中的对象。所以这里也给出了一条对象设计的提示,将经常变化的熟悉和不经常变化的属性分开,并且将经常变化的属性独立出去,作为聚合根的 一个子对象,这样做到变和不变分离,不仅有利于高内聚,而且有利于事务的控制和 缓存的更新。

下面我说一下关于Jdon缓存的一些想法,在jdon的Forum和ForumState对象的 缓存设计中,我看到了Forum有个embedded位表示对象中嵌套的对象是否已经加载完整,当得到Forum对象后,如果发现ForumState已经加载了,那么就直接返回,当有论坛有回帖或者是创建帖子的时候,就重新加载ForumState.还有一种方法也可以这么实现。可以在ForumState对象中增加状态是否改变的标志,那么当我们创建一个主题或者回复帖子的时候,首先从系统 缓存的统一入口处拿到Forum,然后通过Forum得到ForumState对象,并设置ForumState状态改变标记为true,这样以来,当下次从 缓存取出Forum对象的时候,检查两个标记:embedded和 stateChanged,如果embeded为true,但是stateChange也为ture,那么我们重新加载ForumState对象,然后设置stateChanged为false.当然了这样需要对stateChanged的操作同步。这样设计的好处就是将对模型对象的操作都封装在模型对象内部,便于多线程环境下的并发访问控制。因为从把所有对对象的操作都封装起来,方便多线程下的并发同步问题。

上面是关于Repository在对象建模中的作用,下面我也说说关于工厂的作用,既然是工厂,那么它肯定要生产东西出来,但是它不能随便乱生产,它生产出来的应该是整个聚合的根,并且要保证这个聚合的不变量受到保护,这样通过工厂提供一个集中的模型创建的访问点,也方便了控制访问。要设计一个好的工厂,我们首先需要设计一个好的对象模型,分辨出合理的聚合,这样工厂才会发挥真正的效力。

最后既然说到了 缓存,还有一点需要注意,那就是这个 缓存的范围,我这里说的 缓存是全局的 缓存,是一个application级别的 缓存。我个人是比较反对在Httpsession中保存大量数据的,这样当用户增多的情况下,比较会浪费很多的内存,浪费性能。所以我们更应该需要的是全局的 缓存,这样底层的缓冲框架我们还可以采用分布式的 缓存系统,这样以来我们的系统在集群环境下也免去了一些session failover的开销。这其实也是一种SNA架构的思想。

你可能感兴趣的:(设计模式,多线程,编程,PHP,项目管理)