解决问题:(主要是InnoDB引擎)html
优化原则:mysql
优化思路:sql
1. 优化MySQL服务器的最大链接数。数据库
具体操做:参考博客 Mysql查看状态,链接数,线程数以及Mysql性能监控工具doDBA的使用以及优化缓存
2. 优化须知(主要是InnoDB)安全
2.1 优化原理服务器
2.1.1 InnoDB缓冲池(Buffer Pool)数据结构
若是大部分都是InnoDB表,InnoDB缓冲池或许比其余任何东西更须要内存。InnoDB缓冲池并不只仅缓冲索引:它还会缓存行数据、自适应hash、插入缓存、锁,以及其余内部数据结构。InnoDB还使用缓冲池来帮助延迟写入,这样就能合并多个写入操做,而后一块儿顺序地写回。总之,InnoDB严重依赖缓冲区,你必须确认它分配了足够的内存,竟可能的大。并发
2.1.2 优化MySQL的I/O行为(如下内容来自《高性能MySQL》8.5小节)(若是不关心原理,可跳过2.1)socket
对于常见的应用,最重要的一部份内容是InnoDB日志文件大小、InnoDB怎样刷新它的日志缓冲,以及InnoDB怎样执行I/O。
InnoDB事务日志。
InnoDB使用日志来减小提交事务时的开销。由于日志中已经记录了事务,就无须在每一个事务提交时把缓冲池的脏块刷新到磁盘中。事务修改的数据和索引一般会映射到表空间的随机位置,因此刷新这些变动到磁盘须要不少随机I/O。InnoDB假设使用的是常规磁盘(机械磁盘),随机I/O比顺序I/O要昂贵得多,由于一个I/O请求须要时间把磁头移动正确的位置,而后等待磁盘上读出须要的部分,再转到开始位置。
InnoDB用日志把随机I/O变成顺序I/O。一旦日志安全写到磁盘,事务就持久化了,即便变动尚未写到数据文件。若是一些糟糕的事情发生了(断电),InnoDB能够重放日志并恢复已经提交的事务。
固然,InnoDB最后仍是必须把变动写到数据文件,由于日志有固定的大小。InnoDB日志是环形方式写的:当写到日志的尾部,会从新跳转到开头继续写,但不会覆盖还没应用到数据文件的日志记录,由于这样作会清掉已提交的惟一持久化记录。
InnoDB使用一个后台线程智能地刷新这些变动到数据文件。这个线程能够批量组合写入,使得数据写入更顺序,以提升效率。实际上,事务日志把数据文件的随机I/O转换为几乎顺序的日志文件和数据文件I/O。把刷新操做转移到后台使查询能够更快完成,而且缓和查询高峰时I/O系统的压力。
总体的日志文件大小受控于innodb_log_file_size和innodb_log_files_in_group两个参数,这对写性能很是重要。日志文件的总大小是每一个文件的大小之和。默认状况下,只有两个5MB的文件,总共10MB。对高性能工做来讲这过小了。至少须要几百MB或者上GB的日志文件。
InnoDB使用多个文件做为一组循环日志。一般不须要修改默认日志数量,只修改每一个日志文件的大小便可。要修改日志文件,须要彻底关闭MySQL,将旧的日志文件移到其余地方保存,从新配置参数,而后重启。必定要确保MySQL干净地关闭了,或者还有日志文件能够保证须要应用到数据文件的事务记录,否者数据库就没法恢复了!
一般不须要把日志缓冲区设置得很是大,推荐范围是1MB-8MB,通常来讲就足够了,除非要写不少至关大的BLOB记录。较大的日志缓冲区在某些状况下也是有好处的:能够减小缓冲区中空间分配的争用。当配置一台有大点内存的服务器时,有时简单地分配32MB-128MB的日志缓冲。
日志缓冲必须被刷新到持久化存储,以确保提交的事务彻底被持久化了。若是和持久化相比更在意性能,能够修改innodb_flush_log_at_trx_commit变量来控制日志缓冲区刷新的频繁程度。可能的设置以下:
0 :把日志缓冲写到日志文件,而且每秒钟刷新一次,可是事务提交时不作任何事。
1 :将日志缓冲写到日志文件,而且每次事务提交都刷新到持久化存储。这是默认的(而且是最安全的)设置,改设置能保证不会丢失任何已经提交的事务,除非磁盘或者操做系统是“伪”刷新的。
2 :每次提交时把日志缓冲写到日志文件,可是并不刷新。InnoDB每秒作一次刷新。0与2最要的不一样是(也是为何2更合适),若是MySQL挂了,2不会丢失任何事务。若是整个服务器“挂了”或者断电了,则仍是可能会丢失一些事务。
了解清楚“把日志缓冲写到日志文件”和“把日志刷新到持久化存储”之间的不一样是很重要的。在大部分操做系统中,把缓冲写到日志只是简单地把数据从InnoDB的内存缓冲转移到操做系统的内存,并无真的把数据写到持久化存储。
高性能事务处理须要的最佳配置是把innodb_flush_log_trx_commit设置为1且把日志文件放到一个有电池保护的写缓存的RAID卷中。
2.2 优化结果
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Recommended in standard MySQL setup sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # 如下配置是优化后的结果 # MySQL服务器最大链接数 max_connections=1000 # MySQL服务器线程缓存大小 thread_cache_size=500 # 日志缓冲刷新的频繁程度 innodb_flush_log_at_trx_commit=2 # InnoDB缓冲池 innodb_buffer_pool_size=10000M # 每一个日志文件的大小 innodb_log_file_size=512M # 日志缓冲的大小 innodb_log_buffer_size=32M
(若是按照以上配置,Jmeter1000并发,数据链接池1000活跃链接,MySQL的写数据操做能到5000-7000TPS)
(测试结果)若是一样条件把innodb_flush_log_at_trx_commit改为1,TPS会降低3000左右。