楼主的东西,可能指的是外存吧?本来是要存入外存(硬盘)的,缓一缓再存进去。
>>>它是class,当然是class,因为我用的是java。
我说错了,本来应该说是Object。误导了你。
这Object,一般是代码与数据的结合体。把整个Object缓存?有必要嘛?里面的code可是不变的、只读的。有必要也缓存嘛?本来存也不需要存的,何必缓呢?
我就是有许多不明白,才打搅的。
你使用的硬盘,上面会标明有8M的缓存,CPU的cache是为了提高内存访问速度而设置的缓存,缓存就是为了提高访问速度而运用的一种手段,而不是必须得方法,不要神话它,这个技术在计算机发展的二十年前就已经存在且比较成熟了。
那么缓存里面存什么??比如你有一个箱子,你如果用来放衣服,那么你可以称之为衣箱,如果放水果,可以称之为水果箱。但所有的箱子就是来放东西的。当你放衣服的时候你查找的方式是按照一件一件的方式来找,如果是水果就是一个一个或者一种一种,但是对于箱子而言,放的是水果还是衣服有讨论的意义么??缓存就是那个箱子,里面放的是数据,你用OO的方式放进去的就要按照object来找,如果是放进去的是一个数组,那么你取出来就一定要是数组。哪有说缓存就是为了OO设计的。
缓存的对象跟方法有关么??无关!!不光缓存无关,就算你new了长千上万个对象,方法始终存在程序的代码区,有且只有一份,而属性放在了数据区,两个同类而不同的对象区别只在于属性,方法是无区别的。
最后劝一下banq不要对自己不知道的领域妄加评论。
缓存不是取代持久化存储的。持久化存储不可能被取代。我想说的是,大家普遍认为的缓存应该是只需要读的,但是我们经过业务对象的建模,形成的业务对象是线程安全的,这样放到缓存中就可以全局的并发写操作。并且这样有个好处就是,锁是针对具体的场景的,因为我们自己最清楚那些业务对象的并发访问会很大,大访问量的业务对象可以采用细粒度的锁。如果不这样在并发情况下就需要采用事务隔离级别加乐观锁或者悲观锁来进行,但是悲观锁是粗粒度的锁,粒度粗了,并发性也就减低了,而乐观锁有会造成冲突事务只能重来,而通过细粒度的锁既能保证并发性,同时还可以保证操作都能成功。其实采用缓存+业务对象细粒度锁是一种新的思路。新的思路必然面对新的挑战,挑战在这个帖子的前面也讨论了很多。
>>哪有说缓存就是为了OO设计的。
呵呵,OO为了提高性能,提高伸缩性所以才用了缓存。缓存用的地方实在太多,我们只是借用一下缓存来缓存业务对象。
[该贴被xmuzyu于2009-05-31 12:14修改过]
缓存整个object有必要,这个object其实多数是聚合根。因为我需要全局并发写操作,而不是依赖过去的乐观锁,悲观锁来控制并发访问。
至于锁,这是一个非常复杂的问题,比如对于一个链表,从效率上讲在需要修改的一个元素上锁定就好了,但是这样做有的时候会使得链表上的iterator失效,所以必须在链表上加锁。
乐观锁与悲观锁的选择上,我原来就说过,一切应当以可靠性作为基础。
对于应用以上几种缓存的一点经验是对于多用户,可伸缩性要求很高的web或企业级应用,应该避免内存中保存锁(除一些内容管理类型的应用程序),而推荐大量应用事务范围缓存(类型1),但是也有限制,比如内存要求很大,因为事务范围内存消耗和并发数成正比
对于process相关缓存(类型2)或集群范围缓存(类型3)一个比较好的备选是
a.很少改变的对象
b.不重要的对象(如内容管理类型的应用)
c.应用程序固有(数量一定)的对象
d.被其他类的很多实例引用的实例(称为引用数据)
[该贴被yellowcat于2009-06-02 15:14修改过]
[该贴被yellowcat于2009-06-02 15:23修改过]
十个程序员里面有几个能够精通hibernate的使用呢?
[该贴被yellowcat于2009-06-02 22:53修改过]
关于锁:
现在的web接入server,比如apache、tomcat之类的都是多进程的,一个请求一个进程。所以对共享内存进行正确操作就必须要有同步机制,加锁是必须的,上面有人所说的乐观锁、悲观锁我估计就是读锁、写锁。在linux/unix中锁从程度来说只有读锁、写锁、不锁,从时间上来说只有阻塞式锁、非阻塞式锁。
当然你也可以说你自己做一个逻辑server,web server全部接入到逻辑server处理数据,逻辑server起单进程,这样就可以不用共享内存,也就不用锁了。这样确实是不用锁了,这样你的程序会慢的吓死人,一堆请求堵在那里等着处理。所以,虽然很有必要做一个逻辑server来剥离web接入和逻辑数据处理,但是也必须是多进程的。当然锁就不可避免。
实现锁的方法也是多种多样的:原子操作,信号量,文件锁等等都是可以的。
缓存说白了就是一块共享内存。共享内存的意义就是进程间通讯。
缓存中还有一个概念叫做命中率,了解了这个概念之后就会明白被缓存起来的每组数据(比如一组数据就是一个用户的资料)越小越好,这样命中率才能更高,如果命中率低,那你的缓存是在降低效率而不是提高效率。所以缓存整个类的做法好不好大家也应该知道了。
命中率解释:举个例子,你现在从程序去A的相关信息,发现缓存里面有(这就命中了),直接返回给你;如果没有(没有命中),就要先到持久层(DB)去取数据,然后放到缓存里,再返回给你,这样比没有缓存还慢。所以,当你有100组数据要存,但是可用内存大小只能存50组数据(到了50之后的缓存数据就只能覆盖其他的),你的命中率应该就在50%左右,如果你每组的数据变小了,内存可以放80组数据了,那么你的命中率就提高了,自然程序响应速度就快多了,磁盘读写是相当慢的。所以,要使每组数据最小,而把整个类放到缓存的做法可取吗?
缓存也分2中:同步缓存和异步缓存。
这个主要是针对写而言,读是不存在的。所以任何高命中率的缓存对读的性能提高相当大。
同步:当更新数据时,先把数据更新到缓存,然后放入持久层,放入成功后再返回成功信息。
异步:当更新数据时,先把数据更新到缓存,然后返回成功,之后再去把数据放到持久层。
所以同步缓存对写操作来说没有任何的提高。异步缓存对写操作性能有很大的提高。
那为什么不全部用异步缓存呢?因为异步存在风险,万一更新到持久层失败了怎么办,万一在更新之前那块内存被覆盖了怎么办?
所以要看具体业务模型选择,异步缓存一般同步机制用消息队列,但是消息队列又不是无限大的,各个操作系统不一样。
上面是我所了解的,希望对大家了解缓存有一定帮助。
至于你说的区别,区别就是缓存中的对象要保证自己的状态不变量,所以我以前也说过,对象的缓存中,首先是对象的设计,只有设计好了对象才适合放到缓存中。这些是我自己的做法,而面向对象的设计以及并发编程也是我自己的爱好。
不过这样做对团队整体素质要求很高,毕竟不是每个人对并发编程都很熟悉。