zoukankan      html  css  js  c++  java
  • 参数优化,iostat详解

    如何对一个生产系统进行性能的初步诊断,从OS层面进行IO、CPU、内存、网络IO进行初步诊断。
    1.负载在哪个地方
    2.瓶颈在哪个地方


    iostat 1 -x
    这里写图片描述

    • %user:cpu给用户的实际工作时间,图中是16%。
    • %system:系统层面高的话,一般都是I/O过高导致的。
    • %iowait:系统瓶颈。43%的时间在等待,被浪费了。一般>25%就有问题了。
    • %nice和%steal:一般都是0。nice是调整io后的
    • %idle:空闲的时间。一般>25%就认为很好了。
    • rrqm/s:每秒合并的读请求。此值大,说明系统里有严重的全表扫描。
    • wrqm/s:每秒合并的写请求。此值大,说明系统出现严重的批量
    • insert(因为有主键,所以insert的时候很可能由于主键的依次递增而批量insert。insert总是插入相邻的数据块)。
    • r/s:每秒读的次数。
    • w/s:每秒写的次数。 二者相加就是IOPS!
    • rsec/s:每秒读的扇区数。
    • wsec/s:每秒写的扇区数。二者相加就是吞吐量(每秒传输多少M)
    • avgrg-sz:每秒请求扇区的大小。
    • avgqu-sz:平均请求队列的长度。前边排队的请求个数(每次进来后要等待2.85个请求的时间)
    • await:每一个IO请求的处理的平均时间(微秒、毫秒)[即IO的响应时间]。await=avgqu-sz * svctm
    • svctm:平均每次实际的服务时间(毫秒)。
    • %util:繁忙度。在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。

    此值高的话,先看IO,如果IO为0或者很低,就找存储工程师,他的硬盘出问题了。如果IO也很高,可能就是操作造成的IO很忙。

    PS:avgrq-sz/avgqu-sz/2 –》每个请求扫描多少扇区(单位是KB,因为/2了)


    os层面的问题:

    • IO繁忙
    • 写繁忙:svctm
      • ①降低IO:日志写、page写
      • ②提升io性能(主要是写功能)(闪卡、raid卡)
    • 与写功能相关的状态值
      • status
      • write
      • log(redo log、binlog)
      • flush
      • fsync
      • 【监控项:flush、write、fsync(绕过系统缓存,直接fsyncs)、innodb_flush_log_at_trx_commit(0,1,2)】
    • 变量variables
      • 事务提交相关
      • binlog相关
    • redo log size、redo log buffer
    • 脏数据大小、比例
      • innodb_max_dirty_pages_pct=75

    优化的分类:

    • ①参数优化
    • ②索引优化
    • ③SQL优化
    • ④分库分表分区优化

    参数优化

    • 1.从OS层面查看系统目前的负载点和性能瓶颈。
      • 负载点主要在写上。
      • 性能的瓶颈点,也主要在写上。
    • 2.从数据库层面分析一下,负载点主要在数据库的哪些组件上。
      • show global status,查询 GLOBAL_STATUS表
    • 3.调整哪些参数可以提升对应的性能。
    • 4.调整参数,压力测试,看一下效果。

    =====步骤
    1.tpcc压力测试的同时iostat 1 -x。发现,读少,写多。系统的写压力很大。
    2.mysql层面监控一下,这些写压力都来自于哪些组件。(日志写,page写)
    这里写图片描述

    • data page、log、double write #有这些写
    • show global stataus like ”; 或者查询GLOBAL_STATUS表(所有的状态值都在这个表里,大部分是累计值。)

    3.调整参数,持续监控
    1)调整显然可以提升性能的参数。
    如果这个参数的特点是:开、关,调整就很简单。
    如果这个参数是一个数值,就需要逐步调整,持续监控。
    2)持续观察INNODB_LOG_WRITES


    参数优化的思路

    • 1.OS层面查看我们系统的性能瓶颈点和负载点

    这里写图片描述

    发现,读少,写多。系统的写压力很大。

    • 2.写负载过大,来调整一下写负载,让写负载降低下来

    (1)首先关闭double write,这个是基本常识,不需要性能监控。
    会发现,写负载明显降低。
    这里写图片描述

    TPS也从160明显提升到200~300:

    这里写图片描述

    (2)调整了文件系统的mount参数,这个也属于常规调整。
    这里写图片描述

    (3)持续观察fsync,记录变化前的基本值。

    pager grep -i "fsync";

    innodb_data_fsyncs 大约在220/10 秒
    innodb_os_log_fsyn 大约在110/10 秒

    调整参数:
    这里写图片描述

    系统启动以后,需要持续观察fsync的变化量,在观察fsync以前,发现系统的写性能明显降低:

    这里写图片描述

    TPS也明显降低:
    这里写图片描述

    结论:在这个版本的Linux和MySQL下,下面的参数不能再调整:

    show variables like ‘%method%’;
    这里写图片描述

    绘制性能趋势图:
    这里写图片描述

    从上图可见,波峰波谷还是比较明显的。

    调整参数 innodb_log_file_size
    重启数据库,将redo log 从50M调整成300M:

    这里写图片描述

    性能明显提升:
    这里写图片描述

    调整参数以前一定关注状态值,这俩可能会影响数据的完整性
    1,1性能最佳,调整之后,看一下变化趋势
    另外调整一下iocapacity、lru scan depth

    调完之后监控log write,fsync
    这里写图片描述

    • 3、提升写性能
      • Raid卡
      • 闪卡

    存储过程

    eg:把一些状态值每隔2s抽出来放到一张表中:

    create table test.pt( id int,variable_name varchar(20),c_variable_value int,o_variable_value int,c_o_diff int) engine memory;   
    #每抽一次,id加一;要抽的变量名;变量当前的值;变量上一个值;差值;引擎用memory
    
    delimiter //    #以//标志作为存储过程的结束
    create procedure do_insert_pt(i int,k int)
    begin   #begin...end是一对,是存储过程的开头和结尾
    declare j int default 1;    #定义变量
    while j<i+1 do      #循环判断
    set j=j+1;      #给变量赋值
    select sleep(k);
    insert into test.pt(id,variable_name,c_variable_value) select j,VARIABLE_NAME,VARIABLE_VALUE from information_schema.global_status where VARIABLE_NAME in (select c_name from pt_c);        
    #执行SQL。对select来说,取出来的数字赋给一个变量或者游标。插入/删除是直接执行的
    end while;  #结束循环
    end;        #与begin...end是一对
    //      #存储过程结束
    
    insert into pt_c values(1,'Innodb_data_fsyncs'),(2,'Innodb_os_log_fsyncs'),(3,'Innodb_log_writes'),(4,'Innodb_data_writes'),(5,'Com_commit'),(6,'Com_rollback'),(7,'Innodb_buffer_pool_pages_flushed');
    
    
    delimiter //
    create procedure do_update_pt(i int,j int)
    begin
    DECLARE done INT DEFAULT FALSE; #定义一个变量叫done
    declare i_id int;   
    declare i_name varchar(30);
    declare i_c_variable_value int;
    DECLARE c_1 CURSOR FOR SELECT id,variable_name,c_variable_value FROM test.pt where id between i and j order by id,variable_name;
    #定义一个游标。这个游标是select对应的一个结果集
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    #for not found意思就是取到最后,没有数据了,就让done=ture。
    open c_1;       #打开游标
    read_loop: loop
    fetch c_1 into i_id,i_name,i_c_variable_value;  
    #把结果集的第一行拿出来,分别赋值给三个变量
      IF done THEN
          LEAVE read_loop;
        END IF;
    update test.pt set o_variable_value=i_c_variable_value where id=i_id+1 and variable_name=i_name;
    #具体的sql语句
    update test.pt set c_o_diff=c_variable_value-o_variable_value where id=i_id+1 and variable_name=i_name;
    #具体的sql语句
    end loop;
    close c_1;
    end;
    //
    show index from pt;
    +-------+------------+----------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table | Non_unique | Key_name | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------+------------+----------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | pt    |          1 | i_pt     |            1 | id            | NULL      |        NULL |     NULL | NULL   | YES  | HASH       |         |               |
    | pt    |          1 | i_pt     |            2 | variable_name | NULL      |         777 |     NULL | NULL   | YES  | HASH       |         |               |
    +-------+------------+----------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    2 rows in set (0.00 sec)
    create index i_pt on pt(id,variable_name);
    
    select c_o_diff from pt where variable_name='INNODB_LOG_WRITES';
    • 1、要分析为什么要调整这些参数值
    • 2、修改一个参数、观察状态值、继续调整、直至效果最佳

    Create By LPeng

  • 相关阅读:
    [转]Dokuwiki使用感受
    [转]认识与入门Markdown
    [转]2015深度学习回顾:ConvNet、Caffe、Torch及其他
    [转]Dokuwiki插件与主题推荐
    [转]okuwiki布署小记
    PHP环境配置
    keydown和keypress
    JavaScript优化参考
    IE兼容性标签和条件注释
    nodejs 简单http 文件上传demo
  • 原文地址:https://www.cnblogs.com/lpeng94/p/12546457.html
Copyright © 2011-2022 走看看