产品运维中的性能优化

一、问题的提出

 随着系统业务数据量的不断增长, 使用用户的不断增加, 项目组越来越频繁收到用户特别是中研用户反馈的性能问题, 主要是以下几个方面的问题:

 

1. 系统使用高峰期比如周一和月初, 用户反馈系统登陆不了, 菜单响应和操作缓慢等问题;

2. 客户查询功能响应缓慢, 一个4000条数据的查询时间超过N分钟;

3. 客户增量保存功能操作失败,有些时候增量保存的线程跑了1个小时还没成功保存,结果是用户数据丢失(后台同步处理);

4. 客户操作后死机

5. 管理员反馈报表查询响应不了甚至报系统错误

 

经过对系统的监测和分析, 监测到的问题如下:

 

1. 数据库连接占满, 事务等待超时或死锁

2. 数据库服务器停止, 事务日志占满, 报磁盘空间不足的错误

3. 后台日志显示数据库语句堆, 排序堆不足

4. 后台日志显示缓冲池中无页面可用

5. 通过连续监测发现每周一上午9:30-10:30这个时间段数据库CPU使用率接近100%高居不下


二、解决思路

系统的核心业务数据是百万级别的数据, 以及千万级别的日志数据:

既是一个OLTP系统, 又是一个OLAP系统; 任务流程处理这块都是一些大事务和并发多的事务, 而任务分析这块是实时进行大数据量超复杂的统计运算; 这些地方就是系统的性能瓶颈;

鉴于此, 我们从SQL语句, 应用程序逻辑, 数据库, 数据归档, 部署方式等多个层面进行系统的性能优化, 优化的重点是减少事务并发, 保证稀有资源的合理利用;


2.1. SQL语句优化

a) 系统存在很多树结构数据, 比如项目树, WBS, 对这些数据进行查询的SQL进行优化, 分析发现很多递归SQL在递归层次深,数据量大的情况下, 性能问题突出, 我们采取的办法是:

 尽量使用视图;

 将查询条件从SQL语句的最外层移到内层子查询, 减少数据查询量;

 报表SQL允许脏读, 以防大面积的关键数据表行锁升级为表锁;

 b) 系统有很多一对多特别是多对多的表关联查询, 比如任务表和日志填报表; 分析发现很多地方就用一个超大的SQL查询任务和日志数据, 这样查询的结果冗余量大,我们采取的办法是:

拆分成多个SQL进行查询;

 c) 很多SQL中包含in函数, 而且in的子查询语句的结果集不确定, 可能上千上万, 这种SQL导致数据库后台报语句堆不足的错误, 我们采取的优化办法是:

     用关联查询替代in函数;

     用or语句替代in函数;

   d)整理出大数据量查询的SQL语句, 找出关联查询的条件, 根据索引原则, 增加数据库索引;

e) 有不少报表统计SQL语句直接处理的大数据量的复杂运算, 导致占用大量的数据库资源,我们采取的优化办法是:

   SQL语句用来查询数据, 而运算统计的部分交给应用服务器处理;

   采用静态报表, 晚上统计出数据, 白天就可以查询统计后的结果数据;

f) 分析发现有些SQL语句类似 ”select * … ” , 这些地方全部将*号替换成具体的列;

还有些SQL返回的结果集数量是可知的,这些地方使用FETCH FIRST n ROWS ONLY参数

 

2.2.应用程序逻辑优化

a) 一个最大的问题就是循环里面取数据库连接, 这种情况很普遍, 所有地方全部进行了改正;

   还有些功能点需要多次存取数据, 考虑使用一个数据库连接;

   取连接的语句在需要的时候执行, 而不是在方法一开始就执行;

b) 另一个问题是程序中, 有些数据库连接释放的部分代码在try子句里面, 有些在catch子句里面,现在全部改为在finally中执行连接释放的操作, 这也是一个普遍的问题;

c) 程序忽略了异常处理或者对异常处理不够正确, 特别是一些无法测试的异常, 一旦发生这里异常可能导致事务不一致, 重复任务数据的BUG就是这样产生的,我们采取的处理办法是: 

这些地方都进行了异常捕捉处理;

    发生异常的地方都进行了事务的回滚;

d) 另一个是事务一致性和并发性能的取舍问题, 在关键功能上进行了利弊权衡;

e) 有些大事务功能点, 比如客户端下达, 任务反馈日志填报等程序逻辑上,对数据表的更新顺序不一致,这些地方都调整成一致; 以防并发出现互相锁等待的问题;

f) 及时的释放大对象内存, 比如客户端项目列表,WBS列表等;

g) 有些大事务处理的程序导致DB后台日志满, 磁盘空间不足的情况, 我们除了及时的清理备份事务日志, 还对这些大事务程序进行优化, 拆分成多个小事务进行处理;

h) 递归查询的地方采取了数据校验, 防止递归的父和子的ID一致, 死循环查询, 导致最终数据库临时表空间占满, 内存溢出等问题;

 

2.3.数据库调优

a) 定制一个runstats计划, 将需要进行runstats的数据进行分类, 哪些是按月,哪些是按周统计

runstats实用程序用于更新系统目录表中的统计信息,以帮助查询优化过程

b) 对一些排序, 分组的字段或者关联查询的字段比如名称, 日期等, 根据索引原则, 建立了索引;

c) 定期进行数据库日志归档和清理;

d) 利用性能测试工具和监控工具, 进行了数据库的参数调优;

主要参数是缓冲池大小,locklist大小, 排序堆阀值和大小, 查询堆语句堆大小等;

LockTimeout的时间需要指定, 但不能太大;

使用snapshot监视缓冲池, 调整bufferpool参数, 保证缓冲池命中率到95%+;

使用snapshot跟踪排序活动, 并发测试大型排序的报表功能, 调整sortheap参数, 同时调整sheapthres参数;。

 

2.4.数据归档

以项目为单位, 以计划任务数据为依据, 统计出一定时间内没有活动的项目; 经过用户的确认, 将这些项目进行归档处理;

a) 第一步, 按照项目导出这些数据到本地, 包括项目, 计划任务, 日志, 项目成员等数据

b) 第二步, 删除生产环境上的这些项目数据;

c) 第三步, 这些项目数据转移到备份数据库, 用户可以从备份数据库上查询到历史数据

 

数据归档的时候总结出了一些问题

 

 a) 删除语句和导入语句有先后顺序的;

 b) 没有主键的表,导入的时候不能用insert_update操作;

确认数据删除没错的话,可直接用insert取代insert_update操作;

   

 c) 导出的数据量比较大的情况, 建议分段导出

 d) 执行export和import命令需要在装有DB2 Server的环境中执行,否则会报程序包未找到的错误;

 e) 考虑到删除数据量的问题,采用单个项目单个项目数据迁移的方式;

 f) 跑脚本的时候,需要停止其他所有应用,否则很容易引起事务等待;

g) 回滚数据库日志的时候比较消耗内存, 回滚前重启机器

 

2.5.部署方式

将数据库服务器拆分为执行数据库和报表数据库:

执行数据库主要进行OLTP操作,报表服务器用作各类报表的查询,执行OLAP操作

报表服务器的数据定期从执行数据库中同步;

 

  具体方案有2种:

  a)  使用同一个应用服务器

      在已有的AppServer上加上报表数据库的数据源,报表查询都调用报表数据源即可

 

  b) 使用2个应用服务器独立部署

  用户通过执行服务器登陆界面登陆,当查询报表时,自动跳转到报表服务器


报表切换方案

 

  a) 修改 执行AppServer应用程序的报表管理菜单的链接,

让其重定向到 报表AppServer应用上

  b)修改 报表AppServer应用程序,增加redirect.jsp文件。

    主要是在报表AppServer上自动重建session,包括:

    界面语言,是否统一登陆,用户信息,用户类型,菜单列表,当前菜单;

    重建完session后,自动定位到报表管理菜单

  c)配置 报表AppServer菜单

    禁用报表App除了报表管理相关菜单以外的所有菜单,已防止用户误操作;

    比如:用户切换到报表管理菜单后登陆客户端操作,会发生没有权限问题;

d) 报表AppServer一些不相关的业务线程考虑关闭。

     报表AppServer的组织切换跳转考虑不跳转

   

数据同步方案

 

a) DB2远程SQL复制

参考以上部署图,DB2的SQL复制主要有2个程序,一个是Capture程序,通过数据库日志从源数据库中获取变化,并把数据放到一个中间表中。

另一个是Apply程序,在设定的时间间隔将中间表的数据同步到目标数据库,从而到达DB2数据复制的目的。

(步骤略)

 

b) ETL工具同步

报表需要同步的表和Mapping方式如下, ETL工具配置步骤略;


总结:

  目前系统有10几个节点在用, 这些节点都是独立部署, 独立的应用服务器和数据库服务器,
后续用户希望能进行跨体系,跨部门的项目管理, 这就要求我们的系统需要进行多节点的合并处理, 业务数据也需要合并, 这种数据几何级的增长, 必然会对系统有更高的要求, 所以后续工作还需要考虑在集群, 磁盘阵列, OLTP&OLAP分离, 表分区, 树型报表分页, 数据同步等等多个方面进行系统的部署调整


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值