我有一个(几乎)专用系统,我正在使用它来处理一些数据库。我的问题是: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应用程序正在进行更多的查询(SELECT
,UPDATE
和INSERT
)。我正在使用准备好的陈述。
这些是我对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%的使用率?
答案 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