My studying notes for Java,Ruby,Ajax and other any interesting things.

星期二, 八月 01, 2017

mysql性能问题排查及故障诊断思路


思路:
——————————————————————— 
1.找到瓶颈处
2.针对瓶颈进行优化
3.数据库优化策略分为三步走:
  • 配置优化,cpu,内存,io
  • 表结构优化:表引擎,索引,表拆分(大表转小表,减少大字段,控制表数量及表大小),分表分库,主从分离,读写分离,多主
  • SQL优化:简化SQL,减少join,减少sql计算,减少存储过程,使用preparedstatement,找到慢sql逐个优化
4.程序优化:
  • 减少事务,降低锁的概率
  • 使用缓存应对读(但要保证数据的及时性)
  • 异步写操作(但要保证事务顺序和成功)


实践:
——————————————————————— 
寻找瓶颈,有两个思路:
  • 根据监控找到耗时较大的功能、业务:
    • 程序级别的监控,每个请求的时间记录,access_log或者程序在某个controller的切面中将时间打印出来;
    • 根据用户反馈,这个往往不准,因为用户看到慢的时候可能已经形成了雪崩效应;
    • 捋日志,找第一个慢的,或者找到累计最多的,然后单独测试该功能复现和模拟;
    • 原因可能会很多:比如数据库锁住了,内存不够,SQL性能太低....根据原因找;
  • 根据性能监控,查看资源使用情况
    • 在应用服务器,数据库服务器多方面监控资源使用情况,核心关注CPU,内存,IO和网络三点的使用情况
    • CPU忙:
      • 通常在进行计算,计算包括数据处理,图像,正则,科学计算等;从直观上来看,就是循环多,有很多for循环..
      • 常用监控命令:vmstat,mpstat
      • 如果要看某个进程的情况,可以使用"while :; do ps -eo pid,ni,pri,pcpu,psr,comm | grep 'firefox'; sleep 1; done" 类似的语句来查看
    • IO忙:大数据load到内存中,比如数据库、文件检索,本身匹配并不耗CPU,但是数据比较大,比较多需要频繁换页;
      • 监控换页数量,io读写次数,以及iowait数量
      • 常用命令:iostat,lsof
      • 需要注意,swap其实挺慢的,可以通过top、cat /proc/meminfo、vmstat 来监控swap的使用情况;
    • 网络监控:
      • 监控起来最复杂,主要监控网络流出和流入情况,以及丢包、延迟等;
      • 在linux下面可以使用:iptraf,netperf,tcpdump,tcptrace,tcpcopy
  • 工具:salt+zabbix,negios等都可以实现细粒度的监控;
  • 压力测试:针对某些怀疑的点进行压力测试,模拟发现对应的问题,同时检查系统的吞吐能力;
  • 常用工具及命令:Vmstat、sar、iostat、netstat、free、ps、top等
  • 常用组合方式
    • 用vmstat、sar、iostat检测是否是CPU瓶颈
    • 用free、vmstat检测是否是内存瓶颈
    • 用iostat检测是否是磁盘I/O瓶颈
    • 用netstat检测是否是网络带宽瓶颈

针对瓶颈优化:
  • 不同的问题原因不同,优化方案也不一样,通常来讲,分为代码优化和配置优化两条腿,配置优化又分为操作系统,服务和应用的优化。

mysql配置优化:
————————— 
  • 安装以后在mysql的配置文件中有:my-huge.cnf,my-mediam.cnf,my-small.cnf,可以根据需要自己拷贝一份做修改;/usr/local/share/mysql/
  • innodb_buffer_pool_size:数据缓冲池,是数据和索引缓存的地方,这个值越大越好,这能保证你在大多数的读取操作时使用的是内存而不是硬盘。典型的值是5-6GB(8GB内存),20-25GB(32GB内存),100-120GB(128GB内存);根据内存情况来设定。
  • innodb_log_file_size:redo日志的大小,用于确保写操作快速可靠,且在崩溃的时候可以恢复;默认512M,4G比较合适;
  • max_connections:最大连接数,默认151,根据实际情况扩大,但要注意程序端不会无限的增加(连接池)
  • innodb专属设置:
    • innodb_file_per_table,建议为on,每个表单独有自己的idb文件,可以再drop,truncate或者delete的时候会收表空间,如果表特别多的话,不建议使用(比如超过10k)
    • innodb_flush_log_at_trx_commit,是否支持事务一致性,通常为1,当性能要求大于数据一致性要求是可以设为0,比如从库;
    • innodb_flush_method,数据和日志写入方式,如果有raid,且不会down机,使用O_Driect,否则用fdatasync,可以用sysbench来测试;
    • inodb_log_buffer_size,为未执行的事务分配的缓存,默认1M,可以根据innodb_log_waits状态来看,如果不够的话可以适当增加;
  • 其他设置:
    • query_cache_size,查询缓存,这个可能会有坑,建议设为0,通过其他方式来提升缓存;
    • 设定主从:log_bin,
    • 是否跳过域名解析:skip_name_resolve,这样数据中只能使用ip来进行授权;
    • table_cache,表缓存,可以根据open_tables(show global status)来进行优化

mysql性能诊断命令:
  • show global status;show status like 'xxx';
  • show variables
  • show innodb status
  • show processlist
  • show tables status
  • show processlist
  • 事务和锁的检查
mysql的慢查询开启:
  • slow_query_log,设置为on
  • long_query_time,超时时间,比如设置为1,就是1s
  • slow_query_log_file,记录慢日志的文件
  • log_queries_not_using_indexes,记录没有使用到索引的查询语句

根据某个语句进行优化:
  • desc(explain) 某条语句,查看执行计划,可以看到该语句是否使用了索引,临时表、文件排序检索行数等;
  • 设置profiling,然后执行语句,查看profiling的日志:set profiling=1;execute sql;show profiles;show profile for query 1;


mysql结构优化:
————————— 
  • 每个表有主键,
  • 字段简单:
    • 类型选择好,
      • 数字:尽量用整型,包括枚举、时间、ip等都可以数字化,decimal少用
      • 文本:varchar/char,禁用text
      • 时间:性能考虑可以用bigint,否则用timestamp(不用datetime)
    • 二进制、文本、图片等不要用数据库存储,大字段可以分开表存放,减少io;
    • 字符集编码统一,join的时候可能会出现字符集不匹配无法使用索引的问题;
    • 尽量not null
    • 可以适当冗余字段,减少join
    • 拆表拆库:主要将资源分配到更多cpu和内存上,对结构简化有帮助
    • 单表不超过:1000w,有字符串的尽量在500w以内,单库不超过400张表;字段在30-50个;
    • 每个表都有主键,且建议为数据库自增int
使用语句优化:
————————— 
  • 原则:每个sql尽量小,尽量不用大事务,
  • 尽量每条语句都要是用到索引
  • 语句中尽量少join
  • 在语句中少使用子查询,如果一定要,用join比子查询好;
  • 不用函数或在SQL中进行计算,包括类型转换
  • 少用or
  • union all 代替union
  • 少select *,而是需要什么查询什么
  • 尽早过滤
  • 尽量少排序
  • 优先优化数量多,性能没那么好的SQL;再优化频率低,杀伤力大的sql
  • 大量数据插入用load data,且放到低峰期执行
索引创建合理:
  • 索引数量不是越多越好,而是用得越多越好
  • 索引字段不要在sql中计算,可能无法使用索引
  • 尽量不用外键等约束,由程序来保障,避免高并发死锁

程序优化:
——————————————————— 
1.控制事务大小
2.充分利用应用服务器的资源
3.在应用端缓存,分布式、文件、本地都可以




Refer:

星期一, 七月 31, 2017

tmux使用简单记录

简单研究tmux的使用,类似于screen,不过有分屏功能:

有个详细的文章: tmux终端复用


大体有几个关键:
1.安装,mac下面brew install tmux,linux下面用yum或者apt-get都可以正常安装
2.基本使用:

创建和连接session:
  tmux new -s session_name
  tmux a -t session_name
  ctrl+b d, detache一个session

创建新的panel:
  ctrl+b %,纵向拆分一个面板
  ctrl+b " 横向拆分一个面板
  如果有鼠标模式,可以鼠标点击进入不同的panel;
  如果没有鼠标,可以使用ctrl+b 方向键,来切换不同的panel


创建新窗口:
  ctrl+b c 创建一个新的窗口
  ctrl+b n,p 进入上一个或者下一个窗口


3.配置:
在~/.tmux.conf中编辑相关配置,可以设置相关的键盘绑定,基本上默认即可,此处有个简单参考 : http://www.opstool.com/article/253


这里有个文章说如何打造更好的tmux配置: https://segmentfault.com/a/1190000008188987

tmux使用简单记录

一直使用screen,但是在远程的时候开多个窗口比较麻烦,用iterm2的cmd+d拆分也可以实现,但会产生多个ssh链接。无意中发现tmux,试用了一下感觉不错,简单记录。

tmux使用简单记录

简单研究tmux的使用,类似于screen,不过有分屏功能:

有个详细的文章: tmux终端复用


大体有几个关键:
1.安装,mac下面brew install tmux,linux下面用yum或者apt-get都可以正常安装
2.基本使用:

创建和连接session:
  tmux new -s session_name
  tmux a -t session_name
  ctrl+b d, detache一个session

创建新的panel:
  ctrl+b %,纵向拆分一个面板
  ctrl+b " 横向拆分一个面板
  如果有鼠标模式,可以鼠标点击进入不同的panel;
  如果没有鼠标,可以使用ctrl+b 方向键,来切换不同的panel


创建新窗口:
  ctrl+b c 创建一个新的窗口
  ctrl+b n,p 进入上一个或者下一个窗口


3.配置:
在~/.tmux.conf中编辑相关配置,可以设置相关的键盘绑定,基本上默认即可,此处有个简单参考 : http://www.opstool.com/article/253


这里有个文章说如何打造更好的tmux配置: https://segmentfault.com/a/1190000008188987
印象笔记,让记忆永存。下载印象笔记

星期二, 五月 16, 2017

windows下imagemagick水印处理脚本



近期在使用imagemagick处理水印,mac和linux下面都很实用,一个同事是windows系统,也需要类似功能。于是做了一个windows下面的脚本,同时学习了一下windows的bat处理脚本。(真心不好用)

大概记录一下脚本和流程:

— 脚本1:watermark.bat,负责调度和创建目录
echo off
SET IDTY="C:\Program Files\ImageMagick-7.0.5-Q16\identify.exe"
SET SOURCE_DIR="source"
SET LOGO="C:\windows.logo\logo.png"
SET TARGET_DIR="out"

%IDTY% -format "%%[fx:w] %%[fx:h]" %LOGO% > logo.txt

for /f "tokens=1,2" %%a in (logo.txt) do set lw=%%a&set lh=%%b


for /r %SOURCE_DIR% %%i in (*) do if not exist %TARGET_DIR%%%~pi mkdir %TARGET_DIR%%%~pi

for /r %SOURCE_DIR% %%i in (*) do (
      call logo.bat %%i
)

— logo.bat,负责进行logo处理和输出:

SET TARGET_DIR="out"
SET IMCONV="C:\Program Files\ImageMagick-7.0.5-Q16\convert.exe"
SET IDTY="C:\Program Files\ImageMagick-7.0.5-Q16\identify.exe"
SET SOURCE_DIR="source"
SET TARGET_DIR="out"
SET LOGO="C:\Users\zhangwenhui\Desktop\windows.logo++\logo.png"

for /f "tokens=1,2" %%a in (logo.txt) do set lw=%%a&set lh=%%b

@rem echo %lw% %lh%

%IDTY% -format "%%[fx:w] %%[fx:h]" %1 > %1.txt
for /f "tokens=1,2" %%a in (%1.txt) do set w=%%a&set h=%%b
del %1.txt
set /a width=%w%*30/100
set /a height=%lh%*%width%/%lw%
@rem echo w:%w% ,width:%width%,height:%height%

composite -gravity southeast ( %LOGO% -resize %width%x%height% ) %1 %TARGET_DIR%\%~pn1.jpg


有几点注意:
1.windows的bat脚本中的%(百分号)是个坑:
  case1:
    set xx='asdfbc'
    引用xx的时候使用%xx%
   case2:
    在命令行中 for /r /d %d in(*)  do echo %d
    在for里面使用的时候需要用%d的形式访问,然后在后续使用该变量的时候可以使用%d进行访问
  case3:
    在批处理脚本中的for,需要加两个百分号
    for /r /d %%d  in (*) do echo %%d
      如果在for中再进行set xx,就基本上搞不正确了,所以使用了call来调用另外一个脚本;

    2.批处理的执行顺序,在windows的bat处理的时候,感觉会类似递归的调用顺序,没有搞太明白。比如 block a中的block b,在执行的时候是block a把每个block单独输出到命令行被执行,而不是有一个解释器把整个脚本进行调度。
    3.bat中有替换功能,但是好像只能针对%a%的变量,而不能针对%a这样的变量
    4.imagemagick在windows上面默认不安装legacy utilities,所以convert,composite等功能都无法调用,在安装的时候需要选中;在composite的时候与mac略有不同,不需要使用转义括号。
    5.目录中如果有空格,则需要使用引号给引起来;

    印象笔记,让记忆永存。下载印象笔记