分布式缓存问题请教

一个B/S结构的项目中,原来的架构是一个WEB服务器 + 一个数据库服务器。WEB服务器上做了数据缓存。但是后来因为业务需求,客户要把一个WEB服务器变成N个WEB服务器。。这样如何保证缓存内的数据同步。网络上查找了写资料。说是要用分布式缓存技术,好象EJB就可以解决。
但是具体分布式缓存技术如何实现,我不是很清楚,EJB也没有用过,只是在理论上了解一些。
懂的老师,麻烦讲详细具体点,因为如果讲得太抽象,我可能不明白,呵呵,谢谢了。

老师不敢讲,你这种情况其实可以采用SNA架构,虽然SNA架构是PHP首先提出的,但是思想可以通用,并且一般JAVA中都采用memcached来实现的,通过memcached分布式缓存系统,这样你集群环境下,session全部集中保存在memcached里。这时候的架构就是:浏览器--->>(多个web服务器-->>多个应用服务器)-->>memecache分布式缓存服务器-->>数据库服务器。

谢谢 xmuzyu,
浏览器--->>(多个web服务器-->>多个应用服务器)-->>memecache分布式缓存服务器-->>数据库服务器

这里多个web服务器,多个应用服务器,),memecache分布式缓存服务器 物理上都是分开的三类服务器吗。 另外web服务器是类似apache的WEB服务器多个吗。 多个应用服务器是多个tomcat/jboss这样的服务器吗。 因为我们以前一直是只有一个tomcat服务器。没有其他服务器了。能否把你说的画一个逻辑架构视图给我看看,或者物理架构视图也行。谢谢。

分布式缓存有jbosscache torrecotte等。

分布式缓存放的是对象,对象不只是数据,是聚合体,是一个对象群,并时刻能在多台服务器内存中维持自身的统一性,就像你们兄弟俩一起闯江湖,不论到哪块服务器内存中,你们兄弟俩都会彼此照顾。数据就不会彼此照顾,都是死的东西。

数据的一致性很重要,这个维持动作必须由对象自身来完成,如果你分布式缓存中放的不是对象,而是数据,那么难免出现一些数据在这台服务器,有些数据在另外一台服务器,不是同进同出的,没有共同生命周期,如果要进行数据一致性维护,改了一个数据再改另外一个数据,又要依赖数据库操作。

建议楼主学习一下Evans DDD,对你系统架构有帮助,不掌握业务建模设计技巧,纯粹地就技术架构论技术架构,没有意义,每个公司的技术架构都不一样,因为他们根据自己的业务特点进行了优化,这也是核心价值,否则,你用memchaed,别人也用,反正花钱就能买来,但是要跟自己业务结合,就不是三天两天的事情,也不是请比尔盖茨来就能解决的,虽然不一定请得动他。



[该贴被banq于2009-04-30 09:57修改过]

呵呵,为什么那么多人没有意识到缓存的重要性,我觉得还是面向对象的思维没有培养好,DDD中的聚合概念没有理解清楚,对对象的生命周期理解不清楚。如果对聚合,面向对象的设计理解深入的话,就自然而然的需要缓存了。因为有面向对象和数据库有时候是矛盾的,2年前刚来jdon的时候,没怎么理解板桥老师的话,觉得和自己想的完全不是一回事,但是通过自己的不断的思考,越来越明白banq老师的苦心了。

比如我就遇到很多问题,如果将对象封装的好一点,尽量实现一个富模型,那么这个对象持久化的时候就很头疼,尤其是在对象之间的关系比较多的时候,聚合里面有很多子对象的时候。这个时候采用hibernate等ORM,如果要保存或者修改聚合根的话会很头疼,因为简单的操作,hibernate会生成很多的sql。做这种头疼的事情,我想谁都不愿意,所以为了减轻这种痛苦,我会选择缓存,因为从缓存里取出来的对象是完整的,是个血肉丰富的对象,我可以直接调用我设计好的操作,更重要的是这些操作都是不会破坏聚合的不变量约束的,同时这些操作也是满足相应的后验条件的。只有调用这些操作,我们才不会破坏聚合。而如果用业务对象缓存的话,那么我每次就要把这些对象保存到数据库,这样很头疼。以前本来要进行10次操作数据库的操作,而用了缓存之后,也许就只有1次,2次了,减轻了对象和数据库之间的不匹配带来的痛苦。

总之,如果没有设计好业务对象模型的话,就算你缓存了,你也没有办法控制并发情况下,缓存对象的状态,所以还不如不缓存。
[该贴被xmuzyu于2009-04-30 15:34修改过]

Evans DDD 哪里这方面的电子书,Banq,如果你有的话,可否发给我一份。谢谢。

>>如果将对象封装的好一点,尽量实现一个富模型,那么这个对象持久化的时候就很头疼,尤其是在对象之间的关系比较多的时候,聚合里面有很多子对象的时候。这个时候采用Hibernate等ORM,如果要保存或者修改聚合根的话会很头疼,因为简单的操作,hibernate会生成很多的sql


这个问题,我想用过Hibernate的都会有体会的,确实很头疼。

缓存是系统非常重要的环节,尤其对OO方式设计的系统,保持数据的一致性更难,java框架那么多,没有一个对这方面特别支持的,要做缓存,都要手工维护,但要做大量的工作。hibernate同样在这方面不怎么支持。因而我做了一个很轻量的freeze框架,主要用来解决缓存问题。
[该贴被davin于2009-05-04 18:55修改过]

楼上你只要告诉我你的系统缓存是怎样找到一个对象的方式我就知道时候可以值得进行推广应用了。

-->系统缓存是怎样找到一个对象
用对象Id找POJO对象,但必须要对其定义主键,否则系统不能缓存。如果是一个非持久化复杂对象,可以手工缓存,目前对象版本只是粗粒度版本,它不会控制到具体的某一个对象。

通过map??

用的是ehcache缓存,也可以用其它缓存

>>>如果是一个非持久化复杂对象,可以手工缓存,目前对象版本只是粗粒度版本,它不会控制到具体的某一个对象。
请教:既然“它不会控制到具体的某一个对象”,那这缓存与OO有啥关系?那不就是普通的系统缓存嘛?
希望有具体的、详尽的解释。我很困惑。

我的理解很肤浅,就是控制好聚合根,根对象对service开放public,根下对象都不可见,针对根进行缓存,一个业务修改动作只有单一的访问点。

对于缓存而言,缓存的目标只是数据,而跟样式无关。