找到Java / mySQL应用程序的瓶颈

时间:2013-01-07 17:47:58

标签: java mysql performance

我有一个(几乎)专用系统,我正在使用它来处理一些数据库。我的问题是:Java应用程序运行速度很慢(完成任务需要2-3天),我不知道为什么。

该系统是Xubuntu 12.04.1 LTS,3.2.0-32-generic x86_64,mySQL 5.5.28,Phenom X2 550,16 GB RAM和Intel SSD 520(利用SandForce处理器,具有高IOPS)。

首先,CPU负载从未真正达到100%。 htop输出在大多数情况下都是这样的:

  1  : 63.9% sys: 12.9% low:  0.0%        Tasks: 99, 164 thr; 2 running
  2  : 18.5% sys: 21.2% low:  0.7%        Load average: 1.14 1.23 1.22
  Mem[|||||||||||||||||13490/16049MB]     Uptime: 1 day, 06:32:13
  Swp:8188M used:195M                     Time: 18:33:04

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
16168 micha      20   0 5163M 1595M  4500 S 75.0  9.9 11h36:10 java -jar ./build
16169 micha      20   0 5163M 1595M  4500 R 75.0  9.9 11h31:34 java -jar ./build
 5968 mysql      20   0 11.9G 10.7G  3992 S 31.0 68.4 13h21:10 /usr/sbin/mysqld
 6142 mysql      20   0 11.9G 10.7G  3992 S 31.0 68.4 10h44:50 /usr/sbin/mysqld

有时候mysqld的CPU使用率也比java高,但在两个核心上它都不会接近100%。

我正在处理的数据库相当大,总共有24 GB的InnoDB表。每个表都有一个PRIMARY键,我还使用EXPLAIN来使我的索引正确。 java工具做的很简单,但很多。涉及的表有大约10-20M行,而java应用程序正在进行更多的查询(SELECTUPDATEINSERT)。我正在使用准备好的陈述。

这些是我对InnoDB的设置:

mysql> show variables like 'innodb%'
    -> ;
+---------------------------------+------------------------+
| Variable_name                   | Value                  |
+---------------------------------+------------------------+
| innodb_adaptive_flushing        | ON                     |
| innodb_adaptive_hash_index      | ON                     |
| innodb_additional_mem_pool_size | 8388608                |
| innodb_autoextend_increment     | 8                      |
| innodb_autoinc_lock_mode        | 1                      |
| innodb_buffer_pool_instances    | 1                      |
| innodb_buffer_pool_size         | 10737418240            |
| innodb_change_buffering         | all                    |
| innodb_checksums                | ON                     |
| innodb_commit_concurrency       | 0                      |
| innodb_concurrency_tickets      | 500                    |
| innodb_data_file_path           | ibdata1:10M:autoextend |
| innodb_data_home_dir            |                        |
| innodb_doublewrite              | ON                     |
| innodb_fast_shutdown            | 1                      |
| innodb_file_format              | Antelope               |
| innodb_file_format_check        | ON                     |
| innodb_file_format_max          | Antelope               |
| innodb_file_per_table           | OFF                    |
| innodb_flush_log_at_trx_commit  | 0                      |
| innodb_flush_method             |                        |
| innodb_force_load_corrupted     | OFF                    |
| innodb_force_recovery           | 0                      |
| innodb_io_capacity              | 200                    |
| innodb_large_prefix             | OFF                    |
| innodb_lock_wait_timeout        | 50                     |
| innodb_locks_unsafe_for_binlog  | OFF                    |
| innodb_log_buffer_size          | 8388608                |
| innodb_log_file_size            | 5242880                |
| innodb_log_files_in_group       | 2                      |
| innodb_log_group_home_dir       | ./                     |
| innodb_max_dirty_pages_pct      | 75                     |
| innodb_max_purge_lag            | 0                      |
| innodb_mirrored_log_groups      | 1                      |
| innodb_old_blocks_pct           | 37                     |
| innodb_old_blocks_time          | 0                      |
| innodb_open_files               | 300                    |
| innodb_purge_batch_size         | 20                     |
| innodb_purge_threads            | 0                      |
| innodb_random_read_ahead        | OFF                    |
| innodb_read_ahead_threshold     | 56                     |
| innodb_read_io_threads          | 4                      |
| innodb_replication_delay        | 0                      |
| innodb_rollback_on_timeout      | OFF                    |
| innodb_rollback_segments        | 128                    |
| innodb_spin_wait_delay          | 6                      |
| innodb_stats_method             | nulls_equal            |
| innodb_stats_on_metadata        | ON                     |
| innodb_stats_sample_pages       | 8                      |
| innodb_strict_mode              | OFF                    |
| innodb_support_xa               | ON                     |
| innodb_sync_spin_loops          | 30                     |
| innodb_table_locks              | ON                     |
| innodb_thread_concurrency       | 0                      |
| innodb_thread_sleep_delay       | 10000                  |
| innodb_use_native_aio           | OFF                    |
| innodb_use_sys_malloc           | ON                     |
| innodb_version                  | 1.1.8                  |
| innodb_write_io_threads         | 4                      |
+---------------------------------+------------------------+
59 rows in set (0.01 sec)

最后,在查看iotop时,磁盘的使用率大约为1%,因此我认为mySQL实际上只能在系统内存中使用,并且不会使磁盘崩溃。我认为这会将RAM和SSD排除在瓶颈之外,只会离开CPU。

但在投资新CPU之前,我想请求其他/更多意见。 CPU真的是我的瓶颈吗?如果是,为什么它远低于100%的使用率?

2 个答案:

答案 0 :(得分:2)

不知道Java代码(这个答案会得到更新)我推测你的插入/更新有这样的语法:

   openConnection();    
   startTransaction  
   {  
       insertOneRow();  
        commit();  
   }  
   endTransaction();  
   closeConnection();  

此外,我还想象您没有将语句一起批处理,因此您只需调用数据库X/N次,其中X是批量的大小。

我能够在3秒内将2 million条记录保存到 Oracle (我知道你的是MySql)数据库中,因此它不是CPU问题。

答案 1 :(得分:1)

也许您可以通过使用分析器来识别瓶颈?

我使用的是与NetBeans捆绑在一起的,并发现它们非常有用。

在这里你可以找到更多: http://netbeans.org/kb/docs/java/profiler-intro.html