锁定老帖子 主题:关于系统性能的思考
精华帖 (12) :: 良好帖 (3) :: 新手帖 (7) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-06
高性能在是主要,至于技术实现 是次要。
|
|
返回顶楼 | |
发表时间:2009-05-06
高性能在是主要,至于技术实现 是次要。
|
|
返回顶楼 | |
发表时间:2009-05-07
icewubin 写道 fjlyxx 写道 关于第二点 还需要仔细的斟酌,因为把业务弄得数据库要考虑数据库的压力问题.业务放置的位置要么在前台逻辑要么在数据库.放在前台可以减缓数据库压力,放在后台可以提高前台处理能力. 但是有这么一个问题,如果前台有需要进行群集的时候 后台数据库的业务逻辑如何处理. 这时候跑数据库也许就是一个瓶颈了. 总之还是要小心跑数据库这个陷阱,需要很充分的考虑.
第二点我没有说清楚,其实每一点都应该写得具体一点,手酸啊。 这一点我的理解是这样的,银行业务的特点一般是外围系统加核心系统,外围无论如何优化业务,都是要调用核心系统的接口,银行固有的业务特点使得相当一部分业务办理的操作无法做深层次的优化,例如借记卡余额的查询(这种查询操作是不可能做缓存的,对于外围系统来说,每次查询必须要调用核心系统的接口,而不能自说自话的做缓存)。 那么然后说核心系统,暂且不论核心系统是否通过缓存优化一些查询操作,至少目前基本上大部分操作还是依赖于数据库的。我叽叽歪歪说了这些,无非就是举个例子,有这样的场景,无论中间层或外围如何优化,最终对于数据库的压力是固有的,逃不掉的。例如每小时处理10000笔转账业务,这必然带来10000次数据库操作(肯定不止),这是业务特点加上目前的银行核心系统架构带来的固有的数据库的压力。 在这种场景下,因为银行的海量数据,不得不在核心数据库上动脑筋: 1.某人说,数据库做集群不就完了么?Scale Out,可惜几乎不可能,原因复杂一言难尽。 2.一般只能做Scale Up,加CPU,加内存,一般使用大型机,来提高吞吐量。 举这个例子也是想拓宽楼主视野,不同行业,不同业务特点带来的系统瓶颈的位置都不太一样。 其实对于数据库的压力来说,OLTP是远远小于OLAP的,当出现大吞吐量的数据库事务操作时,首先撑不住的并不是数据库,而是业务系统。在实际应用中,数据库的分布式计算绝大多数场景都是在数据挖掘和数据仓库上,或者是消息中间件的转储。银行确实是个比较特殊的案例,但在银行系统中出现了数据库的集群并不能说明系统的性能瓶颈在数据库部分。 不太清楚fjlyxx所说的前台是指什么?web表示层还是所有除数据库外的系统?不过至少,把大量的业务逻辑写在数据库(通过存储过程的方式)并不是一个好的应用模式。 |
|
返回顶楼 | |
发表时间:2009-05-07
前台是指除数据库外的系统 我的意思是 如果把逻辑放在数据库 有可能为以后应用群集带来麻烦. 这时候数据库的业务逻辑就是一个瓶颈了.
|
|
返回顶楼 | |
发表时间:2009-05-07
最后修改:2009-05-07
凤舞凰扬 写道 icewubin 写道 fjlyxx 写道 关于第二点 还需要仔细的斟酌,因为把业务弄得数据库要考虑数据库的压力问题.业务放置的位置要么在前台逻辑要么在数据库.放在前台可以减缓数据库压力,放在后台可以提高前台处理能力. 但是有这么一个问题,如果前台有需要进行群集的时候 后台数据库的业务逻辑如何处理. 这时候跑数据库也许就是一个瓶颈了. 总之还是要小心跑数据库这个陷阱,需要很充分的考虑.
第二点我没有说清楚,其实每一点都应该写得具体一点,手酸啊。 这一点我的理解是这样的,银行业务的特点一般是外围系统加核心系统,外围无论如何优化业务,都是要调用核心系统的接口,银行固有的业务特点使得相当一部分业务办理的操作无法做深层次的优化,例如借记卡余额的查询(这种查询操作是不可能做缓存的,对于外围系统来说,每次查询必须要调用核心系统的接口,而不能自说自话的做缓存)。 那么然后说核心系统,暂且不论核心系统是否通过缓存优化一些查询操作,至少目前基本上大部分操作还是依赖于数据库的。我叽叽歪歪说了这些,无非就是举个例子,有这样的场景,无论中间层或外围如何优化,最终对于数据库的压力是固有的,逃不掉的。例如每小时处理10000笔转账业务,这必然带来10000次数据库操作(肯定不止),这是业务特点加上目前的银行核心系统架构带来的固有的数据库的压力。 在这种场景下,因为银行的海量数据,不得不在核心数据库上动脑筋: 1.某人说,数据库做集群不就完了么?Scale Out,可惜几乎不可能,原因复杂一言难尽。 2.一般只能做Scale Up,加CPU,加内存,一般使用大型机,来提高吞吐量。 举这个例子也是想拓宽楼主视野,不同行业,不同业务特点带来的系统瓶颈的位置都不太一样。 其实对于数据库的压力来说,OLTP是远远小于OLAP的,当出现大吞吐量的数据库事务操作时,首先撑不住的并不是数据库,而是业务系统。在实际应用中,数据库的分布式计算绝大多数场景都是在数据挖掘和数据仓库上,或者是消息中间件的转储。银行确实是个比较特殊的案例,但在银行系统中出现了数据库的集群并不能说明系统的性能瓶颈在数据库部分。 不太清楚fjlyxx所说的前台是指什么?web表示层还是所有除数据库外的系统?不过至少,把大量的业务逻辑写在数据库(通过存储过程的方式)并不是一个好的应用模式。 通过存储过程确实是个不好的应用模式。同样的还有一种情况也是不好应用模式。比如采用SSH开发,一个事务性的操作,action-service-dao这种方式进行,还是一种面向过程的思维,整个的事务性操作中逻辑还是依赖于service,依赖于dao,这种情况下还是会造成大量的数据库操作,并且此时领域对象就是数据容器,不是一个真正的富模型。所以我想要向摆脱对数据库的频繁的操作,就需要实现一个富模型,一个事务性的操作中,操作的是具有业务意义的对象,并且业务逻辑也是由领域对象(比如一个聚合根领域对象)来实现的,这样等到最后的时候再进行数据库的操作显著的减少对数据库的操作次数。所以我觉得采用SSH开发,还是要求有良好的面向对象设计的功底,尽管系统中的功能性的组件生命周期由容器管理的,但是系统中真正的业务对象还是要靠我们自己来管理(比如通过工厂,builder,repository,缓存等来管理)。 呵呵,我这篇文章的意思主要也是通过缓存来缓存业务对象,缓存中存储的是我们系统中的富有业务意义的,有不变量保证,以及方法后验条件保证(所有的这些保证领域对象的不变量约束)的的领域对象,而不是普通的数据(如果缓存普通的数据,还不如不缓存,因为并发环境下,缓存中的数据不变量很难控制,只有设计良好的,严格封装的的对象模型才是一个好的对象模型,才是一个能在并发环境下安全发布的模型),这个时候业务对象的生命周期中就有两个生存的空间:缓存和数据库。而不是以前那样,业务对象的生命周期期间只有一个生存空间:数据库。 |
|
返回顶楼 | |
发表时间:2009-05-07
最后修改:2009-05-07
狂放不羁 写道 通过存储过程确实是个不好的应用模式。同样的还有一种情况也是不好应用模式。比如采用SSH开发,一个事务性的操作,action-service-dao这种方式进行,还是一种面向过程的思维,整个的事务性操作中逻辑还是依赖于service,依赖于dao,这种情况下还是会造成大量的数据库操作,并且此时领域对象就是数据容器,不是一个真正的富模型。所以我想要向摆脱对数据库的频繁的操作,就需要实现一个富模型,一个事务性的操作中,操作的是具有业务意义的对象,并且业务逻辑也是由领域对象(比如一个聚合根领域对象)来实现的,这样等到最后的时候再进行数据库的操作显著的减少对数据库的操作次数。所以我觉得采用SSH开发,还是要求有良好的面向对象设计的功底,尽管系统中的功能性的组件生命周期由容器管理的,但是系统中真正的业务对象还是要靠我们自己来管理(比如通过工,builder,repository,缓存等来管理)。
呵呵,我这篇文章的意思主要也是通过缓存来缓存业务对象,缓存中存储的是我们系统中的富有业务意义的,有不变量保证,以及方法后验条件保证(所有的这些保证领域对象的不变量约束)的的领域对象,而不是普通的数据(如果缓存普通的数据,还不如不缓存,因为并发环境下,缓存中的数据不变量很难控制,只有设计良好的,严格封装的的对象模型才是一个好的对象模型,才是一个能在并发环境下安全发布的模型),这个时候业务对象的生命周期中就有两个生存的空间:缓存和数据库。而不是以前那样,业务对象的生命周期期间只有一个生存空间:数据库。 1.数据库最早发明的时候就是对象数据库,但是为什么关系型数据库能够得到普及和流行呢(这个自己了解一下吧)?只要后台的存储方式还是关系型数据库,就不可避免的有面向过程的味道掺杂在其中。我再推荐一本书吧《Pojo In Action》。 2.数据库和缓存空间本来就不在一个级别上,之前我已经提醒JVM的内存管理大小是有限制的,JVM中能够缓存的业务对象模型的数量也是有限制的。 3.SSH并发下难道会不安全么?并发问题不是什么大问题,集群下的节点间的通讯(例如缓存的同步,HttpSession的同步才是大问题吧)。 4.我相信你应该知道Hibernate的二级缓存吧,如果把Hibernate的二级缓存放在一个比较成熟的缓存结构中,不就是你描述的效果么(可能还有点差别吧)? 5.我是不赞成使用Hibernate的二级缓存的,或者是引用你的话,就是不赞成业务对象的生命周期有两个生存空间,这和SNA的设计思想是矛盾的,SNA的设计思想简单来说就是尽可能避免某一个节点中出现有状态的东西(例如缓存,但不是绝对的)。 6.你这样的想法不是不可以,而且你说了你也实践过,整个过程中,你觉得开发上“省”下的时间成本,在调试、部署和运维上是不是又加倍在还债呢? 7.你的这套方案的假设是,你认为数据库性能不佳,要尽可能地减少对数据库的操作。那我顺着你的想法来回折腾一下,既然缓存也是业务对象的生存空间,那必然也有数据库的事务特性吧,那是不是你在创造一个分布式对象数据库呢(只不过这个对象数据库跑在内存里)? 恩,有人会说缓存框架也可以脱离JVM内存嘛,空间不够了写磁盘啊,哦,一旦写了磁盘,那和传统数据库还有啥区别啊,传统数据库也是磁盘加缓存的结构啊,要知道中间层的缓存技术,数据库也不是不能用的啊,只不过缓存的粒度不一样而已。 再说说,假入数据不大的话,数据库本身也可以放在内存中,或者说把数据库的数据文件指向虚拟硬盘,那数据库的操作性能也是很好的啊。。。 8.你认为缓存结构性能一定比数据库好,是要有量化数据作保证的。假设两台机器集群,两台机器之间做缓存同步,你要有具体的数字评估缓存的效果,因为两台机器之间要做缓存同步,缓存同步是需要时间的,你必须要量化测试的,而且随集群数量的增加,缓存同步的开销甚至于成指数形式上升。 |
|
返回顶楼 | |
发表时间:2009-05-07
最后修改:2009-05-07
要么我还是抽时间说说SNA相关的一些简单的实践技巧和好处吧。
1.测试简单,无状态啊,设计上不要产生有状态的东西,不出现脏读,就可以了,相对于缓存同步机制,调试非常简单,集成测试也很简单。 2.实际的策略一般是,需要负载均衡配合,粘性路由策略,例如某个IP发送的请求,在半小时之内都指向同一台应用服务器,这样的话,就不需要HTTP Session同步了。 3.系统更新非常简单,一台一台更新就是了,不需要把所有服务器全部停止再一起更新。 4.系统横向扩展也非常简单,机器随便加,如果必要的话。 5.即使没有缓存同步,依然可以在设计上做一些缓存,例如数据字典的缓存,几乎不会有太大变化的,有些事几年才变化一次的,例如中国的省份和直辖市的名称列表,缓存失效时间(不是LRU,就是总的缓存有效时间)可以设为24小时,有些是每天只有几次变化甚至于一次一次变化都没有,例如某个企业的部门中的员工信息,缓存时间可以设为10-60秒,这样使得高并发的时候,对单台应用服务器来说,这些信息的获取不再会对数据库造成很多的查询压力。 6.至于更高一级的,例如页面缓存,完全可以用squid这类的反向代理加反向代理所在机器的本地缓存,在应用服务器之前做集群(这个一般企业应用不会用到)。 7.一个业务系统,无论前台和中间层,如何优化最终该操作数据的还是得操作数据库(业务固有的复杂度是不会消失的),我想说的是,基于SNA的思想的做法和基于缓存同步的集群的思想,都是可以有各自的办法来减少无谓的数据库操作,但是无状态的简单结构能够极大的降低调试和运维成本,横向扩展性也非常好。 |
|
返回顶楼 | |
发表时间:2009-05-07
最后修改:2009-05-07
icewubin 写道 狂放不羁 写道 通过存储过程确实是个不好的应用模式。同样的还有一种情况也是不好应用模式。比如采用SSH开发,一个事务性的操作,action-service-dao这种方式进行,还是一种面向过程的思维,整个的事务性操作中逻辑还是依赖于service,依赖于dao,这种情况下还是会造成大量的数据库操作,并且此时领域对象就是数据容器,不是一个真正的富模型。所以我想要向摆脱对数据库的频繁的操作,就需要实现一个富模型,一个事务性的操作中,操作的是具有业务意义的对象,并且业务逻辑也是由领域对象(比如一个聚合根领域对象)来实现的,这样等到最后的时候再进行数据库的操作显著的减少对数据库的操作次数。所以我觉得采用SSH开发,还是要求有良好的面向对象设计的功底,尽管系统中的功能性的组件生命周期由容器管理的,但是系统中真正的业务对象还是要靠我们自己来管理(比如通过工,builder,repository,缓存等来管理)。
呵呵,我这篇文章的意思主要也是通过缓存来缓存业务对象,缓存中存储的是我们系统中的富有业务意义的,有不变量保证,以及方法后验条件保证(所有的这些保证领域对象的不变量约束)的的领域对象,而不是普通的数据(如果缓存普通的数据,还不如不缓存,因为并发环境下,缓存中的数据不变量很难控制,只有设计良好的,严格封装的的对象模型才是一个好的对象模型,才是一个能在并发环境下安全发布的模型),这个时候业务对象的生命周期中就有两个生存的空间:缓存和数据库。而不是以前那样,业务对象的生命周期期间只有一个生存空间:数据库。 1.数据库最早发明的时候就是对象数据库,但是为什么关系型数据库能够得到普及和流行呢(这个自己了解一下吧)?只要后台的存储方式还是关系型数据库,就不可避免的有面向过程的味道掺杂在其中。我再推荐一本书吧《Pojo In Action》。 2.数据库和缓存空间本来就不在一个级别上,之前我已经提醒JVM的内存管理大小是有限制的,JVM中能够缓存的业务对象模型的数量也是有限制的。 3.SSH并发下难道会不安全么?并发问题不是什么大问题,集群下的节点间的通讯(例如缓存的同步,HttpSession的同步才是大问题吧)。 4.我相信你应该知道Hibernate的二级缓存吧,如果把Hibernate的二级缓存放在一个比较成熟的缓存结构中,不就是你描述的效果么(可能还有点差别吧)? 5.我是不赞成使用Hibernate的二级缓存的,或者是引用你的话,就是不赞成业务对象的生命周期有两个生存空间,这和SNA的设计思想是矛盾的,SNA的设计思想简单来说就是尽可能避免某一个节点中出现有状态的东西(例如缓存,但不是绝对的)。 6.你这样的想法不是不可以,而且你说了你也实践过,整个过程中,你觉得开发上“省”下的时间成本,在调试、部署和运维上是不是又加倍在还债呢? 7.你的这套方案的假设是,你认为数据库性能不佳,要尽可能地减少对数据库的操作。那我顺着你的想法来回折腾一下,既然缓存也是业务对象的生存空间,那必然也有数据库的事务特性吧,那是不是你在创造一个分布式对象数据库呢(只不过这个对象数据库跑在内存里)? 恩,有人会说缓存框架也可以脱离JVM内存嘛,空间不够了写磁盘啊,哦,一旦写了磁盘,那和传统数据库还有啥区别啊,传统数据库也是磁盘加缓存的结构啊,要知道中间层的缓存技术,数据库也不是不能用的啊,只不过缓存的粒度不一样而已。 再说说,假入数据不大的话,数据库本身也可以放在内存中,或者说把数据库的数据文件指向虚拟硬盘,那数据库的操作性能也是很好的啊。。。 8.你认为缓存结构性能一定比数据库好,是要有量化数据作保证的。假设两台机器集群,两台机器之间做缓存同步,你要有具体的数字评估缓存的效果,因为两台机器之间要做缓存同步,缓存同步是需要时间的,你必须要量化测试的,而且随集群数量的增加,缓存同步的开销甚至于成指数形式上升。 1 RDBMS有坚实的数学理论基础。相反的面相对象的数据库在数学理论方面欠缺。还有您推荐的<<pojo in action>>以前看过但是没看完,最近在看。个人觉得很多和POEAA很像,也可以说是POEAA的实践版本。 2 缓存和数据库确实不是一个级别,JVM也确实有限制,但是之所以叫缓存那就是暂时存储一部分数据,大小限制也没事,只是一部分,不是全部。 3 缓存同步确实是存在问题,但是session同步也存在严重的问题,我说缓存一方面集群环境下是减少session同步问题,如果不集群的情况下,缓存可以减少数据库操作。比如tomcat那种多机备份策略,同步更加有问题。而对于分布式缓存的同步由分布式缓存系统来完成。其它的应用服务器采用不同的策略,以前看过TSS上一篇文章,揭开J2EE集群神秘面纱,写的很好。 4 hibernate缓存我也不喜欢使用,除了一些不常变化的数据,比如一些地址等的信息。我一般是以前在service层通过开源的缓存系统,通过拦截器或者代理模式来做缓存,并且目前我做的一个项目是通过Repository(DDD概念)和builder模式控制了缓存。 5 正是您所说的不是每个项目都适合SNA的,这里的缓存也可以是SNA中那种缓存服务器的缓存,也可以采用jbosscache torrecotte等分布式缓存系统 6 这样主要是减轻了hibernate向RDBMS映射的痛苦(尤其是业务对象设计的关联比较多的时候,每次hibernate都要生产N多sql。 7 现在开源的缓存系统有很多,我并没有自己开发分布式的缓冲,只是通过封装好的业务对象模型来实现状态的并发更新,所以我说面向对象的设计不仅对于设计一个好的对象模型很重要,同时对于设计对象模型的缓冲也很重要,一个没有经过良好设计的,状态到处暴漏的丑陋的模型,即使用了缓存,也是自找苦吃,状态并发更新的情况下,头痛死了。对于并发编程方面,我个人比较推荐<<java 并发编程实践>> 8 在数据库集群的时候也存在同样的问题。 |
|
返回顶楼 | |
发表时间:2009-05-07
最后修改:2009-05-07
狂放不羁 写道 1 RDBMS有坚实的数学理论基础。相反的面相对象的数据库在数学理论方面欠缺。还有您推荐的<<pojo in action>>以前看过但是没看完,最近在看。个人觉得很多和POEAA很像,也可以说是POEAA的实践版本。
2 缓存和数据库确实不是一个级别,JVM也确实有限制,但是之所以叫缓存那就是暂时存储一部分数据,大小限制也没事,只是一部分,不是全部。 3 缓存同步确实是存在问题,但是session同步也存在严重的问题,我说缓存一方面集群环境下是减少session同步问题,如果不集群的情况下,缓存可以减少数据库操作。比如tomcat那种多机备份策略,同步更加有问题。而对于分布式缓存的同步由分布式缓存系统来完成。其它的应用服务器采用不同的策略,以前看过TSS上一篇文章,揭开J2EE集群神秘面纱,写的很好。 4 hibernate缓存我也不喜欢使用,除了一些不常变化的数据,比如一些地址等的信息。我一般是以前在service层通过开源的缓存系统,通过拦截器或者代理模式来做缓存,并且目前我做的一个项目是通过Repository(DDD概念)和builder模式控制了缓存。 5 正是您所说的不是每个项目都适合SNA的,这里的缓存也可以是SNA中那种缓存服务器的缓存,也可以采用jbosscache torrecotte等分布式缓存系统 6 这样主要是减轻了hibernate向RDBMS映射的痛苦(尤其是业务对象设计的关联比较多的时候,每次hibernate都要生产N多sql。 7 现在开源的缓存系统有很多,我并没有自己开发分布式的缓冲,只是通过封装好的业务对象模型来实现状态的并发更新,所以我说面向对象的设计不仅对于设计一个好的对象模型很重要,同时对于设计对象模型的缓冲也很重要,一个没有经过良好设计的,状态到处暴漏的丑陋的模型,即使用了缓存,也是自找苦吃,状态并发更新的情况下,头痛死了。对于并发编程方面,我个人比较推荐<<java 并发编程实践>> 8 在数据库集群的时候也存在同样的问题。 1.pojo in action中的离线悲观锁,看一看,很有意思的。 2.对呀,既然暂存一部分数据,必然有缓存失效的问题。 缓存作为生存空间,这不就是相当于自己另外造了一个ORM么?只不过你认为Hibernate让你不满意而已。 我总感觉楼主的缓存概念太局限在JVM中了,前台squid+memcached的页面缓存结构和后台的数据库如何做缓存的都应该适当了解一下。 3.问题就是,你认为单机的结构,能够很顺利的迁移到多机的,基于分布式缓存系统的框架下,这个愿望是美好的,实际操作却是非常痛苦的。自己造这种级别的轮子是需要很多的实战经验的,例如单例模式的陷阱等等。 6.Hibernate映射RDBMS不需要很痛苦,简单映射,不使用高级功能,仍然面向过程好了,pojo in action中的script pattern没什么不好啊,java不太适合充血模型的,大多还是写在Service中的Script Pattern而已。 我发现楼主不太了解Hibernate,虽然hibernate达不到你理想中的ORM,但是在一个事务中,合理的编程,Hibernate也是不会触发多余的sql,实际上在尽量不触发sql上,Hibernate是做了大量的工作的。而你说Hibernate会触发大量的sql,我只能说你们使用上有问题。 而由于这个原因使得你期望重造轮子,唉。。。 7.恩?两个问题,第一,同一个JVM中的并发编程,和多台机器中不同的JVM中的程序互相通讯是两码事吧,<<java 并发编程实践>>帮不上太多的忙吧。第二,多台机器之间的通讯(即使是建立在成熟的分布式缓存产品之上),实际的调试和测试成本仍然是高得惊人。 恩。。。你是单机吧,第二点我说了没啥用,这样说好了,单击情况下,假如我用SSH做项目,一般不会有并发问题的,是不是因为你自己在造ORM工具这个大轮子的时候,碰到了很多并发问题呢? 8.数据库集群可以另开一个很大的话题了,这里不讨论。 |
|
返回顶楼 | |
发表时间:2009-05-07
楼主不要见叶就是森林,至于你说领域模型举例那个Forum好像也是jdon中的例子。高性能高并发的应用设计。不是抽象几个概念就能解决的。不过下面大家的跟贴中部分牛人的思路很正。
|
|
返回顶楼 | |