第1章 系统优化
1.1 操作系统优化工具(CPU、MEM、IO)
top
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
-----------------
0.0%us, 0.0%sy %id 0.0%wa
us:用户进程占用的cpu时间比例。
sy: 系统进程占用cpu时间比例。
wa:wait我们不建议太高:
1、IO太差
2、内存太小
我们希望看到us使用更高
如果说sy更高:
1、中病毒
2、系统bug
Mem: 1004112k total, 166296k used, 837816k free, 62268k buffers
Swap: 786428k total, 0k used, 786428k free, 27208k cached
iostat
iostat -dk 1 10
tps:该设备每秒的传输次数。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
kB_read/s:每秒从设备(drive expressed)读取的数据量;
KB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;
kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。
iostat -d -k -x 5 (查看设备使用率(%util)和响应时间(await))
kB_read/s:100M
tps:1000
问:每次IO平均的IO量是多少?
100K
IOPS:计算机磁盘IO设备的定值,每秒的IO的最大次数
出现TPS过高,比如超过了500个。
1、过度条带化,条带化程度不要超过2次,一般就是一次条带化比较好。
2、查询缓存失效。
3、全表扫描
---------------
1.2 vmstat
Procs:r显示有多少进程正在等待CPU时间。
b显示处于不可中断的休眠的进程数量。在等待I/O
Memory:swpd显示被交换到磁盘的数据块的数量。未被使用的数据块,用户缓冲数据块,用于操作系统的数据块的数量
Swap:操作系统每秒从磁盘上交换到内存和从内存交换到磁盘的数据块的数量。s1和s0最好是0
Io:每秒从设备中读入b1的写入到设备b0的数据块的数量。反映了磁盘I/O
System:显示了每秒发生中断的数量(in)和上下文交换(cs)的数量
Cpu:显示用于运行用户代码,系统代码,空闲,等待I/O 的CPU时间
nmon
1.3 企业基础优化实战
思路:
定位问题:
硬件
系统
应用
数据库
架构(高可用、读写分离、分库分表)
处理问题
明确优化目标
性能和安全的折中
防患未然
-------------------
硬件优化:
主机:
根据数据库类型,主机CPU选择、内存容量选择、磁盘选择
cpu:
1、cpu密集型的:I5 I7 I9 power ,更佳擅长用于,计算类型应用用的比较多。
2、IO密集型的:志强Xeon,数据库类的应用(OLTP)
内存:
一般1.5-2倍cpu
IO设备
%%主机 RAID卡的BBU(Battery Backup Unit)关闭
磁盘存储:
根据存储数据种类的不同,选择不同的存储设备
配置合理的RAID级别(raid5、raid10、热备盘)
网络设备:
使用流量支持更高的网络设备(交换机、路由器、网线、网卡、HBA卡)
注意:这些规划应该在初始设计系统时就应该 考虑好
-----------------------
系统优化
Cpu:
基本不需要调整,在硬件选择方面下功夫即可。
内存:
基本不需要调整,在硬件选择方面下功夫即可。
SWAP:
MySQL尽量避免使用swap。
-----------------
Swap调整
/proc/sys/vm/swappiness的内容改成0(临时),/etc/sysctl.conf上添加vm.swappiness=0(永久)
这个参数决定了Linux是倾向于使用swap,还是倾向于释放文件系统cache。在内存紧张的情况下,数值越低越倾向于释放文件系统cache。
当然,这个参数只能减少使用swap的概率,并不能避免Linux使用swap。
%%echo 0 > /proc/sys/vm/swappines
%%/etc/sysctl.conf上
添加vm.swappiness=0(永久)
sysctl -p
-------------
IO :
修改MySQL的配置参数innodb_flush_method,开启O_DIRECT模式。
这种情况下,InnoDB的buffer pool会直接绕过文件系统cache来访问磁盘,但是redo log依旧会使用文件系统cache。
值得注意的是,Redo log是覆写模式的,即使使用了文件系统的cache,也不会占用太多
no soft raid
no lvm
%% ext4或xfs
ssd 或 flash
IO调度策略
IO调度策略
%%echo deadline>/sys/block/sda/queue/scheduler 临时修改为deadline
%%vi /boot/grub/grub.conf
更改到如下内容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet
--------------------------
系统的内存参数调整
/etc/sysctl.conf
net.ipv4.ip_local_port_range=1024 65535
改变本地的端口范围
net.ipv4.tcp_max_syn_backlog=4096
允许更多的连接进入队列
net.ipv4.tcp_fin_timeout=30
对于只在本地使用的数据库服务器,可以缩短tcp保持状态的超时时间、默认1分钟
fs.file-max=65535
系统文件句柄限制
----------------
1.4 系统应用优化
业务应用和数据库应用独立
防火墙:iptables selinux
其他(关闭无用服务):
chkconfig --level 23456 acpid off
chkconfig --level 23456 anacron off
chkconfig --level 23456 autofs off
chkconfig --level 23456 avahi-daemon off
chkconfig --level 23456 bluetooth off
chkconfig --level 23456 cups off
chkconfig --level 23456 firstboot off
chkconfig --level 23456 haldaemon off
chkconfig --level 23456 hplip off
chkconfig --level 23456 ip6tables off
chkconfig --level 23456 iptables off
chkconfig --level 23456 isdn off
chkconfig --level 23456 pcscd off
chkconfig --level 23456 sendmail off
chkconfig --level 23456 yum-updatesd off
另外,思考将来我们的业务是否真的需要MySQL,还是使用其他种类的数据库。
----------------------
1.5 数据库优化
参数调整:
实例整体(高级优化,扩展):
thread_concurrency 并发线程数量个数
+++++++++++++++++++++++++++
在官方doc上,对于innodb_thread_concurrency的使用,也给出了一些建议,如下:
如果一个工作负载中,并发用户线程的数量小于64,建议设置innodb_thread_concurrency=0;
如果工作负载一直较为严重甚至偶尔达到顶峰,建议先设置innodb_thread_concurrency=128,并通过不断的降低这个参数,96, 80, 64等等,
直到发现能够提供最佳性能的线程数,
例如,假设系统通常有40到50个用户,但定期的数量增加至60,70,甚至200。
你会发现,性能在80个并发用户设置时表现稳定,如果高于这个数,性能反而下降。
在这种情况下,建议设置innodb_thread_concurrency参数为80,以避免影响性能。
如果你不希望InnoDB使用的虚拟CPU数量比用户线程使用的虚拟CPU更多(比如20个虚拟CPU),
建议通过设置innodb_thread_concurrency 参数为这个值(也可能更低,这取决于性能体现),
如果你的目标是将MySQL与其他应用隔离,你可以考虑绑定mysqld进程到专有的虚拟CPU。
但是需 要注意的是,这种绑定,在myslqd进程一直不是很忙的情况下,可能会导致非最优的硬件使用率。在这种情况下,你可能会设置mysqld进程绑定的虚拟 CPU,允许其他应用程序使用虚拟CPU的一部分或全部。
在某些情况下,最佳的innodb_thread_concurrency参数设置可以比虚拟CPU的数量小。
定期检测和分析系统,负载量、用户数或者工作环境的改变可能都需要对innodb_thread_concurrency参数的设置进行调整。
show variables like 'innodb_thread_concurrency';
++++++++++++++++++++++++++++++++++++++++++
sort_buffer_size 排序缓冲区
read_rnd_buffer_size 随机读取缓存
---------------------------------
以上几个参数可以微调,但是不要太大。
read_buffer_size 顺序读取缓存 128K
key_buffer_size 索引缓存 16M 32M
show variables like 'xxx'
show status like ''
看一下数据库中有没有行数特别多的表,索引数量较多的表。如果有可以调整32M
%thread_cache_size (1G—>8, 2G—>16, 3G—>32, >3G—>64)
单位是个数,设定线程可以被重用的个数
连接层(基础优化)
设置合理的连接客户和连接方式
%%max_connections 最大连接数 $$
%%max_connect_errors 最大错误连接数 $$
connect_timeout 连接超时
max_user_connections 最大用户连接数
%%skip-name-resolve 跳过域名解析 $$
wait_timeout 等待超时
back_log 可以在堆栈中的连接数量
SQL层(基础优化)
query_cache_size 查询缓存
适用的场景:经常会对数据库的少部分数据进行反复查询时,可以调整较大8M
不适应的场景:
1、经常对数据库大部分数据进行查询,我们建议使用redis 、memcache。
2、业务经常会对表数据进行变更。
%%log_bin 设置binlog位置及名称前缀,建议放到ssd存储上,并数据隔离存储
%%binlog_format 设置binlog的格式,我们建议用row
binlog_cache_size binlog cache大小
max_binlog_cache_size binlog cache的最大大小
max_binlog_size binlog文件的最大小
%% sync_binlog binlog刷新策略(控制的是binlog写入磁盘的条件)
0:默认通过os cache自动控制写入binlog
1:每个事务提交就触发一次binlog写入文件(安全),双一标准中的其中一个
存储引擎层(innodb基础优化参数)
%%default-storage-engine --默认的存储引擎
%%innodb_buffer_pool_size --buffer pool大小
设置一个测试值,比如50%物理内存,然后压力测试进行微调,最大不要超过65%。
%%innodb_file_per_table=(1,0) 表空间模式,我们建议是1
%%innodb_flush_log_at_trx_commit=(0,1,2) redo日志的刷新策略。
0:每秒钟刷新redo一次到os buffer(最大的性能模式)
1:每次事务提交时,属性一次redo到磁盘(最大的安全模式)
2:每次事务提交时都刷新日志到os buffer,每秒钟fsync到磁盘
%%Innodb_flush_method=(O_DIRECT, fdatasync,O_DSYNC)
innodb_log_buffer_size ----->redo buffer内存大小 ,小的话想对安全,大的话性能会有一定的提升
innodb_log_file_size
innodb_log_files_in_group
%%innodb_max_dirty_pages_pct 内存中脏页比例
innodb_additional_mem_pool_size (于2G内存的机器,推荐值是20M。32G内存的100M) 128
%% transaction_isolation 隔离(默认第三种级别)
-------------------------------------------------------
show status like 'com_insert';
show status like 'com_update';
show status like 'com_delete';
show status like 'com_select';
------------------
%%执行计划(基础优化)---管理员关注
%%索引(基础优化)----管理员关注
SQL改写(高级优化) ---配合开发
架构优化(高级优化扩展):----管理员重点要维护一下架构
高可用架构 ---MHA、MYCAT
高性能架构 ---Atlas、MyCAT
分库分表 ---MyCAT ----和应用业务对接