产品运维中的性能优化

2024-04-04 08:18
文章标签 优化 性能 产品 运维中

本文主要是介绍产品运维中的性能优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、问题的提出

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

 

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分离, 表分区, 树型报表分页, 数据同步等等多个方面进行系统的部署调整


这篇关于产品运维中的性能优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/875267

相关文章

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

MySQL中慢SQL优化方法的完整指南

《MySQL中慢SQL优化方法的完整指南》当数据库响应时间超过500ms时,系统将面临三大灾难链式反应,所以本文将为大家介绍一下MySQL中慢SQL优化的常用方法,有需要的小伙伴可以了解下... 目录一、慢SQL的致命影响二、精准定位问题SQL1. 启用慢查询日志2. 诊断黄金三件套三、六大核心优化方案方案