随着公司交易量增长,利用侧 TPS 降落,接口耗时变长,业务高峰期甚至会有申请超时的状况。然而应用服务器 CPU 不到 50%,内存占用 40%(4C8G 配置),load average: 0.43, 0.45, 0.49;负载很低。
数据库为 ORACLE 11G,CPU:128C,内存:512G,存储:14T。业务高峰期 CPU 用掉 60%,IO 闲暇 45%。
次要接口均匀耗时统计,每分钟一个点,从下图能够看出在业务量不大的时候,均匀耗时在 25 毫秒左右。一旦到了业务高峰期,均匀耗时最大值忽然涨到 120 毫秒。
数据库监控图:顶峰时段 CPU 和 IO 使用率十分高。
状况产生后,立刻成立了攻关小组,毕竟邻近五一假期只有一周的工夫了,五一假期期间交易量至多还会增长 30%。
第一阶段剖析后,制订如下几点革新计划:
1、批改利用 Druid 连接池初始化连接数,从 Druid 监控看顶峰时段最大连接数峰值为 27,有可能是霎时交易量激增导致连接数不够用,以往教训通知咱们新创建数据库连贯耗时会比拟长,会导致霎时的申请排队期待获取连贯。所以决定把初始值 20 改为 30。
2、因账务库 (Oracle) 采纳两主一从高可用部署(A,B 为主节点,C 为从节点),目前所有利用系统配置的主节点都是 A,从节点都是 B。决定把一部分利用主节点调成 B,以升高 A 节点压力。
3、账务幂等表革新,现幂等表已实现分表 4 张(单表 4 亿条数据),然而从整个记账申请耗时剖析,幂等表和账务流水表的查问和插入操作耗时比较严重。因而决定把幂等表扩大到 64 张(为什么是 64 张,是通过科学计算的,具体计算过程因窃密不能说哈)。
4、MQ 接管,因为邻近五一,各方压力较大,如果以上优化点不能胜利,最坏的打算是走 MQ 异步接管机制,然而本计划会对业务造成影响,不到万不得已不会应用。
革新计划确定后,开启加班模式,兄弟们披星戴月很快革新实现,上线投产。但上线后成果和预期相差甚远。
计划 1:投产后发现顶峰时段记账耗时依然比较严重,调整 druid 连接池岂但没有成果,反而减少了数据库连接数,节约了资源,回退。
计划 2:主次节点调换程序后,呈现数据库资源争抢重大,频繁 GC,Cpu 使用率反而升高,回退。
计划 3:幂等表分 64 张之后,新表的读写速度很快均匀 0.7 毫秒,老幂等表均匀 4.7 毫秒,然而因为老幂等表数据量较大,没有从新做 hash 洗数据,所以还要代码层还要兼容老幂等表的查问,对整体效率并没有进步。
第一阶段总结:除了计划 3 久远看有功效,其它两个计划都没有解决问题,反思后感觉咱们方向错了,还是没有隔靴搔痒。于是大家从新走上了求医路线。
第二阶段剖析后,又制订了如下两个计划:
1、就在此时 DBA 发现一个新的问题,业务高峰期,账务流水表和会计流水表存在索引决裂问题,初步狐疑是因为流水号采纳了递增模式(通过 sequence 生成,且为索引列),PS:产生索引决裂次要是因为较小的序号往比它大的值后面插入,而以后索引块空间曾经不够了,就须要把原索引块(Index Block)决裂成两个,以保障较小的值可能插到后面去。这样就带来一个问题,旧有块的局部数据须要放到新开拓的索引块下来。频繁的索引决裂必定不是一个坏事。所以决定把流水号生成形式改成雪化算法。
2、目前流水表依照日期采纳 5 天一个分区,保留 2 个月数据。探讨后决定改成 1 天一个分区且只保留近 10 天数据。为什么不做分表,因为流水表波及数据同步,很多业务线都用到这个表,短时间内无奈实现分表革新,而分区对利用零碎而言是通明的。
PS:对于索引决裂请参考这个帖子:http://blog.itpub.net/2673616…,咱们遇到的状况属于 9 - 1 决裂,不论是什么类型的索引决裂,对系统而言必定都不是什么坏事。
和第一阶段一样,又开始了加班模式。然而最初投产后成果和第一阶段一样,又白忙乎了。顶峰时段数据库压力依然很大,且顶峰时段记账均匀耗时仍然超过 100ms。此时此刻心态曾经炸裂,毕竟大家曾经加班一周了,身心早已疲乏。然而问题还要持续解决,不然五一黄金周就不必放假了。。。
第三阶段开始,所谓毕生二,二生三,三生万物,万物变幻,九九八十一后又再循环,归一。第一阶段优化时就提到从整个记账申请耗时剖析,幂等表和账务流水表的查问和插入操作耗时比较严重,此时幂等表曾经分表实现,那么如果把插流水操作改成异步插入呢?没错,首先流水异步插入不会对业务造成影响,其次改成异步后能够升高整个事务周期,事务耗时小了,能够更快的开释资源。最初就算没有成果,通过异步写入也能够达到一个削峰的目标。通过 MQ 积压,升高数据库写入速度,爱护数据库。
PS:因为流水表每天都是亿级流水写入,数据量还是比拟大的。
批改后咱们很快上线了,毕竟工夫贵重,果然九九归一,有成果了。
上图中灰色是咱们把流水改为异步插入后的耗时曲线,和之前比成果非常明显。即便顶峰时段,耗时也只有 30 几毫秒。
再看一下数据库监控图,和之前比,压力曾经降落的非常明显了,此时终于松了一口气。
image.png
第四阶段优化:然而作为一个技术人,此时不应该失去满足,回头想想索引决裂的事件,的确是迷信的,不应该改了没有作用。从新梳理后发现开发小伙伴应用的雪化算法是变异后的算法,说白了就是只能保障全局散列(分布式而言),然而部分依然是间断的(单机而言)。如果间接改用 uuid 呢,抱着试一试的想法,又进行了一轮革新。果然这一想法失去验证。
投产后数据库压力又降了不少。上面三张图展现了优化前,利用优化,索引决裂优化的成果。