高性能应用构建模式解析

标签: 性能 应用 建模 | 发表时间:2012-01-21 22:37 | 作者:
出处:http://www.iteye.com
原文: http://java.sys-con.com/node/2116436

虽然自己开发的一直都是号称"高性能, 高可用, 高并发"的"三高"应用. 但是一直没有对如何实现这种"三高"应用没有进行深入的思考, 直到最近看到这篇文章, 突然有一种醍醐灌顶的感觉. 所以简单的将其转换成中文, 以方便以后工作中的不时之需.

当谈到一个互联网系统的高性能时, 不外乎以下几点:
  • 以迅雷不及掩耳盗铃之势打开一个网页( 低延时)
  • 满足用户访问量的持续增长( 可伸缩性)
  • 提供7x24服务, 永不当机( 高可用)


下面针对实现上面的这些目标的一些常见的手法进行说明.

一. 延时

应用分层: 这个是系统出现延时的最主要的部分. 一个系统的数据一般会经过web server->application server->database三个系统. 而数据的序列化和反序列化又是整个过程中最耗时的部分. 有时候通过将web server和application server合二为一, 甚至将其揉到同一JVM进程, 然后在代码中通过逻辑分层(web层 + application层)来避免物理上的分层从而达到降低延迟. 比如使用Spring容器来帮助我们实现系统分层. 而一旦采用SOA架构(web service+jms), 网络传输和数据的序列化不可避免的增加了系统延时. 这里可以借助一些其他的东东来降低系统的延时, 比如IBM Datapower XML Accelerator和Solace Message Router (感觉有软文的成分^_^)

让数据靠近应用: 为了让数据更靠近应用, 我们将尽可能的降低对数据库的访问, 而最常用的杀手锏就是对数据进行缓存. 一般我们会在web层和应用层使用类似memcached/ehCache这样的缓存服务器. 在web层我们一般会缓存一些静态的内容, 比如HTML, 图片, javascript, css文件. 而应用层通常缓存非事务数据. 如果是互联网应用, 那么通常会采用CDN来加速静态内容的访问.

降低磁盘I/O: 磁盘IO也是系统性能杀手, 而常用的做法就是将数据保存在内存中, 比如使用内存数据库, 相关产品略去500字, 避免广告嫌疑.

任务并行化:将请求切分层小的任务并行处理, 然后再对处理结果进行合并后返回. 而对请求的处理进行分割就是所谓的Map Reduce, 这个一般通过开源软件Hadoop, CouchDB等即可实现. 也可以从语言层面来实现并行处理, 比如Scala, ERLang, Ada等. 对于Java来说, 可以使用Akka库(基于Actor模型)或者ExectorService并行包来实现.

硬件/网络配置:
     优化硬件--因为应用是跑在硬件上的, 所以对硬件的优化升级也是降低延时的一种手段, 比如采用10G/20G的网络带宽, SSD硬盘, 避免使用虚拟化技术(译注:比如我们正在推广直接在linux实体机部署应用而取代原有的虚拟机中部署)
     传输机制调整--有时候处于安全的考虑, 我们会采用SSL来进行网络通讯, 这个也会导致一定的网络延时.

最后, 通过从以上这些方面(比如缓存问题, 算法问题, 数据问题, 检查方式不对等)查找系统延时的瓶颈, 从而实现对系统的调优.

二. 系统可伸缩性

可伸缩性意味着系统能淡定的承受数据和访问量在一定范围内的暴增而不会挂掉, 另外还有最重要的一点就是以降低系统性能来实现的可伸缩性都不能称为真正的可伸缩性. 通过下面几个方面可以实现系统的可伸缩性.

系统应用无状态: 应用的状态应该集中进行存取(通常就是数据库系统), 而应用本身必须是无状态的. 因此在本地文件系统中将不会存储数据或状态. 应用无状态带来的好处就是可以通过增加任意数量的应用实例来应对访问量的增长. 不过这种做法带来的另外一个问题就是存储状态的数据库会逐渐成为整个系统的瓶颈. 随着数据的增加, 数据库的性能也会开始下降. 这时就需要分散数据库中易变的数据. 为了处理这种场景, 数据分片(data sharding)开始登场了. 另一个办法就是数据库只负责写入, 而部分或全部的读操作尽可能转移到NoSQL存储中.

负载均衡:随着系统之间的调用增加, 系统的请求压力需要通过增加应用实例来化解. 负载均衡将保证系统的压力能均匀分布, 而不会超出现有的系统负载, 使得整个系统的压力能实现自动调整. 对于数据库来说, 也可以通过采用Master-Master或者Master-Slave(读写分离)的结构来实现负载均衡. 但是如果数据增长到PB级别, 就需要采用带数据复制(data replication)的数据分片(data sharding)结构. 另外基于内存的数据表格(in-memory data grid)架构也可以解决数据的可伸缩问题.

系统容错能力: 为了保证一个大型应用集群始终处于可运行状态, 最重要的工作就是要避免人工介入. 比如当系统压力达到既定阈值时, 监控系统能自动增加应用实例, 负载均衡能重新分配调用请求, 保持整个系统压力实现新的平衡. 对于数据库来说, 如果对数据重新进行分片, 应用系统能能重新定位到新的IP并建立连接. 一旦应用系统无法识别对应的资源, 应用能自动切换到其他可用资源. 为了实现分区容错, 整个系统还需要借助一个协调各个系统之间依赖关系的元数据配置中心.

三. 系统可用性
系统的可用性可以认为是可伸缩性的产物, 下面列举的一些因素将影响到系统的可用性.

系统冗余: 系统必须做到某些部分的损坏当机(硬件或者软件)能有一定的备份及时进行补充. 这种冗余备份可以针对系统的任何层面. 比如软件, 硬件, 电源甚至是整个数据中心(即使整个数据中心瘫痪, 系统依然可用). 在大多数情况, 成本投入的大小会决定冗余备份的级别和当机时间.

系统可监控/可检测: 具备一套完善的监控系统对了解整个系统的运行状况非常关键. 如果没有监控, 那么系统的处理余量我们将无法评估. 当我们对系统进行长期监控之后, 我们就可以发现系统的执行流程以及瓶颈, 从而对系统进行调优. 一旦系统有了监控, 系统的自动扩展, 对线上系统的检查将变得更容易. 这里可以借鉴Netflix的做法, 他们借助Chaos Monkey(https://github.com/simonmunro/ChaosMonkey 一套通过在线上模拟各种故障来测试系统可靠性的框架)来检测系统的稳定性.

系统可配置: 要保证系统的持续可用还需要实现在运行过程中能对各种参数进行调整. 比如, 系统提供了新的接口, 那么能通过配置开关来打开新接口或者保证与老接口的兼容性. 当要上线一个新功能, 但是希望该功能不是一次性全部打开, 而是根据条件逐步打开的时候, 这个功能将变得非常重要.

综合上面提到的方面将从各个层面来帮助我们构建一套高可用性的系统.

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [性能 应用 建模] 推荐:

高性能应用构建模式解析

- - ITeye博客
原文: http://java.sys-con.com/node/2116436. 虽然自己开发的一直都是号称"高性能, 高可用, 高并发"的"三高"应用. 但是一直没有对如何实现这种"三高"应用没有进行深入的思考, 直到最近看到这篇文章, 突然有一种醍醐灌顶的感觉. 所以简单的将其转换成中文, 以方便以后工作中的不时之需.

Android应用性能 分析

- - CSDN博客推荐文章
  其实主要是内存方面,内存管理是个永恒的话题. 1.从工具DDMS中,在Sysinfo的tab栏里面有一个Memory usage的选项,通过USB连接Android设备以后很容易抓到图. 在图中可以看到系统随时可以用的内存是Free和Buffers两项,因为我抓图的系统只有128M的内存,所以看上去这部分可用内存已经很少了.

Android应用性能测试

- - CSDN博客推荐文章
java虚拟机有内存使用上限的限制. adb shell进入手机,这此参数被纪录在/system/build.prop中,如果想直接查看可以使用adb shell getprop. 单个应用程序最大内存限制,超过这个值会产生OOM. 单个java虚拟机最大的内存限制,超过这个值会产生OOM. android程序内存一般限制在16M,当然也有24M的,而android程序内存被分为2部分:.

应用性能监控

- - 人月神话的BLOG
先看下百度里面对应用性能监控的基本定义:. APM = Application Performance Management,应用性能管理,对企业系统即时监控以实现对应用程序性能管理和故障管理的系统化的解决方案. 应用性能管理是一个比较新的网络管理方向,主要指对企业的关键业务应用进行监测、优化,提高企业应用的可靠性和质量,保证用户得到良好的服务,降低IT总拥有成本(TCO).

提升 web 应用程序的性能

- pathfinder - IBM developerWorks 中国 : 文档库
作为 web 用户,我们知道页面加载或刷新的速度对其成功至关重要. 本文将帮助您更好地理解影响 web 应用程序性能的因素. 学习识别这些问题并且找到客户端内容的瓶颈. 探索 JavaScript、DOM、CSS 和 Dojo 小部件的性能问题. 将通过一个例子展示使用 YSlow 和 Firebug 适当调整 Dojo 小部件.

Spring/Hibernate应用性能调优

- - ImportNew
对于大多数典型的Spring/Hibernate 企业应用来说,应用程序的性能几乎完全取决于它的持久层的性能. 这篇文章将会对如何确认在“数据库约束”的应用前,使用7种“快速见效”的技巧来帮助我们提升应用性能. 如何确认一个应用受到“数据库约束”. 为了验证一个应用程序是否受到“数据库约束”,首先在一些开发环境中做一些普遍的行为,即使用 VisualVM来监控.

Spring / Hibernate应用性能调优

- - ImportNew
对大部分典型的Spring/Hibernate企业应用来说,应用的性能大部分由持久层的性能决定. 这篇文章会重温一下怎么去确认我们的应用是否是”数据库依赖(data-bound)”( 译者注:即非常依赖数据库,大量时间花在数据库操作上),然后会大概过一下7个常用的提升应用性能的速效方案. 怎么确定应用是否是“数据库依赖”.

如何提升 RailS 应用的性能?

- - ITeye资讯频道
「铁路很慢」,你也许听过这个笑话,那么我们的 Rails 框架呢. 如果说 Rails 慢,那么如何提升 Rails APP 的性能就成了开发者们最关注的问题. 也许你听说过很多提升 RoR APP 性能的方法,它们有难有易,我们需要在选择其中最能帮助开发者脱离性能困境的. 这里列举了几种不同的提升 Rails 应用性能的方法.

JAVA 应用性能监控基础

- - Linux - 操作系统 - ITeye博客
       这里简单介绍了JAVA 应用程序部署linux 服务器上的一些常用监控信息,虽然现在很多自动化监控的东西,但是一些基本的东西,我们还是需要了解.        1.我习惯性先看看 CPU 和内存的使用情况,做一个简单的关注.           命令:top 可以关注运行状态.           命令:大写P:按CPU 使用排序,大写M:按内存使用排序,小写c:详细显示应用       .

提高 web 应用性能之 JavaScript 性能调优

- 去北方-Jack - IBM developerWorks 中国 : 文档库
JavaScript 是一个比较完善的前端开发语言,在现今的 web 开发中应用非常广泛,尤其是对 Web 2.0 的应用. 随着 Web 2.0 越来越流行的今天,我们会发现:在我们的 web 应用项目中,会有大量的 JavaScript 代码,并且以后会越来越多. JavaScript 作为一个解释执行的语言,以及它的单线程机制,决定了性能问题是 JavaScript 的软肋,也是 web 软件工程师们在写 JavaScript 需要高度重视的一个问题,尤其是针对 Web 2.0 的应用.