在结算改造项目和Mysql迁移项目中,结算遇到了一些性能问题。 在性能优化的过程中,根据不同的场景采用了不同的方法来解决遇到的问题。我把处理的过程和采用的方法发出来,大家来看下是否这些方法得当。
全量检查客户上下线时,要检查数据库表q_customers里120W左右的数据和ad_campaigns里面110W左右的数据。
考虑了以下两种方法:
1. 所有的数据,要读到内存中进行上下线的计算。 --- 所有的数据load到内存中,内存肯定溢出。
2. 将custid取出来,分批取数据。-- 首先是所有的custid,大约有120w的数据,在整个全量运行期间占据内存。第二,oracle有in不超过1000个的限制,取所有的数据,需要对数据库进行1200次操作,数据库交互次数太多,操作时间太长。
所以,要解决全量的问题:要避免一次把所有数据load到内存中,尽量避免使用in来取数据,减少与数据库交互次数
采用的方案是
1. 分批取数据,每次取40W。
2. 此20W数据,只记录起始和结束的custid,减少custid占用内存。
见如下sql:
SELECT Min(custId) minId,Max(custId) maxId FROM
( SELECT custid FROM (SELECT custid FroM q_customers WHERE custid > #startCustId# ORDER BY custid )
WHERE ROWNUM <= #batchSize# )
结果:
现在压出来的结果,在多个表关联,取十个左右的属性的情况下,40W记录取数据时间大约在 30秒左右。
在日终结算时,原来的处理方式会将所有的点击记录(目前约120W左右)全部读到内存中进行校验、打折、计算扣费等。(日终文件会根据custid进行排序)
这种方式在性能测试时,对于150w左右的数据进行计算时,勉强可以通过,但是当点击记录到达300W时,就会报内存溢出。
问题就出在,把所有记录加载进行计算时,随着数据量的增加,2G的内存总会有成为瓶颈的时候,比如300w。
对这个问题的处理采取的思路时:
对于校验、打折这块逻辑的处理:将点击记录读到内存中,当读的行数到达一个设定的值时(如10W),则将这些点击记录放入临时文件中,依次循环进行,直到所有记录都被处理完成。
对于计算扣费:因为与某个custid的所有记录有关,而每个客户有多少点击并不固定,这个地方的处理是将一个客户的所有点击记录都累加计算完,将客户的扣费情况写入临时文件。(此处的处理方式是因为我们系统中不会有某个客户的每天的点击超过10W条,不会占用过多内存。如果某天我们有超级客户,每天的点击超过10w的情况出现,可能整个结算都要重新考虑架构方式来解决性能问题了)
Mysql迁移项目中,结算要读取的q_customers,ad_campaigns,ad_budgets等数据已经迁移到mysql中,而其他的如accounts表中的数据在oracle中。结算需要从双库中读取数据。从mysql中去读40W数据不能使用 between and 这种custid区间的方式,那么在第一条中所使用的方法在读mysql的数据时,就要考虑改变,只能使用in的方式去mysql中去读了。压测的结果表明,在mysql中使用in循环去读数据时,性能很慢。读40W条记录,大约需要20分钟,这在结算上下线中是不可接受的。
So,采用以下的方式。
//1.将某个custid区间的40Wcustid先取出来
//2.对custid根据cobar分区规则进行分区,得到128个数组
//3.将128个数组,分成16组。每组里面分别有8个分区的数据
//4.使用8个线程,分别对16组数据 从mysql中获取(mysql没有in个数的限制)
多线程的代码如下:
private class GetDataThreadMysql<E> extends Thread {
private Vector<E> v1;
private List<List<Long>> custListTeam;
private List<Long> campaignIdList;
private String sql;
private boolean flag = false;
public boolean isFlag() {
return flag;
}
public GetDataThreadMysql(Vector<E> v1, List<List<Long>> custListTeam, List<Long> campaignIdList, String sql){
this.v1 = v1;
this.custListTeam = custListTeam;
this.sql = sql;
this.campaignIdList = campaignIdList;
}
@SuppressWarnings("unchecked")
@Override
public void run() {
if (Checks.isEmpty(campaignIdList)) {
for (List<Long> custIdList : custListTeam) {
v1.addAll(executeQueryForList(sql, custIdList));
}
} else {
Map<String, List<Long>> pMap = new HashMap<String, List<Long>>();
pMap.put("campaignIdList", campaignIdList);
for (List<Long> custIdList : custListTeam) {
pMap.put("custIdList", custIdList);
v1.addAll(executeQueryForList(sql, pMap));
}
}
flag = true;
}
}
解决方式如三,使用多线程解决。
在不使用多线程时,cobar1w 条提交时间为1分钟左右。
现在每1W条数据提交时间,oracle为100ms左右,mysql使用8个线程为1000ms。
在多次处理过程中,会经常遇到 full gc比较多的情况。
使用jstat –gcutil <pid> 可以查看这个pid fgc的次数。
Fgc次数多有什么危害,大家可以自己google一下。
在fgc比较多时,可以使用 jmap –histo <pid> 来查看哪些对象占用内存比较多,然后有针对性的进行优化。
分享到:
相关推荐
调优过程中,要关注镜头质量、像素阵列、信噪比(SNR)以及锐化算法的选择。锐化可以增强边缘细节,但过度的锐化可能会引入假象。海思ISP提供了多种内建的锐化模式,调优时需根据应用场景选择合适参数,确保在不失真的...
作者通过一个故事,讲述了如何在实际项目中遇到性能问题,并通过自己的经验总结出了性能调优的重要性。 性能调优的挑战 性能调优是一项非常复杂的技术,需要开发者具备广度和深度的技术知识。互联网时代,一个简单...
通过这份指南,开发者可以学到Java性能调优的实践经验和技术,包括计算机基础知识、源码分析、追问和总结等。开发者可以通过这些知识点来提高系统性能,解决性能问题,并且提高自己的技术广度和深度。 知识点: 1....
本文档总结了作者在实践中不断积累的JVM性能调优经验,涵盖了JVM基础知识、内存调优策略、常见性能问题及解决方案等多个方面。希望通过这份总结能够为广大读者提供有价值的参考和帮助,提升应用性能,优化用户体验。...
在实际操作中,调优过程通常需要配合监控工具,如Apache的mod_status模块,实时查看服务器状态,根据负载情况动态调整参数。同时,还要注意监控系统资源,如CPU、内存和网络带宽,以确保系统整体的健康运行。 总的...
【性能调优文档_自动化测试】的文档主要涵盖了在性能测试过程中针对各种中间件和系统的调优策略。这里,我们详细解析其中涉及的关键知识点。 **1. 中间件调优** 1.1 **Tomcat调优** 1.1.1 **JVM大小调整** - `...
#### JAVA应用性能测试调优经验总结 1. **GC调优参数的使用**:垃圾收集器的选择和配置对应用性能有重大影响。例如,使用-XX:+UseG1GC启用G1垃圾收集器,适用于大内存的应用场景;调整-XX:MaxGCPauseMillis以减少GC...
- **经验总结**: 根据实际情况调整配置。 - **优化返回查询结果返回大量数据的场景**: 采用Paging或Limit等方法减少数据量。 ##### 12.9.2 SQL和DataFrame调优 - Spark SQL和DataFrame的调优主要包括: - **...
通过阅读《阿里巴巴Java性能调优实战(2021华山版)》,读者不仅可以掌握Java性能调优的理论知识,还能学习到阿里巴巴在实际业务中总结的宝贵经验,这对于提升个人或团队的开发效率,保障系统稳定性和性能具有极大的...
随着Java技术的发展,JVM的性能调优显得尤为重要,因为这直接影响到程序的响应速度和资源利用率。通过理解JVM的运行时分析,我们可以更好地控制应用程序的运行状态。 2. **JAVA虚拟机运行机制概览** - **运行时...
总的来说,SQLServer性能调优是一门深奥且实用的技术,需要理论与实践经验相结合,才能有效地提升系统性能,确保业务的高效运行。本文仅做了概念性总结,更深入的实战技巧和工具使用将在后续的文章中进一步探讨。
在Websphere性能调优过程中,Top10监控信息提供了系统运行状态的重要参考。通过对CPU利用率、内存使用情况、线程状态、JVM垃圾回收等关键指标的监控,可以快速定位潜在的性能瓶颈,为后续的调优工作提供数据支持。 ...
2. 应用开发人员需选择高效的实现策略,并识别可能导致性能问题的SQL语句。 3. 数据库管理员则负责监控系统活动,提供性能数据,及时发现和解决问题。 4. 硬件/软件管理人员需要提供系统配置信息,协助优化硬件和...
总结,JVM调优是一项技术性极强的工作,需要深入理解JVM内存结构、垃圾回收机制,结合实际应用情况,通过调整相关参数实现最佳性能。实践中应结合理论知识与实践经验,不断测试、监控、分析,确保应用的高效稳定运行...
总结以上知识点,我们了解到在T-SQL性能调优过程中,对于SQL Server 2012版本的数据库管理员或开发者而言,熟练掌握窗口函数的使用是一个至关重要的技能。通过合理地应用窗口函数,可以有效地提升数据库操作的性能,...
总结,J2EE应用性能调优是一个综合性的工程,涉及到硬件、网络、操作系统、J2EE容器、后台服务、前端以及JVM等多个层面的优化。每个层面的优化都有其独特的方法和策略,需要结合实际情况灵活运用,以实现整体性能的...
【性能测试项目实施经验总结与系统调优方法1】 在性能测试中,为了确保测试的准确性和效率,往往需要对实际系统进行一定的调整。以下是从标题、描述和标签中提炼出的关键知识点: 1. **去除安全验证**: - 在进行...
为了实现有效的性能调优,必须具备全面的知识背景和实践经验。此外,还需要合理利用各种性能监控工具,科学地分析数据,准确地定位问题,并采取有效的解决措施。通过这一系列的过程,可以显著提升系统的性能表现,...
4. **数据库性能调优技术系列**: 这可能涵盖了一系列的技术,包括: - **SQL调优**:使用`EXPLAIN PLAN`分析查询执行路径,识别全表扫描、索引扫描等问题,优化JOIN操作,使用绑定变量避免硬解析。 - **索引优化...