一段insert/update代码在单测中只需要几毫秒就能搞定,但用ab并发测试时,随着请求数和并发数的增加,所花费的时间越来越长(10ms -->5s+)。 数据库使用mysql,innoDB引擎,表结构也是很简单的几个字段,无外键,无死锁现象,数据池也开的足够大足够用(spring在DataSourceUtils.getConnection(dataSource)时基本不花费时间) 其次,把事务部分的代码都注释掉后进行ab测试也一样。 mysql也已经尽量优化,部分内容如下: key_buffer_size = 256M  
max_allowed_packet = 10M  
table_open_cache = 512  
sort_buffer_size = 16M  
read_buffer_size = 128M  
read_rnd_buffer_size = 4M  
myisam_sort_buffer_size = 64M  
thread_cache_size = 80  
#query_cache_size= 128M  
query_cache_size= 256M  
# Try number of CPU's*2 for thread_concurrency  
#thread_concurrency = 8  
thread_concurrency = 16  
tmp_table_size = 1024M  
  
innodb_autoextend_increment = 1000  
innodb_data_file_path = ibdata1:4000M;ibdata2:4000M:autoextend  
innodb_log_group_home_dir = /usr/local/mysql/log/  
# You can set .._buffer_pool_size up to 50 - 80 %  
# of RAM but beware of setting memory usage too high  
innodb_buffer_pool_size = 512M  
innodb_additional_mem_pool_size = 20M  
# Set .._log_file_size to 25 % of buffer pool size  
innodb_log_file_size = 256M  
innodb_log_buffer_size = 8M  
#innodb_flush_log_at_trx_commit = 1  
innodb_flush_log_at_trx_commit = 2  
#innodb_lock_wait_timeout = 50  
sync-binlog=1  
bulk_insert_buffer_size=12M  
innodb_flush_method=O_DIRECT  
innodb_thread_concurrency=1000  
ps.原先做查询时也很慢,但在SELECT中使用了SQL_NO_CACHE和SQL_CACHE后就不再慢了(slow.log中就没出现过了)。 但在insert和update时不知如何优化,向大家求教了! 

解决方案 »

  1.   

    并发测试,遇到瓶颈,可以考虑下分库吧。这样每个库的压力就没这么大了。
    比如说根据user_id分库,user_id从0-1000,可以分10个库0-100,101-200等等之类的。
    楼主要做的重新写个连接池吧,如果这样分库的话,不仅效率会好一些,同时更方便以后的拓展。
    当然我刚才说的分库规则只是最简单的,还可以根据hash,一致性哈希,虚拟节点一致性哈希,好多的。
    希望对楼主有帮助。
      

  2.   

    或者暂时先考虑下mysql的master/slaver模式,把读和写分开,这样就减轻了数据库的压力了。
      

  3.   

    现在就是分库的,只是没有读写分离,就是ab加大请求数和并发数时,mysql在执行insert/update时速度明显下降。
    在进行ab -n 1 -c 1的情况下inset/update都几毫秒~几十毫秒就能处理完,但当请求和并发开大之后变的越来越慢,慢查询记录如下:
    //这条没有锁表,但速度已明显增加到了149毫秒
    # Query_time: 0.149032  Lock_time: 0.000120 Rows_sent: 0  Rows_examined: 0
    SET timestamp=1345517343;
    INSERT INTO file_jobs SET pubdate=NOW(),renew='N',isimg='N';//这条貌似是因为innoDB进行了行锁,速度花了1.15妙
    # Query_time: 1.157453  Lock_time: 0.862603 Rows_sent: 0  Rows_examined: 1
    SET timestamp=1345517350;
    UPDATE `ps_47` SET `usage`=`usage`+(1028454) , fcount=fcount+1 WHERE pid=775542831 AND `index`=UNHEX('a80195fe9472a97a') AND path='/' LIMIT 1;若ab的请求和并发开的更大的花,慢查询的数据就更慢了。
    现在就想问问大伙,有没有什么思路解决,已经折腾了3,4天了
      

  4.   

    谢谢答复。现在有4个数据源,每个数据源都默认开了5个链接,都有spring统一管理,逻辑中只负责从spring中拿取,用完后直接释放。就上面的测试中,通过show processlist显示,单个数据源的链接最多也只有10个左右,所以应该不是连接数过大的原因。
      

  5.   

    一般mysql遇到性能瓶颈,如果在调优以后仍旧有,那只有两种方式,一种是做集群(经济点垂直集群,奢侈点水平集群),另一种修改mysql代码(反正开源的),更改内存吞吐量与并发处理方式,以及查询语句解析,调整磁盘io访问,增加更多缓存功能。两种方式成本都巨大,但是集群相对而言好点。