论坛首页 Java企业应用论坛

关于系统性能的思考

浏览 27492 次
精华帖 (12) :: 良好帖 (3) :: 新手帖 (7) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-05-01   最后修改:2009-05-01
狂放不羁 写道
shenrd666888 写道
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?


呵呵,我现在仅仅是一个即将毕业的应届生而已。这些观点也是我对自己项目的一点总结吧。

建议你看看SNA的思想,把现有的想法彻底打破,重新思考软件的本质。

但是楼主实战经验不够,无法分辨出书上哪些是忽悠人的,哪些是过时的,哪些是当前可借鉴的。例如这里已经有不少高人提到业务分析的重要性,楼主可能要很久以后才能彻底明白什么叫“业务分析的重要性”。
0 请登录后投票
   发表时间:2009-05-02   最后修改:2009-05-02
icewubin 写道
狂放不羁 写道
shenrd666888 写道
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?


呵呵,我现在仅仅是一个即将毕业的应届生而已。这些观点也是我对自己项目的一点总结吧。

建议你看看SNA的思想,把现有的想法彻底打破,重新思考软件的本质。

但是楼主实战经验不够,无法分辨出书上哪些是忽悠人的,哪些是过时的,哪些是当前可借鉴的。例如这里已经有不少高人提到业务分析的重要性,楼主可能要很久以后才能彻底明白什么叫“业务分析的重要性”。



呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。
0 请登录后投票
   发表时间:2009-05-02   最后修改:2009-05-02
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。
0 请登录后投票
   发表时间:2009-05-02   最后修改:2009-05-02
icewubin 写道
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。



呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。








0 请登录后投票
   发表时间:2009-05-02  
狂放不羁 写道
icewubin 写道
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。



呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。


我来说说我的看法:
1 因为网络本身是无状态的,所以用SNA能更好地利用网络的特性来提高性能。
2 很多时候用集群比分布式更好,网络之间的远程调用是有代价的。EJB这种重量级组件对服务器的要求就很高,用得不好反而直接影响系统的性能。
3 软件的核心当然是业务啦, 再好的技术没有好的业务也没用,SUN就是个例子。
4 如果多台server集群就会出现缓存失效的问题, 使用底层数据库作为全局锁是一种解决方案,当然memcache那种分布式缓存也是一种解决方案。

我认为影响系统性能的几个因素:
1 memory 慎用池化,有可能造成memory leak。
2 同步   
3 数据库  索引,IO等。

0 请登录后投票
   发表时间:2009-05-03  
狂放不羁 写道
呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。

不错,1、2、3的书你都看过,那我只能说你确实是实战经验不够了。

你说的第3和第4提到的思想在一定的前提下是完全正确的,但是和第1点是矛盾的:
1.SNA架构下的缓存的设计首先要避开分布式通讯的问题,然后就是缓存结构和对象图没有必然联系,或者说缓存占用的内存和JVM没有必然联系,再或者说用JVM做缓存是有很大的约束条件的。

2.缓存设计和业务是紧密相关的,首先是确定数据实时性的要求,有T+1、6小时、3小时、1小时、5分钟、严格事务实时,不是所有查询需求都是要严格事务实时要求的,举个具体的例子就是,不是所有业务系统的信息展示的要求是要达到股票交易的实时性的。这是业务分析重要性的一点,我起了个头。因为从软件工程角度来说,一个架构设计是寻找各方面成本的平衡点,开发成本、部署成本(包括硬件)、维护成本等,针对不同业务实时性的特点,不同的模块的缓存设计是不同的,之所以不同,是因为有些设计可以极大的降低某一类成本。例如像JE的某个圈子的首页,除了一些个人登录信息以外,大部分统计类的信息的实时性要求是很低的,如果要设计一个小功能点,显示某个圈子的发贴总数,你可以有N多种的实现方法,至于你最终选择哪一种,更多的是根据业务特点来定的,而不是根据某个万精油一样的技术模式(不是领域设计模式,更高一层的模块设计模式)来决定的。这个例子表示了,业务分析的重要性,一个合适的系统的设计一定是更多的根据业务特点来的。
0 请登录后投票
   发表时间:2009-05-03  
从技术角度来说,要进行性能的提高 一般先要找到性能的瓶颈所在,那个地方性能是性能的瓶颈,为什么会有这样的瓶颈进行分析.如果性能的瓶颈是来自于系统逻辑实现本身 那么你实现要考虑的如果消除这种逻辑瓶颈.一般可以通过分解逻辑进行消除,把本来一气呵成的东西分成很多小东西进行.其次你要好考虑能否用批量的任务进行处理.比如系统日志模块是否有必要用户每次的操作都要实时的记录还是先把用户操作记录写道缓存 然后再批量入库呢,是否对某些轮询任务进行休眠等等...
如果这个瓶颈是来自于一些外部环境,比如网络,数据库等等.这时候你要考虑的就是这么和减少这些外部环境交互的次数.一次IO能完成的就没必要用两次,连接长短的选择,SQL的优化等等.如果这些瓶颈是完全出在外部环境,比如数据库查询效率很低,那么你就该考虑如何去优化.比如数据库的索引,数据区域的整理等等.
很多时候CPU和内存是冤家,你高我低,你低我高的.这时候就要具体考虑了.

反正一句话, 找瓶颈,判断瓶颈类型,进行解决方案论证,解决问题,回归测试. 如果是在不行那么也只能靠群集,负载均衡了.
0 请登录后投票
   发表时间:2009-05-04  
icewubin 写道
狂放不羁 写道
呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。

不错,1、2、3的书你都看过,那我只能说你确实是实战经验不够了。

你说的第3和第4提到的思想在一定的前提下是完全正确的,但是和第1点是矛盾的:
1.SNA架构下的缓存的设计首先要避开分布式通讯的问题,然后就是缓存结构和对象图没有必然联系,或者说缓存占用的内存和JVM没有必然联系,再或者说用JVM做缓存是有很大的约束条件的。

2.缓存设计和业务是紧密相关的,首先是确定数据实时性的要求,有T+1、6小时、3小时、1小时、5分钟、严格事务实时,不是所有查询需求都是要严格事务实时要求的,举个具体的例子就是,不是所有业务系统的信息展示的要求是要达到股票交易的实时性的。这是业务分析重要性的一点,我起了个头。因为从软件工程角度来说,一个架构设计是寻找各方面成本的平衡点,开发成本、部署成本(包括硬件)、维护成本等,针对不同业务实时性的特点,不同的模块的缓存设计是不同的,之所以不同,是因为有些设计可以极大的降低某一类成本。例如像JE的某个圈子的首页,除了一些个人登录信息以外,大部分统计类的信息的实时性要求是很低的,如果要设计一个小功能点,显示某个圈子的发贴总数,你可以有N多种的实现方法,至于你最终选择哪一种,更多的是根据业务特点来定的,而不是根据某个万精油一样的技术模式(不是领域设计模式,更高一层的模块设计模式)来决定的。这个例子表示了,业务分析的重要性,一个合适的系统的设计一定是更多的根据业务特点来的。


呵呵,多谢老哥耐心的讨论。实战经验方面确实欠缺很多。那个领域驱动设计我也接触不久,还不到2年时间,并且我只是看了<<领域驱动设计>>后很有感触,所以在自己的创业项目中应用了(不幸的是创业失败了,不过还是学到很多),其它关于领域驱动设计的知识也都是从infoq,yahoo group,TSS上面学习的,自己实战的不多,很多公司也不用呵呵。

对于第一点,SNA的缓存设计首先避免分布式的开销这点我理解,但是第一点后面的不太理解,我觉得缓存的设计与对象图是有关系的(或者我没理解老哥的对象图的含义),以前一个项目中,因为我应用了全局的缓存,但是因为面向对象的设计功底不好,没有设计好合理的聚合根,结果最后导致了全局缓存中的对象在并发环境下状态很难控制,最后不得不重构对象模型,经过重构后,对象状态也变得更加容易了,所以我觉得缓存首先应该要确定一个全局的入口,系统所有设计到缓存的操作,都首先要从全局的缓存入口得到对象,并且这个很大程度上是一个聚合根,聚合根对象要封装好整个聚合的状态,不能将状态暴漏给客户,这样容易控制聚合的状态不变量。还请老哥能解释一下呵呵,多谢。
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-05
狂放不羁 写道
呵呵,多谢老哥耐心的讨论。实战经验方面确实欠缺很多。那个领域驱动设计我也接触不久,还不到2年时间,并且我只是看了<<领域驱动设计>>后很有感触,所以在自己的创业项目中应用了(不幸的是创业失败了,不过还是学到很多),其它关于领域驱动设计的知识也都是从infoq,yahoo group,TSS上面学习的,自己实战的不多,很多公司也不用呵呵。

对于第一点,SNA的缓存设计首先避免分布式的开销这点我理解,但是第一点后面的不太理解,我觉得缓存的设计与对象图是有关系的(或者我没理解老哥的对象图的含义),以前一个项目中,因为我应用了全局的缓存,但是因为面向对象的设计功底不好,没有设计好合理的聚合根,结果最后导致了全局缓存中的对象在并发环境下状态很难控制,最后不得不重构对象模型,经过重构后,对象状态也变得更加容易了,所以我觉得缓存首先应该要确定一个全局的入口,系统所有设计到缓存的操作,都首先要从全局的缓存入口得到对象,并且这个很大程度上是一个聚合根,聚合根对象要封装好整个聚合的状态,不能将状态暴漏给客户,这样容易控制聚合的状态不变量。还请老哥能解释一下呵呵,多谢。

你说的第二段很不错,很有想法,但是这条路是不通的,这句话如何理解,我一点点说给你听:
1.确实是有系统如你所说,几乎每步操做都需要极其严格的事务要求(严格序列化,说的通俗点叫做先后顺序必须要保证),单单说到这其实还是比较好实现的,一般的消息队列都能做到这个效果(脑子里先去除关系数据库的桎梏)。但是有些系统除了严格的序列化,还需要有非常高的实时性要求,假设包括外部因素总延时在5秒之内吧,上交所的股票交易系统就是这样的一个典型例子。

这样的系统不是不能做,但是代价太大,而且做法和通常的做法完全不一样,基本没有什么普遍性可言。他们的做法,说的简单点就是全内存操作,巨大的内存几乎加载了所有必要的实时数据。。。

2.第一个例子过于极端,说说第二种情况,绝大多数的银行吧,为了保证核心系统(实际是记账中心)的交易无差错,基本上所有的操作最终都集中在一台大型机上,跑数据库的(你不要幻想数据库集群能有效的提高性能,那是骗人的)。

3.从第二个例子中的数据库集群骗人事件,引出,如果你仔细看过 J2EE Without EJB的话,我记得好像有这么一句话,最好的分布式就是不要做分布式,感觉有点故弄玄虚,主要意思是这样的,一个通常的分布式集群的系统,其各个节点间的通讯(包括各种同步等的开销)代价往往会把集群带来的性能提升完全抵消掉,而且这样的集群基本没有线性的扩展性,集群的机器数量越多,集群中节点间的通讯的代价就越发恐怖。SNA的思想就是尽可能避免这种依赖于一种集中式集群的瓶颈。我个人还认为,节点间互相关系密切的集群系统的集成测试和运维、升级的复杂度是惊人的高的,成本巨大。

4.我再从另一个角度来说,第一点提到消息队列,恩,当你把一个消息队列的功能做得非常完善,或者说当你把一个缓存系统做得非常完善,例如加上一些类似于数据库的事务控制,那你可能就是在自己造一个分布式数据库了。Memcached DB算是一个这样的典型例子吧。这种缓存系统作为产品拿来用用还是比较靠谱的,自己造,而且要没有什么bug,这代价好像大了点吧。

5.如第四点所说,应该把缓存结构独立出来,单独考虑,例如你要用Memcached服务做缓存服务器,先和原本的J2EE的架构分离出来,JVM本身就是大小限制的,真要用Java做大的缓存框架,其实限制是很多的。所以不要迷信各级缓存,缓存结构不是你想像的那么简单的,不仅仅是开发和设计、调试和部署的成本都非常高。

6.做项目好像人生,不如意十有八九,预算成本和时间成本都是有限的,又要结构简单,又要效果好,往往得从业务出发,简单的例子我前面讲过,例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构,和避开性能瓶颈。而复杂的例子,例如寻找外星人的项目,或者是Google的Map/Reduce,或者是林登实验室的Second Life的分布式计算结构,都是针对特殊的业务设计的。这些都不是传统的编程手段或技术能直接实现的。

7.拓展一下思路吧,第六点提到的简单例子“例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构”,这个例子貌似简单,如果对查询的实时性要求不高,但是查询速度要求很高的话,楼主可以看看数据仓库的概念,不是要楼主学习数据仓库,而是拓展一下思路,思维不要局限在Java或者说JVM上,不要局限在事务型关系数据库存储上。

8.再做个引申,大量的事务型操作其实是很容易造成瓶颈的,但是有时候适当的一些假设,就能够部分的不使用事务,例如假设某张表中没有update和delete操作,只有insert操作,整个业务模块按照这个假设设计就能够很简单的实现,实际上现实世界中的财务流水帐在业务模型上就是这么设计的。。。

9.你有一定的项目经验,一般能根据需求估算出一个系统的各方面的负载有多大,然后再根据以往项目实施的经验,就能比较靠谱的掌握一个性能、成本的平衡点了。
0 请登录后投票
   发表时间:2009-05-05   最后修改:2009-05-05
根据JE童鞋们的回复,作个总结,提高性能系统的根本:
1. 一个系统通常要考虑的不是性能,而是单位时间内的吞吐量和响应时间的均衡。
2. 技术可以提高性能,池话,负载均衡,分布式都可以提高性能,但是这些都有瓶颈。性能的根本在于业务设计,进行业务的深度分析才能从根本上提高性能。
3. 系统的瓶劲主要集中在数据库的吞吐量。真正最为常见地影响软件系统性能的是对数据库的访问,而非数据库本身的优化。

获益非浅啊,投精华。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics