OLTP场景服务器配置建议

当服务器出现瓶颈时,对服务器的配置参数调整往往不是优先级最高的。一般来讲优化的效果是:SQL及索引>数据库表结构>系统配置>硬件,而优化的成本却恰好反过来,此外,对于大部分参数配置,mysql默认设置已经够用,也许调整后会有一些小提升,但可能也为其他方面的问题埋下隐患,因而服务器参数配置的一个原则应该是如果非必要,尽量不要随便调整参数。

对于OLTP场景,一般是高并发,事务提交要求小而快,属于cpu密集型,同时读写频繁,对于资源的竞争需要处理好,对性能要求较高。

对于OLAP场景,需要对大量数据进行查询搜集分析,对提交速度要求不如OLTP,应该尽量追求处理速度(就是说不要求你马上提交,因而可以尽量使用临时表等有帮助的手段提升数据处理过程的速度),由于需要处理大量数据,因而对硬盘io要求较高,属于io密集型。

OLTP场景配置

*硬件配置:

*CPU配置:对于OLTP场景多核处理器很有优势,现在的mysql一般可以在16~24核心cpu上运行较好,所以建议尽量使用更多核的处理器。

*内存配置:一般来讲要保证io等待的时间维持在可接受范围内选择内存大小。比如说在80%cpu利用率下,用于io等待的时间为1%,那么侧面说明缓存命中率还不错,内存应该够用,如果io等待占比较大的话,就应该考虑是否增大内存了(不过首先应该考虑的是mysql配置,查询,索引或者其他方面是否有异常,最后才考虑增加内存的问题)。

*硬盘配置:一般来讲使用多块硬盘组成的raid磁盘阵列,如果经费允许尽量使用ssd。对于oltp来说一般要保证安全性的话,并且对并发性速度有一定要求,则选择raid5,数据量大的话可以选择raid50,这种选择在磁盘损坏重建的时候会导致性能下降,如果钞票实在够多那也可以选择raid10.。

此外,对于数据库来说,硬盘具有断电保护(带有电池)的缓存功能很有必要,既可以提高读写速度,也可以一定程度保证断电时的数据安全。

*基本配置:

*innodb:当innodb不能启动时是否启动服务器,对于OLTP来说innodb引擎是必须的,因而为了保证服务器安全性这个选项很有必要。

*default_storage_engine:默认存储引擎,设置为innodb。对于要求支持事务、高并发读写来说是最好的选择。

*max_connections:在高并发场景时挺有用,当服务器负载较大时新增连接没有任何作用 ,因为没有足够资源分配给这些连接,这样的话不如从一开始就限制能够达到的连接数量上限,以免高并发带来的太多连接拖垮服务器。一般来说设置为比平时正常负载多出百分之30左右。

*skip_name_resolve:禁用了DNS查找环节,如果查找失败可能导致连接超时,最好禁用掉,将授权改为IP地址,通配符。

*thread_cache_size:当连接释放而cache size有足够空间时,放进该cache中。当有新连接时从该cache中取出存放的thread。可以节约thread创建和释放的资源,一般来讲根据并发连接的波动设置,比如说500~700的连接波动那么cache size为200~250之间比较合适。

*innodb_stats_persistent:将统计信息持久化,可以避免启动时重新收集统计信息。同时可以通过关闭innodb_stats_on_metadata来避免统计信息自动更新导致的io问题,通过周期性执行analyze table来更新统计信息。

*innodb_file_per_table:一般来讲建议设置,因为共享表空间修改或者空间回收等都需要导出数据,修改配置,重启,重建新的数据文件然后导入数据这些步骤,非常麻烦,而ibd文件可以直接用rm删除。

*read_only&slave_net_timeout:禁止非特权用户在备库做变更,设置为只读模式;备库连接失败等待重连的时间,默认是1小时,改为1分钟或者更短。

*max_connect_errors:最大连接错误次数,超过了该连接会被禁用一段时间,一般来说服务器安全性较好的应该尽量设置大一些。

*transaction-isolation:对于OLTP设置为默认的可重复读。

*内存参数配置:

*innodb_buffer_pool_size:对于已innodb引擎为主的服务器来说是最重要的参数,对于OLTP的高并发来说更是如此,占了服务器内存大部分的分配,一般来讲是75~85%(不过辉哥告诉我他们生产环境一般用50%)。具体分配策略可以根据以下步骤分析:1.分配给操作系统和其他必须进程的内存,一般来说2~3G2.分配给mysql自身的内存,不多。3.分配给innodb日志缓存,binlog缓存,key cache,查询缓存等重要缓存。把剩下的内存乘以90%(保留一些余地总是好的)就是分配给buffer pool的缓存。

此外对于high concurrency来说,innodb_buffer_pool_instance也是一个重要参数,可以设置多个独立FREELIST,LRU,FLU以及mutex的buffer pool实例从而减少对缓冲的竞争。根据网上查询的资料一般是buffer pool size/2GB(官网上建议是8GB每实例),不过我觉得默认8实例已经足够用了。

*innodb_adaptive_hash_index:是否使用自适应hash索引。会对经常出现,对某一索引使用同一规范的查询创建hash索引,由于索引在内存(buffer pool)中,因而大大提高查询效率,一般来讲对于高并发应用有比较好的效果。

*innodb_log_buffer_size:事务日志的大小不必设置的太大,一般来说1~8M就够了(除非是大型事务或者有BLOB等),因为对于缓存刷新设置innodb_flush_log_at_trx_commit来说,最宽松的刷新机制也是一秒就刷新一次,8M就足够1s间使用了。刷新机制的选择需要在高性能和数据安全性之间做考量,如果严格的刷新机制(每次事务提交就刷新)导致当前负载压力较大可以考虑设置为0或者2。

*table_cache_size:包括table_definition_cachetable_open_cache。对于高并发应用来说应该设置的足够大,这样可以避免每次连接都需要重新打开表和解析表,一般来讲设置为max_connections10倍,也就是10000左右。不过对于innodb来说他又自己的文件描述符缓存,由innodb_open_files控制数量,如果设置了innodb_file_per_table,就应该把innodb_open_files设置的足够大已保持所有ibd文件打开。

*key_buffer_sizeMyISAM引擎表所使用的键缓存,对于以innodb为主的服务器来说设置一个较小的数比较合适,一般来说是把库中所有myisam索引文件大小加起来的值,但是也不能没有,因为mysql系统表基本都是MyISAM。

*tmp_table_size&max_heap_table_size:对于OLTP来说事务一般不大,保持created_tmp_disk_tables/created_tmp_tables维持在一个较小的百分比即可,比如3%以下,一般来说设置64M应该够用了。

query_cache_size:对于高并发且小而快的查询比较重要,可以在缓存中存储较多这种的查询,从而可以直接再此返回结果而不需要进行解析及以后的步骤。不过对于innodb来说,事务影响的表相关的查询都会从缓存中删除,所以对于读写频繁的OLTP系统最好还是关闭查询缓存。

*I/O参数配置:

*innodb_log_file_size:一般来讲最少要记录一个小时内的活动内容,可以根据每秒写入日志的速度来估计log的大小,对于高并发服务器来说至少需要2G或以上的大小。

*innodb_io_capacityinnodb刷新数据页有两种状态,一种是每10s循环时如果io压力不大则刷新脏页到硬盘,一种是当buffer pool不够用时刷新LRU中的脏页。这个值不应设的太高,不然会导致周期性io负载过大。可以根据测试服务器硬盘能够承受的io能力决定,一般来讲10000~20000左右。

*innodb_read_io_threads&innodb_write_io_threads:当负载较大且有较多硬盘时可以把这两个参数从默认的4提高,一般来讲提高至跟硬盘数量相同,可以提高硬盘io效率。

*innodb_flush_method:把数据从内存刷新到硬盘的方式,一般来讲类UNIX系统设置为O_DIRECT,即刷新时不使用系统缓存,innodb自己已有缓存,使用系统缓存没什么意义还降低速度,并且若数据处于系统缓存时崩溃这对于innodb来说是未知的,这样会导致很糟糕的结果。

*binlog_sync:对于OLTP应该尽量设置为1,尽管这样会拖累io(不仅修改数据,还要修改文件大小等元数据),可以通过带电池保护的写缓存raid来补偿一下。当然如果io负载实在过大,可以考虑调高该参数。该参数一般与innodb_flush_log_at_trx_commit配合使用,这里涉及到日志写入顺序的问题,感兴趣的可以去查查。

猜你喜欢

转载自blog.csdn.net/qq_38125183/article/details/80647834