如何解决有限的资源和运算能力分配问题

11-12-22 KenWT
近日在工作上遇到这么一个问题,我们公司的应用在现场服务器环境中运行中,发现了一些问题,比如一个完整产品的某个模块处理数据的进度在产品升级后变得较之前缓慢,甚至在刷新数据方面完全失效,进而导致前台报表没有展示出近期的业务数据。在解决开始阶段,就遇到了现场的数据库超过最大连接数的情况,所以无法对失效的数据库对象进行更新等操作。无奈之下,现场运维同事就协助对数据库进行了重启,重启之后,数据库恢复服务。紧接着,主管召集大家开会,探讨针对这些运行中的问题的解决方案,一番讨论之后,结果,解决方案全是针对程序的逻辑处理过程的优化,其实这样的优化,相对目前版本来说,从程序层面来讲,理论上完全可以改善目前所暴露的问题。但是有这么一个信息,就是这次服务器上部署了多个应用,而且数据库也是公用的,这就自然而然地产生这么一个问题,产品在公司发布前,实验室的测试环境是一台服务器和专用数据库,结果没有测出某模块处理数据进度比预期慢的问题;而产品实际的运行环境中有数个应用在运行,准确地讲,是多个应用在共享有限的服务器资源和数据库的运算能力,从而产生了目前所出现的这个问题。

从问题表面上,可以这么简单地理解,就是因为程序运行所需要的资源出现了紧缺,所以在完成任务的过程中出现了异常。那么应用们在运行中,是如何争夺资源和运算能力,这些有限的服务器资源和数据库的计算能力又是如何分配给应用的呢?应用以目前的水平,在拥有多少资源和运算能力下,可以很稳定地运行呢?如何这个问题可以得到一个准确的回答,那么优化方案方面结合程序范围的解决方案的话,应该就是一个相得益彰,相当有成效的优化。这就是我今天想请教大家的问题?谢谢大家

[该贴被admin于2011-12-23 09:21修改过]

              

8
banq
2011-12-22 18:18
2011年12月22日 15:03 "@KenWT"的内容
那么应用们在运行中,是如何争夺资源和运算能力,这些有限的服务器资源和数据库的计算能力又是如何分配给应用的呢?应用以目前的水平,在拥有多少资源和运算能力下,可以很稳定地运行呢? ...

这个问题实际就是我们经常讨论的软件可伸缩性Scalable或可扩展性问题。

第一步:应用服务器和数据库服务器的资源和计算能力没有均衡分布,你这个案例是几乎负载都集中到数据库上了,而应用服务器闲置,解决这个一现象可以通过在应用服务器中引入缓存的方式。

第二步:如果应用服务器的缓存丢失率高,说明应用服务器和数据库服务器负载都很高,那么我们可以在应用服务器和数据库服务器之间引入分布式缓存如memcached。

现在架构是:

client -- > 应用服务器 (in-memory Cache) ---> memcached ---->DB

下一步就是引入云计算技术:

云计算有两种方式:一种是自己引入云计算组件,做私有云:比如对于一些复杂计算耗费CPU且频繁调用的报表计算,比如数据仓库挖掘等可以使用云计算Hadoop;对于爆炸增长的大数据量引入NoSQL等等。

另外一种是租用现有的云计算平台,租用公有云,比如Google和Amazon。

KenWT
2011-12-22 22:52
2011年12月22日 18:18 "@banq"的内容
这个问题实际就是我们经常讨论的软件可伸缩性Scalable或可扩展性问题。 ...

帮主,您好,首先对您的回复表示感谢。您讲得可伸缩和扩展性问题,这方面的理论,我目前尚且略知一二。不过我认为您的答复并没有正面回答我所关心的核心问题,那就是部署在服务器上运行中的应用们是如何相互争夺资源的?有点类似多线程的调度(要么虚拟机管理调度,要么操作系统负责),可是应用们获取运行时所需资源的多与少,这个地方的调度管理究竟是由谁,什么规则来调度呢?希望大家多多讨论,谢谢

banq
2011-12-23 09:16
2011年12月22日 22:52 "@KenWT"的内容
部署在服务器上运行中的应用们是如何相互争夺资源的 ...

首先:编程时尽量避免多线程的资源争夺,多线程有一个致命问题是资源争夺,那么难免使用锁,这些都是导致资源利用率下降的根本原因,因此,在目前多线程编程中,尽量使用不变性,或者直接使用缺省是不变性的语言Scala。这些都能避免资源纠结与争夺。

其次:无论微观如何争夺调度,我们也需要在宏观整体进行调度。在程序中多引入异步,异步可能到来最终一致性,这些都需要根据情况选用,尽量避免或缩小事务或数据库锁JDBC等锁定资源的使用范围。

这里有一个消耗资源大小或耗费性能的排列:

基于内存异步事件 ---> 内存锁 --->事务锁 --->数据库锁。

越是后面,性能越差,可伸缩性越差,资源利用帅越差,闲置率越高。

这里比较一下异步和通常同步,也就是你们现在架构的区别:

同步情况下:当你发出请求必然有一个响应结果,但是你可能接着还需要继续其他更多处理,不是立即用到这个响应结果。

这样,你不必发出请求后,就在那里傻等响应结果,而是继续做你其他更多处理,直到需要它时才过来取。

生活中排队,你去买两样东西,一样东西需要排队,那么先买不需排队的,再过来买。

等待时线程会闲置,会消耗系统资源。对于一个高交互量的系统,线程闲置数= arrival_rate * processing_time。如果arrival_rate很高,闲置数将非常高,系统工作在一个非常无效率的状态。

我上面的一个帖子是提出了解决办法,这个帖子是解释了原因,希望能够帮助到你。

在自己测试环境自己的软件是正常的,而到生产现场则不正常,这个现象非常普遍,主要是我们以前只考虑功能,没有过多考虑运营复杂状况,还有测试部门对生产现场的数据采样没有跟上,能够尽量模拟生产现场,其实最终结的办法是Event Sourcing,使用一个NoSQL将所有用户操作事件日志保留下来,然后在调试环节回放。

只有采集数据接近现实,你就能通过调试判断:应用以目前的水平,在拥有多少资源和运算能力下,可以很稳定地运行。

如果你觉得这样的数据难以获取,那么就采取可扩展的云架构,通过虚拟化技术和自动伸缩扩展功能,随着你的资源和运算能力多少,自动调配资源。

[该贴被banq于2011-12-23 09:19修改过]

BinnyJ
2011-12-23 15:58
感觉LZ的几个问题处于猜测阶段,需要有手段验证你的问题。

1.多个应用部署到同一个服务器,是否因为应用服务器满负荷(同服务器的其它应用占用很多)导致你得产品运行慢。

2.共用一个数据库,由于其它应用占用数据库资源过大导致数据查询、处理速度慢,从而导致你得产品慢。

对于第1个问题,可以通过监控服务器 硬盘、CPU等情况确定服务器是否满负荷了?对于第2个问题,可以通过监控数据库运行的SQL语句,SQL语言运行的效率,服务器运行的效率来判别是否数据库满负荷。

如果是以上2个问题导致的,那么就只能增加服务器解决或者移走其它应用。

但是,在验证上面2个问题之前,你是否确认你得产品在生产环境下是正常的。是否跟踪过你的产品处理过程每个环节,是否有调试每个环境处理的时间,性能等情况?

猜你喜欢
3Go 1 2 3 下一页