AWS AURORA  CPU 100% 的解决方案

  最近作了一个系统,是从各个地方按照不一样的接口同步订单,底层采用的是Spring JdbcTempalte,支持按预订时间分表存储和查询的功能,使用到了jdbc的BatchUpdate功能.生产环境采用的是AWS,使用的数据库方案是AWS的RDS(Rational DataBase Service),这是我第一次使用RDS.本地环境测试起来一切正常,可是发布到生产环境CPU就飙到100%,且一条直线横到底.html

 虽然RDS的服务不会挂,可是系统的性能受到严重的影响.第一次使用AWS的RDS数据库,我简答的认为Amazon Aurora与经常使用的mysql是同样的,后来查询RDS的文档,才发现有一些不一样.mysql

Amazon Aurora 是一个兼容 MySQL 的关系数据库引擎,结合了高端商用数据库的速度和可用性以及开源数据库的简单性和成本效益。Amazon Aurora 的性能最高可达到 MySQL 的五倍,而且能以十分之一的成本提供商用数据库的安全性、可用性和可靠性。sql

这是http://aws.amazon.com/cn/rds/aurora/上对Aurora的介绍,一直把全部的文档看完,可是仍是没有能解决个人问题,经过查询的ShowProcessList和程序的日志上来看,发现系统在执行一些Sql方面有严重的性能问题.数据库

好比根据订单号删除订单的同步任务.安全

delete from res_id_list_for_fetch  where ersp='XXX' And source='yyyy'并发

这条语句竟然会死锁,执行SQL时,若是指定了主键,那么速度是最快的,主键是惟一的,因此只需锁定这一行记录便可,可是上面的SQL里面,是有3kw的数据量的基础上执行的,并且没有索引,因此直接锁定了整个表,在40个线程并发执行的状况下,出现死锁就不足为奇了.因此解决方案也是很简单,对ersp和source创建索引.性能

同时,在执行BatchUpdate时,slowlog的日志也显示有性能问题,在stackoverflow 上看到有位仁兄也遇到过这样的问题测试

http://stackoverflow.com/questions/2993251/jdbc-batch-insert-performance fetch

根据上面的解决方案,在jdbc的url上加入参数url

?useServerPrepStmts=false&rewriteBatchedStatements=true"

默认的状况下,rewriteBatchedStatements是false,这个参数的设置的解释以下

I'd like to expand on Bertil's answer, as I've been experimenting with the connection URL parameters.

rewriteBatchedStatements=true is the important parameter. useServerPrepStmts is already false by default, and even changing it to true doesn't make much difference in terms of batch insert performance.

Now I think is the time to write how rewriteBatchedStatements=true improves the performance so dramatically. It does so by rewriting of prepared statements for INSERT into multi-value inserts when executeBatch() (Source). That means that instead of sending the following n INSERT statements to the mysql server each time executeBatch() is called :

INSERT INTO X VALUES (A1,B1,C1)
INSERT INTO X VALUES (A2,B2,C2)
...
INSERT INTO X VALUES (An,Bn,Cn)

It would send a single INSERT statement :

INSERT INTO X VALUES (A1,B1,C1),(A2,B2,C2),...,(An,Bn,Cn)

You can observe it by toggling on the mysql logging (by SET global general_log = 1) which would log into a file each statement sent to the mysql server.

按照以上的解决方案,该创建索引的创建索引,链接参数也修改了,部署到生产环境,后来观察,cup一直稳定在3%.问题获得解决.

总结 对于常常使用的查询字段,该创建索引的仍是要创建索性,血的教训. 

相关文章
相关标签/搜索