写在前面
其实谁也不敢保证自己管理的系统(系统平台)性能是否极好
关于很多对系统性能优化的资料都在表达一个问题:怎样在业务高度增长的同时尽可能的合理优化资源的消耗?如何保证用户的响应速度和服务质量?如何使有限的计算机系统资源为更多的用户服务?这似乎是一个矛盾的集合,然而矛盾的关键就在于“合理优化”上。
一套完整的信息系统平台我认为重点涉及到数据库、操作系统、网络 三个方向
下面我根据并不丰富的工作经验谈谈我对 系统性能优化的理解(仅针对在线系统环境)。
数据库优化方面
如何保证数据库运行在最佳状态,个人觉得在系统开发之前就该提前想到数据库的优化策略,比如一张表达到T级,逻辑备份时间超过检修窗口规定时间。这就是一个典型的例子。
对于数据库的优化策略大概包括,数据库参数调整,网络性能调整 应用程序sql语句分析设计等几个方面。(还有很多方面此处略)
关于数据库指标性的问题大概分为数据库吞吐量、数据库用户响应时间。
数据库用户响应时间=系统服务时间+用户等待时间。所以解决用户的响应时间问题的基本两个方向即:
1减少系统服务时间,也就是提高数据库的吞吐量。
2是减少用户的等待时间,也就是减少用户访问同一个资源的冲突率。
数据库性能上的优化具体细节可以概括成下面几个设计方向:
1.调整数据结构的设计,比如提前考虑是否使用分区表,对于经常访问的数据是否需要建立索引
2.调整sql语句设计, 应用程序执行最终将变为数据库中的sql语句执行,所以sql语句的执行效率也就决定了数据库的性能
3.程序设计,这部分的工作应该在开发系统之前就应该完成,比如我们要考虑应用程序使用什么样的体系结构,是传统的C/S还是 B/W/D,因为不同的应用程序体系结构要求的数据库资源是不一样的
4.系统内存分配设计,这部分应该是在系统运行过程中不断的优化,比如根据数据库运行的状况不仅可以调整数据库系SGA的数据缓冲区 日志缓冲区和共享池的大小,当然大小作为DBA会根据经验判断到底给多大合适,例如小库200M,中库200-400,大库400-700M,一般shard_pool_size 设置不到1G (实际环境参数设置是不一样的)
5.调整硬盘I/O 比如在系统上线之前我们可以把组成同一个表空间的数据文件放在不同的磁盘上,实现硬盘之间的I/O负载均衡
6.调整OS的系统参数 比如可以调整UNIX数据缓冲区的大小,每个进程能使用的内存大小等参数
实际生产中 数据库性能恶化从用户的角度上看,基本表现为用户响应时间过长(太卡),需要用户等待很长的时间,典型例子12306。但是造成恶化的原因却是多种多样,有时是多种因素共同造成
在我看来数据库应该关注两个重点指标:速度和吞吐量,即尽可能地缩短响应时间和同等吞吐量的基础上尽可能的提高负载能力
具体措施:
1.如果设计完善,可以避免很多优化问题,例如尽量减少不必要的表连接,这样可以大大的提高应用程序可用性
2.磁盘规划,对磁盘性能的监控非常重要,前提是在系统上线之前就对数据量进行预判,目的是使恢复时间更短,数据访问更快
3.对新添加的应用程序进行跟踪监控,新上线的模块会导致数据库工作量发生变化,性能问题也会随之而来
4.对在线系统运行过程中的优化,比如定期查看报表,可以根据累计的报表数据和系统平台上线之前的设计思路很容易找出业务增长规律,主要为了找到性能瓶颈,要么提前预防要么加以解决,典型反面教材又是12306
以上措施针对的细节举例如下:
仅列举我能想到的问题
性能调优的问题:
1、坏的回话管理,比如一次查询多次连接,会消耗资源
2、坏的游标的管理,防止同一个sql进行不同的书写方式 比如绑定变量的用途
开发阶段的调优:
1、调节设计是否合理
2、检查sql语句是否正确,写的好不好
3、调节内存
4、调节 I/O
5、调节热点块
投产的系统阶段的调优:
1、定义问题(现象的产生,例如CPU暴涨)
2、收集操作系统和oracle的指标(sql命中率,buffer cache比例等)
3、考虑常见的性能错误(这是经验活)
4、假定一个概念,就是猜想问题的根源(在测试库上实验)
5、尝试去解决问题 (测试库上实验)
6、检查这个解决问题的方式是否合适(长期观察)
调优的经验:
1、检查日志
2、检查参数是否正确
3、查看系统的I/O和内存的利用率,确定那个进程占用做多
4、检查那个sql语句大量的占用cpu和i/o (比如模块设计不合理)
如果用户感觉时间很慢 (观察statspack)
1、要分明白具体干活的时间和等待资源的时间那个慢
2、检查那部分事件占用时间最多
3、把每隔事件在进一步细化
系统的安全性和性能的平衡度
1、如果控制文件很多会导致性能下降,但是会很安全。
2、redo成员多个
3、频繁的产生检查点
4、备份数据文件的时候
5、alter system switch logfile(影响很大,数据量越大延迟越大)
6、用户事物的并发量
关于安全性和性能的取舍oracle常见的例子比如,利用DG实现的容灾,要么就牺牲两倍日志写速度采用maximum protection模式换来安全,要么担着不能绝对保证数据完全一致的风险选择maximum availability模式换来容灾上的性能提升,然而生产环境完全根据实际情况而定,无法兼得。
针对数据库方面的优化远不止这些,所以在未来的工作中会有大量的可预测及不可预测的问题出现
操作系统方面的优化(仅根据以往接触的工作进行阐述)
有一句话比较赞同,假设通过对系统的调优使其性能提升了50%(或者更高)那么可以基本判断当初设计这个系统的时候就存在非常大的问题。系统问题最直接的表现为“运行迟缓”但是产生运行迟缓的原因多种多样,不过大体概括问几个方面
1.进程太多,操作系统可能仅仅只是同时运行了太多的应用程序,或者正在运行CPU 密集型的操作。或者是服务器超负荷运行,也可能是某一个进程耗尽了大量的系统资源等等,典型例子比如又是12306,其前端设计被骂了无数次
2.活动内存太多,假设某一个进程使用了大量的内存,那么系统可能会从磁盘换入大量的页面并将大量的页面换出到磁盘,这意味着系统花费在内存交换上的时间比真正使用内存的时间更多,又一次彰显了缓存服务器的重要性
3.硬件故障,有时候会碰到莫名其妙的硬件故障导致其他服务器组件工作不正常导致系统花费很长的时间等待信息,举一个曾经遇到的问题,HA高可用集群跑在vmware虚拟平台上,但是无论如何CMAN也无法启动,光处理这个问题就花费了大量的时间和精力。
针对以上问题用到的工具
vmstat工具来监视虚拟内存统计信息
top观察活动的进程、负载以及内存统计信息
uptime观察平均负载
ps 观察相关进程
Nagios 自动化运维必不可少的工具,可以对进程 cpu 负载 硬盘进行监控 并可自行设置阀值进行报警,优势不言而喻
出现问题的系统很可能和采集到的统计信息之间并不存在直接关系,但收集的统计信息越多,对问题的定位就越精确。(经验活)
网络方面的优化(ISP方面)
仅根据自身经验进行阐述,网络性能问题直接影响到出口链路,可以比喻成数据还没进家门就死外面了...
每一个针对业务的数据机房想必都遇到过以下问题
网络核心应用如何保障?
如何进行业务优先级划分?
实际环境中整个带宽应用,P2P下载+网络电视+WEB视频流量超过80%以上(ISP运营商与校园业务类似基本如此)。而在核心网运维的过程中,主要面临的问题如下:
交付延迟:应用交付的响应超时,数据损失
网络带宽:对于终端用户和应用程序远远不够实际需求,并发请求往往超过出口链路的承载能力。
应用程序:不断增加的应用程序抢占有限的带宽资源,成倍增长的数据量已给核心业务交付带来困境。
传统管理的方式:
1.无法了解宽带网络应用和用户习惯,无法建立流量模型。网络出口升级频繁,却赶不上流量增长速度。导致网络出口升级毫无科学依据(间接的表现就是运营成本大幅度增加也无法满足业务需求)。
2.P2P、病毒和垃圾邮件以及不良信息充斥网络中,无法避免带宽滥用。并且成本高昂。
根据当前网络宽带业务的发展趋势,用户的行为越来越多样化并且难以控制,越来越多的应用开始抢占带宽:如P2P ,PPLIVE QQlive等视频点播业务。这甚至让传统的浏览网页的应用也受到了严重影响。
针对以上面临的问题采取的优化措施:
单纯通过网络层面的控制(数据包控制)已经完全无法满足实际问题 比如大多数路由器都有的CBQ队列缓存机制(实际上作用不大,基本控制不住P2P泛滥)
所以针对面临的实际问题只能通过抓包(流控设备从新设计了此功能)来识别需要控制的协议。有意思的是,P2P协议族本身就是双刃剑,他为了保证高速传输通常会进行"端口跳跃"来躲避监控设备的协议识别,举一个曾经遇到的问题,监控报警提示定义的视频数据流暴涨通过,我们用过协议识别较差的审计设备观察暴涨的流量发现竟然是QQ或者是某些私有协议(比如ERP等)。在这里插一句,根据自身经历个人觉得,大多数审计产品集成了流控功能,这是噱头,想达到协议识别精度和内容审计精度这基本不可能,至少国内尚未出现,比如某些厂商的设备明明写着承载并发30W,但是压力测试发现基本上跟指标相差甚远
在网络性能优化上,大多数办法是在出口链路上部署基于DPF和DFI技术的流控产品来实现。(关于产品,国内产品这个领域成熟产品有很多。如Panabit,网康,深信服,天融信,华为等等)
此处需要解释一下为何不通过WEB端(WEB服务器)来控制非正常高峰流量而必须通过在链路出口部署流控设备进行流量控制来达到实现网络优化的目的。
通过对某些厂商技术白皮书的理解我认为原因如下:
通过WEB端进行流控主要运用了两种办法
1.TCP滑动窗口技术
2.调整配置文件参数达到会话数和连接数的控制。
那么以上两种办法的好处是什么?
比如,有一台WEB服务器,用户向服务器发起请求打开一个页面,该页面包含了8,000字节信息,标准TCP窗口为16K,所以当服务器接收到请求后,16K的数据就会向用户发送到。假设链路每毫秒可以传输100个字节,也就是说需要160毫秒用来传输这些页面,在传输的过程中,任何其他的流量都需要等这些页面传输完成后才可以处理,也就是说在此网络中整体会有160毫秒的延时。
基于TCP滑动窗口技术,将TCP窗口改为32,000。那么服务器发送8,000字节的数据给用户,只需要80毫秒就可以传输完成,比没有使用TCP窗口控制时节省了80毫秒,以此减少网络的延时。
但是实际的需求往往没有这么简单,首先控制TCP窗口并不代表控制每个用户,因为每个用户都可以建立多个实时并发连接,比如一个用户可以在浏览器中打开多个页面,对每一个页面产生的连接进行TCP窗口控制,仅仅能保证此用户建立的每个连接受到控制而不是带宽受到控制,而流控真正需要做的是让每个用户使用的带宽不能占用过多并且不能占用
其他人的带宽。
再者,使用TCP窗口控制,对于每个TCP的连接都需要分步进行调整,也就是说,每一个数据流都要进行监控,每个ACK包都需要延时,每个IP头都需要重建,另外控制TCP的窗口将导致网络中出现大量的小包(1500字节),因为1500字节数据包是保证网络没有延时的最小数据包.这就解释了在复杂生产环境下(ISP级)基于会话数/连接数和TCP滑动窗口技术无法有效抑制网络拥堵的原因。如果在出口链路上无法控制P2P的泛滥,那么当数据到达应用层很容易导致服务器瘫痪,数据库也一样,皮之不存毛将焉附!
关于系统性能上的优化我来大胆的举一个例子:
铁道部花了3亿的RMB用来帮助IT同行们学习先致敬一下,然后在拿12306开刀。
查了一下资料,12306的网站使用的是J2EE架构,具体WEB服务就不清楚了,数据库应该是ORACLE。下面我来分析一下,如果有优化我觉得从下面几个问题考虑:
1,系统架构设计问题,说一个常见的架构方式,HTTP服务器做业务请求,WEB调用中间件,操作系统用AIX,数据库用ORACLE,应用服务器通过集群组承载庞大的业务请求。假设用户发出的请求是先找车次(查询操作),再看余票的信息,然后购买,那么可以可以通过根据IP进行负载均衡处理这些事务,并把业务请求分发到各个节点上,可以通过CDN加速分发到各个节点,实现动态请求,让真正的事务在节点上完成。这样,在处理请求的时候就减轻主服务器的压力,实现均衡的目的。
2,大并发的处理问题,系统设计之初就应该设计成容纳最大的并发数,尽可能的防止用户的访问产生堵塞,当然多少并发都未必真能阻止堵塞,那么在设置上就可以采用队列机制,
但是,水涨船高面临这个问题首先应该估算今年通过网络形式购票的人数,这个计算方法
我觉得应该是比较成熟的,通过估算出的数据可以算出高峰访问量和并发量的预计值。另外,根据整个订票流程,可以分析出系统本身哪一个事务操作可能造成大并发操作,比如说,查询完不提交(实际上,没有谁会着急付钱啊)很容易造成数据锁定,最后大家都卡在那。
3,由于12306比较特殊(官方话)那么针对这个系统就需要一个庞大的数据库,首先调用的数据过程能通过缓存就走缓存,通过内存的交互提高订票的速度。这有个非常实际的例子
比如我买票,我可能会长时间的查询,对于系统来说这张被查阅的票就被锁定,导致其他用户无法购买,也就是我没有付钱,没有提交,对于用户来说是好的,但是谁也不能保证付款时间,如果大量用户同时做这种事务,那么就产生了大量的访问,在数据库看来付款成功率下降,用户访问量大量增加。那么针对这种情况订票流程就需要设计相应的应对机制。
所以综上所述,实际生产环境的系统性能优化我个人觉得用一句话概括
“横看成岭侧成峰,远近高低各不同”
但是,从架构,业务逻辑,客户产生的数据等等方面却都有着相似之处,归根结底就是三个字:经验活!