呵呵,我真的不知道该怎样说了,如果我说你不理解企业应用你一定不承认,可是从实际来看你确实不动企业应用。
1、有冗余就代表需要同步,那么同步时间是什么程度,企业应用的可接受程度是多少??你有相关数据么??对于一般网站慢一些可能无所谓,但是对于电信级应用这就是需要考虑的问题。
2、为什么数据库有了镜像还需要备份策略拿??因为有的时候我们需要对历史进行追踪,需要对某一刻的东西进行一个记录,这个记录很重要,当我需要的时候可以适当恢复,那么你用什么方法来恢复到某一个点拿??如果没有恢复那么,如果一个操作错了,我如何来恢复它拿??
3、不管是领域模型,还是其他模型,我们面对的是保存在内存中的数据,跟是否使用什么模型无关,使用领域模型还是关系模型只是存储方式,何况所谓领域模型也摆脱不了基本数据类型的束缚。
4、如果我想有一个开发环境,需要一定的生产环境数据,那么我怎样获取生产环境的数据??难道我需要手工生成??

>>不管是领域模型,还是其他模型,我们面对的是保存在内存中的数据,跟是否使用什么模型无关,使用领域模型还是关系模型只是存储方式,何况所谓领域模型也摆脱不了基本数据类型的束缚。

这个观点,实在不敢同意。保存在内存中应该是聚合根的对象,聚合根要控制对其子对象的访问,如果内存中放的是数据,这样缓存中的并发访问很难控制,要想并发控制简单,那么就需要封装好对象,通过根访问子对象。


ps:电信的项目,具体我不清楚,但是我公司最近的建行的项目,我是看出来,给所谓的大企业,财主做系统,系统的性能可以靠硬件支持着。昨天用建行的封装好的台写了个demo,简单的例子,控制台全部是sql语句,如果换其他没钱的企业,估计这系统跑不起来。一个做所谓的做企业级应用的公司,技术不一定是最重要的,也许人家技术一般般,但是业务牛B,系统做出来了,性能不行,好,去换个高性能的服务器,换个高性能的应用服务器,接着换个高性能的数据库服务器。搞定。

>何况所谓领域模型也摆脱不了基本数据类型的束缚。

这个认识很有普遍性,以为数据就是对象,看看教科书和学校出来的论文,满嘴数据数据的,看看国外的技术文章,都是Object Object,现在国人有了一个翻译工作,他们叫Object,我们叫数据,而且似乎抓住问题本质了,这是相当可笑。

对象不只是数据,是聚合体,是一个对象群,并时刻能在多台服务器内存中维持自身的统一性,就像你们兄弟俩一起闯江湖,不论到哪块服务器内存中,你们兄弟俩都会彼此照顾,什么叫照顾呢,就是外界改了你兄弟的状态数据,那么你就要检查会不会影响到你自己,在业务上你们两个是否应该一起修改,打个比喻:订单总金额应该是订单每个条目金额加起来的总额,如果有人只是改了一个订单条目金额,没有修改订单总金额,那么这就破坏了订单这个对象的一致性了。

而数据就不会彼此照顾,都是死的东西。数据都躺在数据表里光着身子不知羞耻的让所有人随便进来动动修改。

>当数据库数据变化时,如何同步缓存
>数据库数据为什么会变化,首先因为是缓存里对象发生变化,所以,缓存变化是在数据库变化之前,一定要改变这种习惯思维。
这么看来DDD只能用于独立系统。企业应用都是逐步成长起来的,无法保证所有对数据库的更新都通过缓存里的对象。而且也无法保证和其它系统的接口都通过对象。
即使是全新开发的系统,业务不断变化,域模型也就不可避免的发生变化,由于持久层由域模型控制,对应的数据库表结构也会发生变化。这种变化会造成历史数据备份无法恢复,这是企业应用绝对无法接受的。

>当更新完成内存中聚合对象群以后,再通过一个专门机制sync将数据库向缓存看齐,更新数据库。
同步的时间如何控制?同步到数据库之前系统崩溃怎么办?造成的数据丢失和不一致如何解决?人工修复由域模型自行生成的数据库数据几乎就是噩梦。

>共享内存肯定需要属于某一个设备,那么设备是否又成为单点
>我们有分布式缓存 集群就是本质上分布式缓存,几台服务器内存集群在一起,就象一块大内存,任何一个点失败,都没有单点风险,其他机器顶上。
没有单点风险,那同一个对象应该在几台服务器都有缓存,否则一台服务器崩溃就会造成对象丢失.这样的话,内存不是很浪费吗?

>为什么数据库有了镜像还需要备份策略拿??因为有的时候我们需要对历史进行追踪,需要对某一刻的东西进行一个记录,这个记录很重要,当我需要的时候可以适当恢复,那么你用什么方法来恢复到某一个点拿??如果没有恢复那么,如果一个操作错了,我如何来恢复它拿??

非常同意,企业应用对数据的关心超过一切,可以牺牲性能,但是数据安全和可追述性要保证。如果那天需要查5年前的数据,你告诉老板,对不起,模型变了,数据库结构不一样,无法导入历史数据,什么下场就不用说了。
最简单的,数据太多,影响性能,要求导出并删除1年前的数据。对于完全由域模型控制的数据库,表结构都不是你定的,怎么操作?

>>没有单点风险,那同一个对象应该在几台服务器都有缓存,否则一台服务器崩溃就会造成对象丢失.这样的话,内存不是很浪费吗?

缓存缓存就是暂时存储的意思,大量的数据还是放在数据库里啊。一台服务器宕掉了,大不了重新从数据库里面拿到内存啊。请不要太较真了。

>>企业应用对数据的关心超过一切,可以牺牲性能,但是数据安全和可追述性要保证。

这句话,我同意。确实是这样的,尤其像银行这样的地方,数据安全很重要,他们有钱,通过强大的硬件来支持。但是并不是说企业级应用数据安全重要,缓存就不重要,这个是两个层面的问题,缓存的不是数据,是聚合对象。你当然可以不用缓存的,照样也可以做系统,就比如我公司现在的系统,速度慢的要死,但是建行照样在用啊,为什么,人家有高性能的服务器,高速度的磁盘阵列,高性能的数据库系统。

所以各位大哥大姐,叔叔,阿姨,缓存和数据没什么必然联系,缓存中存储的是业务对象,是数据经过加工后的结果。如果在缓存中存储的仅仅是数据的话,那还不如不用缓存了,因为你没有办法控制并发线程对数据的访问,从而也就失去了对数据状态的控制。而如果保存的时候对象的话,那么我们可以给对象加不变量约束以及每个操作都可以有后验条件,每次操作都不会破坏状态的完整性,而如果只是数据,不是设计合理的对象,我想您还是不要用缓存了,用了也是自找苦吃,没办法控制数据状态。
[该贴被xmuzyu于2009-04-30 16:17修改过]

>缓存缓存就是暂时存储的意思,大量的数据还是放在数据库里啊。一台服务器宕掉了,大不了重新从数据库里面拿到内存啊。请不要太较真了。
我也没说所有数据都在缓存里,问题是内存是昂贵的,你每台服务器都缓存一份对象,消耗几倍的内存,性能是不是有几倍的增长呢.举个例子:一共10G数据,你5台服务器,每台2G缓存,一共就缓存2G数据,还有大部分数据在硬盘上,如果不分布,一台10G内存,全部数据都在内存里.如果觉得数据这词不好,可以换成对象.那个方案性能更好呢?


>所以各位大哥大姐,叔叔,阿姨,缓存和数据没什么必然联系,缓存中存储的是业务对象,是数据经过加工后的结果。
我讨论的不是数据和缓存的关系,我也同意缓存很重要.我的主要问题是采用DDD后,随业务变化带来域模型变化,从而影响数据库结构,历史数据库的备份无法导入系统,造成历史数据无法访问。还有就是系统崩溃时,缓存没有写到数据库里造成的数据丢失和不一致如何解决。

5x2就是10啊,怎么“一共就缓存2G数据”了呢?
好像绝大部分缓存的应用都用来提高读的性能,写操作应该还是直接入库的

>>我也没说所有数据都在缓存里,问题是内存是昂贵的,你每台服务器都缓存一份对象,消耗几倍的内存,性能是不是有几倍的增长呢.举个例子:一共10G数据,你5台服务器,每台2G缓存,一共就缓存2G数据,还有大部分数据在硬盘上,如果不分布,一台10G内存,全部数据都在内存里.如果觉得数据这词不好,可以换成对象.那个方案性能更好呢?


呵呵,并不是说所有的数据都放到内存,因为缓存有置换算法,比如FIFO,LFU,LRU等,我们可以根据系统的运行情况来改变的。那些经常不使用的对象,缓存系统会动态的清除,而只有那些经常用的对象才会在缓存中呵呵。

至于你所说的每个服务器10G的内存相当于缓存2G的内容,其实这个时候,你要用分布式的缓存了,可以采用集中控制的策略,就好比SNA架构那样,在数据库前面架设缓存服务器,所有的服务器获得数据都是从集中的分布式缓存服务器拿,缓存中的数据其实没有备份的,并不是您理解的集群环境下的session复制。

还有一点需要声明的就是:缓存中的对象其实都是从根据系统运行的动态特性,从DB加载的,如果一台缓存服务器宕掉了,也没事,大不了从DB重新加载一次呵呵。


也许您做了很多企业级的系统,呵呵,我也理解企业级系统数据是很重要,最近我公司的建行项目,我也看出来了,性能对于银行来说,不重要,即使这个系统性能有问题,不是我们的问题,我们会说要换高性能的服务器了,如果还是有性能问题,我们会说IBM的东西都用了,还是性能不行,我们也没办法。但是其实您也可以换种角度考虑的,我以前也是思路换不过来,其实等换过来了,由是一种新的思路,只不过平时做银行的项目,还得按照人家的平台来哈哈。人家也许更加讲究项目管理,比如100多号人的项目组做3年的系统,我公司就有一个例子,这个时候项目管理就很重要了呵呵。

我从来没有说过缓存不重要,一直以来我都强调这是完全两种不同的概念。从计算机的结构上来看,CPU有cache,有内存,有硬盘,难道因为cache得速度最快就要说内存跟硬盘没有用处么??领域模型很重要,他是代表着未来系统进行扩展以及变化的能力,这也就是为什么无论什么项目都要进行项目设计的原因,但是最后这些东西要变成计算机能够读懂的东西,要变成101011000这样的东西,这是任何项目的必然归宿。我们可以讨论领域模型,讨论缓存提升性能,但是缓存永远也取代不了数据库,这是不争的事实。

>> 还有一点需要声明的就是:缓存中的对象其实都是从根据系统运行的动态特性,从DB加载的,如果一台缓存服务器宕掉了,也没事,大不了从DB重新加载一次呵呵。
这是不是意味着是为读而缓存的?
如果这样,那拿缓存去杀死数据库,就更荒谬了。
“缓存中的对象”是“从DB加载的”,是不是意味着存储在数据库里的就是对象?

>>我们可以讨论领域模型,讨论缓存提升性能,但是缓存永远也取代不了数据库,这是不争的事实。

其实我赞成Banq,xmuzyu所说的缓存的重要性,以及用面向对对象的思想设计系统。但是ACoder说的对,数据库的重要性是无法替代的。

我觉得我们不能什么问题都讨论缓存,什么问题都去讨论
存的是数据还是存的对象。。难道对象不是数据在内存中的一种表现形式吗?我觉得对象是一个动态的概念,而数据的既可以是动态的,也可以是静态的。

不过,我确实觉得Banq,xmuzyu对面向对象思想理解得相当深入,值得我们学习。谢谢大家。

>>“缓存中的对象”是“从DB加载的”,是不是意味着存储在数据库里的就是对象?

什么叫RDBMS?除非你用对象数据库。我的意思是对象,更准确一点说是聚合的根对象,是有数据库加载的,也许这个聚合根的对象需要多个表的数据来填充,你不用model缓存,可以,每次操作,你可以调用数据库完成,但是利用了缓存以后,我们可以操作聚合根啊?为什么操作聚合根啊?因为聚合根能保证整个聚合的不变量不被破坏啊,并且聚合根中操作还要满足操作的后验条件,这些都是裸体的数据无法实现的。更加极端点将,model缓存是正对业务对象的,不是正对数据的,如果要把裸体的数据放到缓存中,别的不说,缓存的并发控制,就够你受了,你怎么控制裸体的数据在多线程环境下的不变量,还能有时间考虑核心:业务模型吗?所以内存中的业务对象缓存是一种新的思想,是一种对面向对象设计以及多线程并发编程的挑战,如果没有学好面向对象的设计,没有设计好聚合根,那么很难做对状态的控制,更不用说多线程下的状态控制了。

把业务对象缓存起来的目的是通过内存中的锁机制来实现并发,而不是以前那种单纯的靠数据库事务锁来控制并发,这些都是新的思路,新的思想。用内存锁控制并发,事务仅仅用来保证事务的原子性。

最后说一句:能不能用缓存,能不能用面向对象的设计,能不能用DDD可能不是你的问题,很大程度上是有大环境造成的,比如公司已经有了封装好的IDE,封装好的开发平台,要想换掉代价很大。但是你自己能不能改变一下思想就是自个的事情了。

>>我们可以讨论领域模型,讨论缓存提升性能,但是缓存永远也取代不了数据库,这是不争的事实。
这确实是个事实。我们用缓存的目的并不是说不用数据库,而是说让我们更加关注软件的核心:业务对象模型,或者说领域模型。从我理解的角度来说,要想用好缓存,面向对象的设计以及并发编程是很重要的,同时面向对象的设计对对象在并发环境下安全的发布与共享也是非常重要的。


对于banq的回复,我真的深表可笑,难道你现在成了买办主义的代表任务么??老外的东西就要当成金科玉律的皇王圣旨么??何况中国的语言本来与国外的语言本来就有出入,很难说明object是代表这一个什么样子的东西,但是不管是什么样子的东西,在计算机内他总要代表一个存储,一个物理位置。
至于你说的两个兄弟的例子,更加不值得一说,比如我改变了哥哥的某个特性(比如统一一下两个人穿一样颜色的衣服),那么方法是先换一个人之后再换另一个人,还是招两个人给兄弟两个一起换那??如果是第一种方式,就需要同步时间(时间成本以及锁),第二种方式需要更多的资源(双线程,事务锁),同时如果是分布应用还需要网络传输。这些东西你从来不用考虑是么??